Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
XCOMM $XConsortium: Imakefile /main/11 1996/08/09 14:50:28 barstow $
XCOMM
XCOMM RESTRICTED CONFIDENTIAL INFORMATION:
XCOMM
XCOMM The information in this document is subject to special
XCOMM restrictions in a confidential disclosure agreement between
XCOMM HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
XCOMM document outside HP, IBM, Sun, USL, SCO, or Univel without
XCOMM Sun's specific written approval. This document and all copies
XCOMM and derivative works thereof must be returned or destroyed at
XCOMM Sun's request.
XCOMM
XCOMM (c) Copyright 1996 Digital Equipment Corporation.
XCOMM (c) Copyright 1996 Hewlett-Packard Company.
XCOMM (c) Copyright 1996 International Business Machines Corp.
XCOMM (c) Copyright 1993,1996 Sun Microsystems, Inc.
XCOMM (c) Copyright 1996 Novell, Inc.
XCOMM (c) Copyright 1996 FUJITSU LIMITED.
XCOMM (c) Copyright 1996 Hitachi.
PROGRAM = rpc.cmsd
INCLUDES = -I. -I$(CSASRC) -I$(DTHELPSRC)
SYS_LIBRARIES = DtClientSysLibs
#ifdef SunArchitecture
LOCAL_LIBRARIES = $(CSALIB) $(DTSVCLIB) $(TTLIB)
#else
LOCAL_LIBRARIES = $(CSALIB) $(DTWIDGETLIB) $(DTHELPLIB) $(DTSVCLIB) $(TTLIB) $(XMLIB) $(XTOOLLIB) $(XLIB)
#endif /* SunArchitecture */
OSMAJORVERSION = OSMajorVersion
OSMINORVERSION = OSMinorVersion
DEFINES = -DREL="$(OSMAJORVERSION)$(OSMINORVERSION)" -DSVR4 \
-DRELMAJOR="$(OSMAJORVERSION)" \
-DRELMINOR="$(OSMINORVERSION)"
#ifdef RsArchitecture
EXTRA_LIBRARIES = -lrpcsvc -lPW -ldiag -lc
#endif
#ifdef HPArchitecture
EXTRA_DEFINES = -DHPUX -DS9000
EXTRA_LIBRARIES = -lrpcsvc -lV3 -lc -lPW
#endif
#ifdef SunArchitecture
EXTRA_DEFINES = -DSunOS=$(OSMAJORVERSION)$(OSMINORVERSION)
EXTRA_CCOPTIONS = -xstrconst -Xc -v
EXTRA_LIBRARIES = -lsocket -lnsl -lintl
#endif
SRCS = \
parser.y access.c callback.c \
cmscalendar.c cmsconvert.c cmsentry.c \
cmsmatch.c delete.c garbage.c \
insert.c lexit.c list.c \
log.c lookup.c reclotick.c \
recount.c relasttick.c reminder.c \
renexttick.c repeat.c reprevtick.c \
rerule.c reutil.c tree.c \
utility.c v4ops.c v5ops.c \
cmsfunc.c programtable.c rtable2.c \
rtable3.c rtable4.c svcmain.c \
update.c
OBJS = \
parser.o access.o callback.o \
cmscalendar.o cmsconvert.o cmsentry.o \
cmsmatch.o delete.o garbage.o \
insert.o lexit.o list.o \
log.o lookup.o reclotick.o \
recount.o relasttick.o reminder.o \
renexttick.o repeat.o reprevtick.o \
rerule.o reutil.o tree.o \
utility.o v4ops.o v5ops.o \
cmsfunc.o programtable.o rtable2.o \
rtable3.o rtable4.o svcmain.o \
update.o
all:: $(PROGRAM)
NormalProgramTarget($(PROGRAM),$(OBJS),,$(LOCAL_LIBRARIES),)
.SUFFIXES: .y
.y.c:
$(YACC) -d $(YFLAGS) $<
sed -e "s/yy/yyy/g" -e "\a# linea D" y.tab.c > $*.c
sed s/yy/yyy/g y.tab.h > $*.h
$(RM) y.tab.c y.tab.h
parser.o: parser.c
clean::
$(RM) \
parser.h parser.c
DependTarget()

View File

@@ -0,0 +1,190 @@
$ $XConsortium: SUNW_SDTCM_CONVERT.msg /main/2 1995/09/06 08:25:07 lehors $
$
$quote "
$set 1
1 "usage: %s [-v output-version] [-s <mm/dd/yy>] [-c character-set] [-d backup-directory] calendar\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number 1 to 5 are to be print out all at the same time
$ */
2 "\t-v specifies the output version, 3 or 4\n"
3 "\t-s specifies the start date to do the conversion\n"
4 "\t-c specifies the locale name to be used in the character set attribute\n"
5 "\t-d specifies the backup-directory\n"
6 "Invalid version number specified.\n"
7 "Invalid start date specified.\n"
8 "%s: insufficient memory\n"
9 "unknown failure"
10 "insufficient memory"
11 "invalid attribute"
12 "invalid attribute value"
13 "invalid date and time"
14 "invalid enumeration value"
15 "invalid flag"
16 "invalid recurrence rule"
17 "unsupported attribute"
18 "unsupported enumeration value"
19 "unsupported flag"
20 "Failed to convert appointment(s):\n"
21 "%d) id %d, what/summary = %s\n"
22 "error code = %d (%s)\n"
23 "Failed to lock lockfile, %s.\n"
24 "Failed to lock lockfile, %s.\n"
25 "Failed to kill rpc.cmsd, please kill it before\nrunning this program.\n"
26 "Failed to open %s\n"
27 "Failed to open %s\n"
28 "Failed to set %s to the correct mode.\n"
29 "Failed to backup calendar file to %s\n"
30 "There is not enough space on %s\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number (30, 31 and 32) or number (30, 31 and 34) or
$ * number (30, 31 and 35) are to be printed out together as a
$ * group depending on the error situation
$ */
31 "Please free up some space before running this program.\n"
32 "The new calendar file may need as much as %d bytes of disk space.\n"
33 "Problem accessing %s: "
34 "The calendar file needs %d bytes of disk space to backup.\n"
35 "The new calendar file may need as much as %d bytes of disk space.\n"
36 "The calendar name (%s) is inconsistent with that in the calendar name\nattribute (%s)."
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number (36, 37 and 38) or number (36 and 39) are
$ * to be printed out together as a group depending on the situation
$ */
37 " There is already a calendar with the name %s\n"
38 "Do you want to correct the value of the calendar name attribute? (Y/N) [Y] "
39 "\nDo you want to correct it? (Y/N) [Y] "
40 "Please select a calendar name, 1) %s or 2) %s\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number 40 and 41 are to be printed out together
$ */
41 "Name to use? (1, 2, or q to quit) "
42 "The ownership of the calendar file and/or the calendar owner attribute\nis wrong, the calendar should be owned by %s\n"
43 "Do you want to correct it? (Y/N) [Y] "
44 "Owner (%s) of the calendar file is inconsistent with that in the calendar\nowner attribute (%s).\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number (44 and 45) or (44 and 46) are to be
$ * printed out together as a group depending on the
$ * situation
$ */
45 "Do you want to correct the value of the calendar owner attribute? (Y/N) [Y] "
46 "Do you want to correct it? (Y/N) [Y] "
47 "Please select an owner, 1) %s or 2) %s\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number 47 and 48 are to be printed out
$ * together
$ */
48 "Name to use? (1, 2, or q to quit) "
49 "Failed to get uid for %s\n"
50 "Problem getting the owner name for %s: \n"
51 "Problem getting the owner name for %s: \n"
52 "The ownership and/or the permission mode of the calendar file is wrong.\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * messages number 52 and 53 are to be printed out
$ * together
$ */
53 "Do you want to correct it ? (Y/N) [Y] "
54 "Failed to do the correction.\n"
55 "Total number of appointments\t\t= %d\n"
56 "Number of one-time appointments\t\t= %d\n"
57 "Number of repeating appointments\t= %d\n"
58 "Please specify a calendar.\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * If message number 58 is printed, it will be
$ * followed by messages number 1 to 5.
$ */
59 "You have specified a calendar in a remote host, %s\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Messages number 59 and 60 will be printed out
$ * together. If they are printed, they will be
$ * followed by messages number 1 to 5.
$ */
60 "The calendar must be located in the local host, %s\n"
61 "Problem accessing calendar file %s:\n"
62 "%s: Must be run by super-user or the owner of the calendar.\n"
63 "Loading the calendar ...\n"
64 "Failed to parse the calendar file %s\n"
65 "The calendar file is ok.\n"
66 "Correction done.\n"
67 "Root does not have permission to write to %s\n"
68 "The calendar server, rpc.cmsd, running on your machine does not support\nthe version 4 data format. If you convert your calendar to the version 4\ndata format, you have to upgrade your calendar server to one that\nunderstands the version 4 data format.\n\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Messages 68 and 69 will be printed out together
$ */
69 "Do you want to continue? (Y/N) [Y] "
70 "Could not get the platform independent locale name for %s\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Messages 70 and 71 will be printed out
$ * together
$ */
71 "Please specify a valid locale name.\n"
72 "\nWARNING!! Data will be lost when converting version 4 data format\nback to version 3 data format.\n\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Messages 72 and 73 will be printed out together
$ */
73 "Do you want to continue? (Y/N) [Y] "
74 "Doing conversion ...\n"
75 "The original calendar file %s is not changed.\n"
76 "Failed to move the calendar file to %s\n"
77 "Writing out new file ...\n"
78 "Failed to write the new file.\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Messages number (78 and 79) or (78 and 80) or (78 and 81)
$ * or (78 and 82) will be printed out together depending
$ * on the error condition
$ */
79 "You need to recover %s from %s\n"
80 "The original calendar file %s is not changed.\n"
81 "You need to recover %s from %s\n"
82 "The original calendar file %s is not changed.\n"
83 "Correction done.\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Messages number 83, may be 84, and 85 will be printed out
$ * together
$ */
84 "The new file is saved in %s\n"
85 "The original file is saved in %s\n"
86 "Conversion done successfully with exceptions noted above.\n"
$ /*
$ * NL_COMMENT
$ * Attention Translator:
$ * Either message 86 or 87 will be printed out
$ * together with messages number 88 to 94.
$ */
87 "Conversion done successfully.\n"
88 "Total number of appointments\t\t\t= %d\n"
89 "Number of one-time appointments converted\t= %d\n"
90 "Number of repeating appointments converted\t= %d\n"
91 "Number of one-time appointments pruned\t\t= %d\n"
92 "Number of repeating appointments pruned\t\t= %d\n"
93 "The new file is saved in %s\n"
94 "The original file is saved in %s\n"

View File

@@ -0,0 +1,542 @@
/* $XConsortium: access.c /main/5 1996/10/08 16:41:05 barstow $ */
/*
* (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 <string.h>
#include <pwd.h>
#ifdef SunOS
#include <sys/systeminfo.h>
#endif
#include "access.h"
#include "appt4.h"
#include "utility.h"
#include "log.h"
#include "lutil.h"
#include "laccess.h"
#define NUM_CACHE 50 /* cache for unix user name */
extern int debug;
typedef struct uname_cache {
uid_t uid; /* unix user id */
char *name; /* user name */
struct uname_cache *next;
} Uname_cache;
static Uname_cache *ucache_list = NULL;
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static Uname_cache * in_u_cache(uid_t uid);
static char * get_uname(uid_t uid);
static Access_Entry_4 * in_access_list(Access_Entry_4 *l, char *s);
static Access_Entry_4 * combine_access_list(Access_Entry_4 *p_list,
Access_Entry_4 *p_head, int type, int *p_world);
static CSA_return_code _GetV4AccessRights(_DtCmsCalendar *cal, char *target,
char *sender, uint *access);
static CSA_return_code _GetV5AccessRights(_DtCmsCalendar *cal, char *target,
char *sender, uint *access);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
/*
* If the requester is the owner, "*sender" will be set to NULL.
*/
extern CSA_return_code
_DtCmsV4LoadAndCheckAccess(
struct svc_req *svcrq,
char *target,
char **sender,
uint *access,
_DtCmsCalendar **cal)
{
CSA_return_code stat;
if (target == NULL || sender == NULL || cal == NULL)
return (CSA_E_INVALID_PARAMETER);
if ((stat = _DtCmsGetClientInfo(svcrq, sender)) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCmsGetCalendarByName(target, B_TRUE, cal))
!= CSA_SUCCESS)
return (stat);
if ((*cal)->fversion == _DtCMS_VERSION1)
return (_GetV4AccessRights(*cal, target, *sender, access));
else
return (_GetV5AccessRights(*cal, target, *sender, access));
}
/*
* If the requester is the owner, "*p_src" will be set to NULL.
*/
extern CSA_return_code
_DtCmsV5LoadAndCheckAccess(
struct svc_req *svcrq,
char *target,
char **sender,
uint *access,
_DtCmsCalendar **cal)
{
CSA_return_code stat;
cms_access_entry *alist;
cms_attribute_value *owner;
int worldaccess = 0, useraccess = 0;
boolean_t isowner;
if (target == NULL || sender == NULL || cal == NULL)
return (CSA_E_INVALID_PARAMETER);
if ((stat = _DtCmsGetClientInfo(svcrq, sender)) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCmsGetCalendarByName(target, B_TRUE, cal))
!= CSA_SUCCESS)
return (stat);
if ((*cal)->fversion == _DtCMS_VERSION1)
return (_GetV4AccessRights(*cal, target, *sender, access));
else
return (_GetV5AccessRights(*cal, target, *sender, access));
}
extern CSA_return_code
_DtCmsGetClientInfo(struct svc_req *svcrq, char **source)
{
char *name;
char *uname;
struct authunix_parms *unix_cred;
if (source == NULL)
{
return (CSA_E_INVALID_PARAMETER);
}
switch (svcrq->rq_cred.oa_flavor) {
case AUTH_UNIX:
unix_cred = (struct authunix_parms *) svcrq->rq_clntcred;
if (unix_cred == NULL)
return (CSA_E_NO_AUTHORITY);
if ((name = get_uname (unix_cred->aup_uid)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if ((uname = malloc(strlen(name) +
strlen(unix_cred->aup_machname) + 2)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
else {
sprintf(uname, "%s@%s", name, unix_cred->aup_machname);
*source = uname;
return (CSA_SUCCESS);
}
case AUTH_NULL:
default:
svcerr_weakauth(svcrq->rq_xprt);
return (CSA_E_NO_AUTHORITY);
}
}
/*
* good format of owner and user assumed:
* owner: user[@host[.domain]]
* user: user@host[.domain]
* target: name@host[.domain]
*/
extern boolean_t
_DtCmsIsFileOwner(char *owner, char *user, char *target)
{
char *ptr1, *ptr2, *ptr3;
if (debug) {
fprintf(stderr, "rpc.cmsd: %s, %s = %s, %s = %s, %s = %s\n",
"check file owner",
"owner", ((owner == NULL) ? "NULL" : owner),
"user", ((user == NULL) ? "NULL" : user),
"target", ((target == NULL) ? "NULL" : target));
}
if (owner == NULL || user == NULL || target == NULL)
return (B_FALSE);
ptr1 = _DtCmGetPrefix(owner, '@');
ptr2 = _DtCmGetPrefix(user, '@');
if (strcmp(ptr1, ptr2)) {
free(ptr1);
free(ptr2);
return(B_FALSE);
}
free(ptr1);
free(ptr2);
/* check domain if domain info is available */
ptr1 = strchr(user, '.');
ptr2 = strchr(target, '@');
if (ptr2)
ptr3 = strchr(ptr2, '.');
else
ptr3 = NULL;
if (ptr1 == NULL || ptr3 == NULL)
/* assume that user is in the local domain */
return B_TRUE;
else
return(_DtCmIsSamePath(++ptr1, ++ptr3));
}
extern void
_DtCmsShowAccessList(Access_Entry_4 *l)
{
while (l!=NULL) {
fprintf(stderr, "Access: %s(%c%c%c)\n", l->who,
l->access_type & access_read_4 ? 'r' : '_',
l->access_type & access_write_4 ? 'w' : '_',
l->access_type & access_delete_4 ? 'd' : '_');
l = l->next;
}
}
extern Access_Entry_4 *
_DtCmsCalendarAccessList(_DtCmsCalendar *cal)
{
int world = access_none_4;
Access_Entry_4 *a;
Access_Entry_4 *l = NULL;
l = combine_access_list(GET_R_ACCESS(cal), l, access_read_4, &world);
l = combine_access_list(GET_W_ACCESS(cal), l, access_write_4, &world);
l = combine_access_list(GET_D_ACCESS(cal), l, access_delete_4, &world);
l = combine_access_list(GET_X_ACCESS(cal), l, access_exec_4, &world);
/* WORLD exists in one of the lists, add her to the combined list. */
if (world != access_none_4)
{
a = _DtCm_make_access_entry4(WORLD, world);
a->next = l;
l = a;
}
return (l);
}
extern Privacy_Level_4
_DtCmCheckPrivacyLevel(char **p_src, Appt_4 *p_appt)
{
if (*p_src == NULL)
return(public_4);
if (p_appt != NULL) {
/*
* if p_src is the author of the appointment,
* it should see everything.
*/
if (_DtCmIsSameUser(*p_src, p_appt->author)) {
*p_src = NULL;
return(public_4);
} else
return(p_appt->privacy);
} else
return(private_4);
}
/*
* the user can view the entry if it has OWNER rights,
* the appropriate VIEW rights or he is the organizer of
* the entry and has ORGANIZER rights.
*/
extern CSA_return_code
_DtCmsCheckViewAccess(char *user, uint access, cms_entry *eptr)
{
uint need;
cms_attribute_value *oval, *sval;
need = (_DtCmsClassToViewAccess(eptr)) | CSA_OWNER_RIGHTS;
if (access & need) {
return (CSA_SUCCESS);
} else {
oval = eptr->attrs[CSA_ENTRY_ATTR_ORGANIZER_I].value;
sval = eptr->attrs[CSA_ENTRY_ATTR_SPONSOR_I].value;
if (((access & CSA_ORGANIZER_RIGHTS) &&
_DtCmIsSameUser(user, oval->item.calendar_user_value)) ||
((access & CSA_SPONSOR_RIGHTS) && sval &&
_DtCmIsSameUser(user, sval->item.calendar_user_value)))
return (CSA_SUCCESS);
else if ( (need & ~CSA_OWNER_RIGHTS) == (CSA_VIEW_CONFIDENTIAL_ENTRIES) ) {
return (CSA_E_TIME_ONLY);
} else
return (CSA_E_NO_AUTHORITY);
}
}
extern CSA_return_code
_DtCmsCheckChangeAccess(char *user, uint access, cms_entry *eptr)
{
uint need;
cms_attribute_value *oval, *sval;
need = (_DtCmsClassToChangeAccess(eptr)) | CSA_OWNER_RIGHTS;
if (access & need) {
return (CSA_SUCCESS);
} else {
oval = eptr->attrs[CSA_ENTRY_ATTR_ORGANIZER_I].value;
sval = eptr->attrs[CSA_ENTRY_ATTR_SPONSOR_I].value;
if (((access & CSA_ORGANIZER_RIGHTS) &&
_DtCmIsSameUser(user, oval->item.calendar_user_value)) ||
((access & CSA_SPONSOR_RIGHTS) && sval &&
_DtCmIsSameUser(user, sval->item.calendar_user_value)))
return (CSA_SUCCESS);
else
return (CSA_E_NO_AUTHORITY);
}
}
extern uint
_DtCmsClassToViewAccess(cms_entry *entry)
{
cms_attribute_value *val;
val = entry->attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value;
switch (val->item.uint32_value) {
case CSA_CLASS_PUBLIC:
return (CSA_VIEW_PUBLIC_ENTRIES);
case CSA_CLASS_PRIVATE:
return (CSA_VIEW_PRIVATE_ENTRIES);
case CSA_CLASS_CONFIDENTIAL:
return (CSA_VIEW_CONFIDENTIAL_ENTRIES);
}
}
extern uint
_DtCmsClassToInsertAccess(cms_entry *entry)
{
cms_attribute_value *val;
val = entry->attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value;
switch (val->item.uint32_value) {
case CSA_CLASS_PUBLIC:
return (CSA_INSERT_PUBLIC_ENTRIES);
case CSA_CLASS_PRIVATE:
return (CSA_INSERT_PRIVATE_ENTRIES);
case CSA_CLASS_CONFIDENTIAL:
return (CSA_INSERT_CONFIDENTIAL_ENTRIES);
}
}
extern uint
_DtCmsClassToChangeAccess(cms_entry *entry)
{
cms_attribute_value *val;
val = entry->attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value;
switch (val->item.uint32_value) {
case CSA_CLASS_PUBLIC:
return (CSA_CHANGE_PUBLIC_ENTRIES);
case CSA_CLASS_PRIVATE:
return (CSA_CHANGE_PRIVATE_ENTRIES);
case CSA_CLASS_CONFIDENTIAL:
return (CSA_CHANGE_CONFIDENTIAL_ENTRIES);
}
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static Uname_cache *
in_u_cache(uid_t uid)
{
int cache = NUM_CACHE;
Uname_cache *p_prev;
Uname_cache *p_cache;
p_prev = NULL;
p_cache = ucache_list;
while (p_cache != NULL)
{
if (p_cache->uid == uid)
return (p_cache);
if (--cache < 0)
{
/* Assume that the cache size is at least 1 */
p_prev->next = p_cache->next;
free (p_cache->name);
free (p_cache);
p_cache = p_prev->next;
}
else
{
p_prev = p_cache;
p_cache = p_cache->next;
}
}
return (NULL);
}
static char *
get_uname(uid_t uid)
{
struct passwd *pw;
char buff[16];
Uname_cache *ucache, *prev;
if ((ucache = in_u_cache(uid)) == NULL)
{
if ((pw = getpwuid (uid)) == NULL) {
/* Can't map uid to name. Don't cache the uid. */
sprintf (buff, "%ld", (long)uid);
return (strdup(buff));
}
if ((ucache = (Uname_cache *)malloc(sizeof(Uname_cache)))
== NULL)
return (NULL);
if ((ucache->name = strdup(pw->pw_name)) == NULL) {
free(ucache);
return (NULL);
}
ucache->uid = uid;
ucache->next = ucache_list;
ucache_list = ucache;
}
return (strdup(ucache->name));
}
static Access_Entry_4 *
in_access_list(Access_Entry_4 *l, char *s)
{
char *name;
if (l==NULL || s==NULL) return(NULL);
while(l != NULL) {
/* only for combining lists, not for authentication */
if (strcmp(l->who, s) == 0)
break;
l = l->next;
}
return(l);
}
static Access_Entry_4 *
combine_access_list(
Access_Entry_4 *p_list,
Access_Entry_4 *p_head,
int type,
int *p_world)
{
Access_Entry_4 *a;
Access_Entry_4 *h = p_head;
while (p_list != NULL)
{
/* Delay to put the WORLD into the combined list because
* in_access_list() may return wrong result.
*/
if (strcmp (p_list->who, WORLD) == 0)
*p_world |= type;
else
{
/* The user is not in the combined list, add to list. */
if ((a = in_access_list (h, p_list->who)) == NULL)
{
a = _DtCm_make_access_entry4(p_list->who, type);
a->next = p_head;
p_head = a;
}
a->access_type |= type;
}
p_list = p_list->next;
}
return (p_head);
}
static CSA_return_code
_GetV4AccessRights(
_DtCmsCalendar *cal,
char *target,
char *sender,
uint *access)
{
int worldaccess = 0, useraccess = 0;
Access_Entry_4 *alist;
/* first check to see if the user is the owner of the calendar */
if (_DtCmsIsFileOwner(cal->owner, sender, target)) {
*access = CSA_OWNER_RIGHTS;
return (CSA_SUCCESS);
}
for (alist = cal->alist; alist != NULL; alist = alist->next) {
if (strcmp(alist->who, WORLD) == 0)
worldaccess = alist->access_type;
else if (_DtCmIsSameUser(sender, alist->who)) {
useraccess = alist->access_type;
break;
}
}
*access = worldaccess | useraccess;
return (CSA_SUCCESS);
}
static CSA_return_code
_GetV5AccessRights(
_DtCmsCalendar *cal,
char *target,
char *sender,
uint *access)
{
cms_access_entry *alist;
cms_attribute_value *owner;
int worldaccess = 0, useraccess = 0;
boolean_t isowner;
/* first check to see if the user is the owner of the calendar */
owner = cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value;
isowner = _DtCmsIsFileOwner(owner->item.calendar_user_value, sender,
target);
if (isowner && cal->checkowner == B_FALSE) {
*access = CSA_OWNER_RIGHTS;
return (CSA_SUCCESS);
}
alist = cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value->\
item.access_list_value;
if (alist == NULL) {
*access = worldaccess | useraccess;
return (CSA_E_NO_AUTHORITY);
}
for (; alist != NULL; alist = alist->next) {
if (strcmp(alist->user, WORLD) == 0)
worldaccess = alist->rights;
else if (_DtCmIsSameUser(sender, alist->user)) {
useraccess = alist->rights;
break;
}
}
*access = worldaccess | useraccess;
return (CSA_SUCCESS);
}

View File

@@ -0,0 +1,93 @@
/* $XConsortium: access.h /main/4 1995/11/09 12:39:54 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.
*/
#ifndef _ACCESS_H
#define _ACCESS_H
#include "ansi_c.h"
#include "cm.h"
#include "rtable4.h"
#include "cmscalendar.h"
#define _DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(a) \
((a) & (CSA_VIEW_CALENDAR_ATTRIBUTES | CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_INSERT_CALENDAR_ATTR_ACCESS(a) \
((a) & (CSA_INSERT_CALENDAR_ATTRIBUTES | CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_CHANGE_CALENDAR_ATTR_ACCESS(a) \
((a) & (CSA_CHANGE_CALENDAR_ATTRIBUTES | CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_VIEW_ACCESS(a) ((a) & (CSA_VIEW_PUBLIC_ENTRIES | \
CSA_VIEW_CONFIDENTIAL_ENTRIES | \
CSA_VIEW_PRIVATE_ENTRIES | \
CSA_ORGANIZER_RIGHTS | \
CSA_SPONSOR_RIGHTS | \
CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_INSERT_ACCESS(a) ((a) & (CSA_INSERT_PUBLIC_ENTRIES | \
CSA_INSERT_CONFIDENTIAL_ENTRIES | \
CSA_INSERT_PRIVATE_ENTRIES | \
CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_CHANGE_ACCESS(a) ((a) & (CSA_CHANGE_PUBLIC_ENTRIES | \
CSA_CHANGE_CONFIDENTIAL_ENTRIES | \
CSA_CHANGE_PRIVATE_ENTRIES | \
CSA_ORGANIZER_RIGHTS | \
CSA_SPONSOR_RIGHTS | \
CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_V4_BROWSE_ACCESS(a) \
((a) & (access_read_4 | CSA_OWNER_RIGHTS))
#define _DTCMS_HAS_V4_WRITE_ACCESS(a) \
((a) & (access_write_4 | CSA_OWNER_RIGHTS))
extern CSA_return_code _DtCmsV4LoadAndCheckAccess P((
struct svc_req *svcrq,
char *target,
char **sender,
uint *access,
_DtCmsCalendar **cal));
extern CSA_return_code _DtCmsV5LoadAndCheckAccess P((
struct svc_req *svcrq,
char *target,
char **sender,
uint *access,
_DtCmsCalendar **cal));
extern CSA_return_code _DtCmsGetClientInfo P((
struct svc_req *svcrq,
char **source));
extern boolean_t _DtCmsIsFileOwner P((char *owner, char *user, char *target));
extern void _DtCmsShowAccessList P((Access_Entry_4 *l));
extern Access_Entry_4 *_DtCmsCalendarAccessList P((_DtCmsCalendar *cal));
extern Privacy_Level_4 _DtCmCheckPrivacyLevel P((char **p_src, Appt_4 *p_appt));
extern CSA_return_code _DtCmsCheckViewAccess P((
char *user,
uint access,
cms_entry *eptr));
extern CSA_return_code _DtCmsCheckChangeAccess P((
char *user,
uint access,
cms_entry *eptr));
extern uint _DtCmsClassToInsertAccess P((cms_entry *entry));
extern uint _DtCmsClassToViewAccess P((cms_entry *entry));
extern uint _DtCmsClassToChangeAccess P((cms_entry *entry));
#endif

View File

@@ -0,0 +1,660 @@
/* $XConsortium: callback.c /main/5 1996/10/03 10:40:51 drk $ */
/*
* (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 <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <rpc/rpc.h>
#include "agent.h"
#include "cmcb.h"
#include "callback.h"
#include "appt4.h"
#include "utility.h"
#include "lutil.h"
extern int debug;
extern char *pgname;
/*
* forward declaration of static functions used within the file
*/
static _DtCmsRegistrationInfo * _DtCmsDoCallback(
_DtCmsRegistrationInfo *rlist,
uint type,
char *source,
int pid,
int version,
void *args);
/*****************************************************************************
* extern functions
*****************************************************************************/
extern _DtCmsRegistrationInfo *
_DtCmsMakeRegistrationInfo(
char *client,
int types,
u_long prognum,
u_long versnum,
u_long procnum,
int pid)
{
_DtCmsRegistrationInfo *rinfo;
if ((rinfo = (_DtCmsRegistrationInfo *)calloc(1,
sizeof(_DtCmsRegistrationInfo))) == NULL)
return (NULL);
if ((rinfo->client = strdup(client)) == NULL) {
free(rinfo);
return (NULL);
}
rinfo->types = types;
rinfo->prognum = prognum;
rinfo->versnum = versnum;
rinfo->procnum = procnum;
rinfo->pid = pid;
rinfo->next = NULL;
return(rinfo);
}
extern void
_DtCmsFreeRegistrationInfo(_DtCmsRegistrationInfo *rinfo)
{
if (rinfo==NULL) return;
if (rinfo->client != NULL)
free(rinfo->client);
free(rinfo);
}
/*
* this routine is for v4, so type is not checked
*/
extern _DtCmsRegistrationInfo *
_DtCmsGetRegistration(
_DtCmsRegistrationInfo **_rlist,
char *client,
u_long prognum,
u_long versnum,
u_long procnum,
int pid)
{
_DtCmsRegistrationInfo *rlist = *_rlist,
*prev,
*ptr,
*tmp_ptr;
for (prev = ptr = rlist; ptr != NULL; ) {
if ((strcmp(ptr->client, client)==0) &&
(ptr->prognum == prognum) &&
(ptr->versnum == versnum) &&
(ptr->procnum == procnum))
{
if (ptr->pid == pid) {
*_rlist = rlist;
return (ptr);
} else {
/* ptr points to a stale record
* remove it from the linked list
* and update ptr and prev appropriately
*/
if (ptr == prev) { /* top of list */
rlist = rlist->next;
_DtCmsFreeRegistrationInfo(ptr);
ptr = prev = rlist;
} else {
prev->next = ptr->next;
tmp_ptr = ptr;
ptr = ptr->next;
_DtCmsFreeRegistrationInfo(tmp_ptr);
}
}
} else {
prev = ptr;
ptr = ptr->next;
}
}
*_rlist = rlist;
return (NULL);
}
/*
* Go through the registration list and ping each client.
* Deregister clients that do not respond.
*/
extern _DtCmsRegistrationInfo *
_DtCmsCheckRegistrationList(_DtCmsRegistrationInfo *rlist)
{
int nclients=0, ndereg=0;
char *sourcehost=NULL;
_DtCmsRegistrationInfo *p_next;
_DtCmsRegistrationInfo *p_prev;
_DtCmsRegistrationInfo *head;
struct timeval timeout_tv;
CLIENT *cl;
boolean_t advance = B_TRUE;
timeout_tv.tv_sec = 10;
timeout_tv.tv_usec = 0;
/* loop through the registration list */
head = p_prev = rlist;
while (rlist != NULL) {
p_next = rlist->next;
if (debug) {
fprintf(stderr,
"%s: pinging %s on prog: %ld, vers: %ld, proc: %ld\n",
pgname, rlist->client, rlist->prognum, rlist->versnum,
rlist->procnum);
}
sourcehost = _DtCmsTarget2Location(rlist->client);
cl = clnt_create(sourcehost, rlist->prognum, rlist->versnum,
"udp");
if (cl != NULL) {
clnt_control(cl, CLSET_TIMEOUT, (char *)&timeout_tv);
timeout_tv.tv_sec = 5;
clnt_control(cl, CLSET_RETRY_TIMEOUT,
(char*)&timeout_tv);
}
/* no client or client not responding */
if (cl == NULL || clnt_call(cl, 0, (xdrproc_t)xdr_void, (char *)NULL,
(xdrproc_t)xdr_void, (char *)NULL, timeout_tv) != RPC_SUCCESS)
{
if (debug) {
clnt_pcreateerror(sourcehost);
fprintf(stderr, "%s: %s deregistered, pid %d\n",
pgname, rlist->client, rlist->pid);
}
if (rlist == p_prev) { /* top of list */
head = p_next;
p_prev = p_next;
advance = B_FALSE;
} else {
p_prev->next = p_next;
}
/* deregister client */
_DtCmsFreeRegistrationInfo(rlist);
rlist = p_prev;
ndereg++;
}
if (cl)
clnt_destroy(cl);
free(sourcehost);
nclients++;
if (advance) {
p_prev = rlist;
rlist = p_next;
} else
advance = B_TRUE;
}
if (debug) {
fprintf(stderr, "%s: number of clients before cleanup = %d\n",
pgname, nclients);
fprintf(stderr, "%s: number of clients deregistered = %d\n",
pgname, ndereg);
}
return (head);
}
extern _DtCmsRegistrationInfo *
_DtCmsDoV1CbForV4Data(
_DtCmsRegistrationInfo *rlist,
char *source,
int pid,
cms_key *key1,
cms_key *key2)
{
Appt_4 appt1, appt2;
if (rlist == NULL)
return (rlist);
appt1.appt_id.tick = key1->time;
appt1.appt_id.key = key1->id;
if (key2) {
appt2.appt_id.tick = key2->time;
appt2.appt_id.key = key2->id;
appt2.next = NULL;
appt1.next = &appt2;
} else
appt1.next = NULL;
return (_DtCmsDoV1Callback(rlist, source, pid, &appt1));
}
/*
* this routine takes care of callbacks to clients using v1 of the callback
* protocol.
*/
extern _DtCmsRegistrationInfo *
_DtCmsDoV1Callback(
_DtCmsRegistrationInfo *rlist,
char *source,
int pid,
Appt_4 *a)
{
Uid_4 *k, *ids = NULL;
Table_Res_4 res;
int nclients=0, ncallbacks=0;
char *sourcehost=NULL;
_DtCmsRegistrationInfo *ptr;
_DtCmsRegistrationInfo *prev;
struct timeval timeout_tv;
CLIENT *cl;
boolean_t advance = B_TRUE;
if (rlist == NULL)
return (rlist);
/* Callback with appointment ids only for security reason. */
while (a != NULL)
{
if ((k = (Uid_4 *)malloc(sizeof(Uid_4))) == NULL) {
_DtCm_free_keyentry4(ids);
return (rlist);
}
k->appt_id = a->appt_id;
k->next = ids;
ids = k;
a = a->next;
}
res.status = access_ok_4;
res.res.tag = ID_4;
res.res.Table_Res_List_4_u.i = ids;
rlist = _DtCmsDoCallback(rlist, 0, source, pid, AGENTVERS, (void *)&res);
if (ids != NULL)
_DtCm_free_keyentry4(ids);
return (rlist);
}
extern void
_DtCmsListRegistration(_DtCmsRegistrationInfo *rlist, char *cal)
{
int n = 0;
fprintf(stderr, "registration list of calendar %s\n", cal);
while(rlist != NULL) {
n++;
fprintf(stderr, "\t%s (pid %d)\n", rlist->client, rlist->pid);
rlist = rlist->next;
}
fprintf(stderr, "\tnumber of registered clients = %d\n", n);
}
extern _DtCmsRegistrationInfo *
_DtCmsRemoveRegistration(
_DtCmsRegistrationInfo *rlist,
_DtCmsRegistrationInfo *rinfo)
{
_DtCmsRegistrationInfo *ptr, *prev;
for (ptr = prev = rlist; ptr != NULL; prev = ptr, ptr = ptr->next) {
if (ptr == rinfo) {
if (ptr == rlist)
rlist = ptr->next;
else
prev->next = ptr->next;
_DtCmsFreeRegistrationInfo(ptr);
break;
}
}
return (rlist);
}
extern _DtCmsRegistrationInfo *
_DtCmsDoOpenCalCallback(
_DtCmsRegistrationInfo *rlist,
char *cal,
char *user,
int pid)
{
cmcb_update_callback_args args;
char calendar[BUFSIZ];
if (rlist == NULL)
return (rlist);
sprintf(calendar, "%s@%s", cal, _DtCmGetLocalHost());
args.calendar = calendar;
args.user = user;
args.data.reason = CSA_CB_CALENDAR_LOGON;
return (_DtCmsDoCallback(rlist, CSA_CB_CALENDAR_LOGON, user, pid,
AGENTVERS_2, (void *)&args));
}
extern _DtCmsRegistrationInfo *
_DtCmsDoRemoveCalCallback(
_DtCmsRegistrationInfo *rlist,
char *cal,
char *user,
int pid)
{
cmcb_update_callback_args args;
char calendar[BUFSIZ];
if (rlist == NULL)
return (rlist);
sprintf(calendar, "%s@%s", cal, _DtCmGetLocalHost());
args.calendar = calendar;
args.user = user;
args.data.reason = CSA_CB_CALENDAR_DELETED;
return (_DtCmsDoCallback(rlist, CSA_CB_CALENDAR_DELETED, user, pid,
AGENTVERS_2, (void *)&args));
}
extern _DtCmsRegistrationInfo *
_DtCmsDoUpdateCalAttrsCallback(
_DtCmsRegistrationInfo *rlist,
char *cal,
char *user,
uint num_attrs,
cms_attribute *attrs,
int pid)
{
cmcb_update_callback_args args;
cmcb_cal_attr_data cdata;
_DtCmsRegistrationInfo *res;
char buf[80];
char calendar[BUFSIZ];
int i;
if (rlist == NULL)
return (rlist);
sprintf(calendar, "%s@%s", cal, _DtCmGetLocalHost());
/* set up update info */
if (num_attrs > 0 &&
(cdata.names = (char **)calloc(1, sizeof(char *)*num_attrs)))
{
for (i = 0; i < num_attrs; i++)
cdata.names[i] = attrs[i].name.name;
} else {
cdata.num_names = 0;
cdata.names = NULL;
}
args.calendar = calendar;
args.user = user;
args.data.reason = CSA_CB_CALENDAR_ATTRIBUTE_UPDATED;
args.data.data.cdata = &cdata;
res = _DtCmsDoCallback(rlist, CSA_CB_CALENDAR_ATTRIBUTE_UPDATED, user,
pid, AGENTVERS_2, (void *)&args);
if (num_attrs > 0) free(cdata.names);
return (res);
}
extern _DtCmsRegistrationInfo *
_DtCmsDoInsertEntryCallback(
_DtCmsRegistrationInfo *rlist,
char *cal,
char *source,
long id,
int pid)
{
cmcb_update_callback_args args;
cmcb_add_entry_data adata;
char buf[80];
char calendar[BUFSIZ];
if (rlist == NULL)
return (rlist);
sprintf(calendar, "%s@%s", cal, _DtCmGetLocalHost());
/* set up update info */
sprintf(buf, "%ld", id);
adata.id = buf;
args.calendar = calendar;
args.user = source;
args.data.reason = CSA_CB_ENTRY_ADDED;
args.data.data.adata = &adata;
return (_DtCmsDoCallback(rlist, CSA_CB_ENTRY_ADDED, source, pid,
AGENTVERS_2, (void *)&args));
}
extern _DtCmsRegistrationInfo *
_DtCmsDoDeleteEntryCallback(
_DtCmsRegistrationInfo *rlist,
char *cal,
char *source,
long id,
int scope,
time_t time,
int pid)
{
cmcb_update_callback_args args;
cmcb_delete_entry_data ddata;
char buf[80];
char calendar[BUFSIZ];
if (rlist == NULL)
return (rlist);
sprintf(calendar, "%s@%s", cal, _DtCmGetLocalHost());
/* set up update info */
sprintf(buf, "%ld", id);
ddata.id = buf;
ddata.scope = scope;
ddata.time = time;
args.calendar = calendar;
args.user = source;
args.data.reason = CSA_CB_ENTRY_DELETED;
args.data.data.ddata = &ddata;
return (_DtCmsDoCallback(rlist, CSA_CB_ENTRY_DELETED, source, pid,
AGENTVERS_2, (void *)&args));
}
extern _DtCmsRegistrationInfo *
_DtCmsDoUpdateEntryCallback(
_DtCmsRegistrationInfo *rlist,
char *cal,
char *source,
long newid,
long oldid,
int scope,
long time,
int pid)
{
cmcb_update_callback_args args;
cmcb_update_entry_data udata;
char nbuf[80], obuf[80];
char calendar[BUFSIZ];
if (rlist == NULL)
return (rlist);
sprintf(calendar, "%s@%s", cal, _DtCmGetLocalHost());
/* set up update info */
sprintf(obuf, "%ld", oldid);
udata.oldid = obuf;
if (newid > 0)
sprintf(nbuf, "%ld", newid);
else
nbuf[0] = NULL;
udata.newid = nbuf;
udata.scope = scope;
udata.time = time;
args.calendar = calendar;
args.user = source;
args.data.reason = CSA_CB_ENTRY_UPDATED;
args.data.data.udata = &udata;
return (_DtCmsDoCallback(rlist, CSA_CB_ENTRY_UPDATED, source, pid,
AGENTVERS_2, (void *)&args));
}
/*
* this routine takes care of callbacks to clients using either
* v1 or v2 of the callback protocol.
*/
static _DtCmsRegistrationInfo *
_DtCmsDoCallback(
_DtCmsRegistrationInfo *rlist,
uint type,
char *source,
int pid,
int version,
void *args)
{
int nclients=0, ncallbacks=0;
char *sourcehost=NULL;
_DtCmsRegistrationInfo *ptr;
_DtCmsRegistrationInfo *prev;
struct timeval timeout_tv;
CLIENT *cl;
boolean_t advance = B_TRUE;
/*
* loop through the registration list looking for parties
* interested in this transaction.
*/
for (ptr = prev = rlist; ptr != NULL; ) {
/* The caller will get the results of the rpc call.
* If he's registered on the callback list, don't call him -
* UNLESS the process id of his client differs from the
* original ticket. However, if the pid is a VOIDPID (-1),
* a version 2 client has registered and there's no way
* of telling which instance of the client it is. So,
* to be safe (avoid deadlock) we won't callback version
* 2 clients registered on version 3 daemons if their
* registration name entry matches the caller's. [Nanno]
*/
if (version != ptr->versnum ||
(type && !(type & ptr->types)) ||
((strcmp(source, ptr->client) == 0) &&
((pid == ptr->pid) || (pid == -1 ) || (ptr->pid == -1)))) {
prev = ptr;
ptr = ptr->next;
nclients++;
continue;
}
sourcehost = _DtCmsTarget2Location(ptr->client);
if (debug) {
fprintf(stderr,
"%s: calling back %s on prog: %ld, vers: %ld, proc: %ld\n",
pgname, ptr->client, ptr->prognum, ptr->versnum,
ptr->procnum);
}
cl = clnt_create(sourcehost, ptr->prognum, ptr->versnum, "udp");
/* deregister client if fails to create handle */
if (cl == NULL) {
if (debug) {
clnt_pcreateerror(sourcehost);
}
if (ptr == rlist) { /* top of list */
rlist = ptr->next;
prev = rlist;
advance = B_FALSE;
} else {
prev->next = ptr->next;
}
/* deregister client */
_DtCmsFreeRegistrationInfo(ptr);
ptr = prev;
} else {
/* Set timeout to zero so that the call
* returns right away.
*/
timeout_tv.tv_sec = 0;
timeout_tv.tv_usec = 0;
#ifndef SunOS
/* for non-sun systems, clnt_call won't
* return right away unless timeout is set
* to zero using clnt_control(), (rpc bug?)
*/
clnt_control(cl, CLSET_TIMEOUT,
(char *)&timeout_tv);
#endif
if (version == AGENTVERS) {
(void)clnt_call(cl, ptr->procnum,
(xdrproc_t)_DtCm_xdr_Table_Res_4, (char *)args,
(xdrproc_t)xdr_void, (char *)0, timeout_tv);
} else if (version == AGENTVERS_2) {
(void)clnt_call(cl, ptr->procnum,
(xdrproc_t)xdr_cmcb_update_callback_args,
(char *)args, (xdrproc_t)xdr_void, (char *)0,
timeout_tv);
}
ncallbacks++;
nclients++;
}
if (cl)
clnt_destroy(cl);
free(sourcehost);
if (advance) {
prev = ptr;
ptr = ptr->next;
} else
advance = B_TRUE;
}
if (debug) {
fprintf(stderr, "%s: number of registered clients = %d\n",
pgname, nclients);
fprintf(stderr, "%s: number of clients called back= %d\n",
pgname, ncallbacks);
}
return (rlist);
}

View File

@@ -0,0 +1,113 @@
/* $XConsortium: callback.h /main/4 1995/11/09 12:40:25 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.
*/
#ifndef _CALLBACK_H
#define _CALLBACK_H
#include "ansi_c.h"
#include "rtable4.h"
typedef struct __DtCmsRegistrationInfo {
char *client;
int types;
u_long prognum;
u_long versnum;
u_long procnum;
int pid;
struct __DtCmsRegistrationInfo *next;
} _DtCmsRegistrationInfo;
extern _DtCmsRegistrationInfo *_DtCmsMakeRegistrationInfo P((
char *client,
int types,
u_long prognum,
u_long versnum,
u_long procnum,
int pid));
extern void _DtCmsFreeRegistrationInfo P((_DtCmsRegistrationInfo *w));
extern _DtCmsRegistrationInfo *_DtCmsGetRegistration P((
_DtCmsRegistrationInfo **rlist,
char *client,
u_long prognum,
u_long versnum,
u_long procnum,
int pid));
extern _DtCmsRegistrationInfo *_DtCmsRemoveRegistration P((
_DtCmsRegistrationInfo *rlist,
_DtCmsRegistrationInfo *rinfo));
extern _DtCmsRegistrationInfo *_DtCmsCheckRegistrationList P((
_DtCmsRegistrationInfo *rlist));
extern _DtCmsRegistrationInfo * _DtCmsDoV1CbForV4Data P((
_DtCmsRegistrationInfo *rlist,
char *source,
int pid,
cms_key *key1,
cms_key *key2));
extern _DtCmsRegistrationInfo *_DtCmsDoV1Callback P((
_DtCmsRegistrationInfo *rlist,
char *source,
int pid,
Appt_4 *a));
extern _DtCmsRegistrationInfo *_DtCmsDoOpenCalCallback P((
_DtCmsRegistrationInfo *rlist,
char *cal,
char *user,
int pid));
extern _DtCmsRegistrationInfo *_DtCmsDoRemoveCalCallback P((
_DtCmsRegistrationInfo *rlist,
char *cal,
char *user,
int pid));
extern _DtCmsRegistrationInfo *_DtCmsDoUpdateCalAttrsCallback P((
_DtCmsRegistrationInfo *rlist,
char *cal,
char *user,
uint num_attrs,
cms_attribute *attrs,
int pid));
extern _DtCmsRegistrationInfo *_DtCmsDoInsertEntryCallback P((
_DtCmsRegistrationInfo *rlist,
char *cal,
char *source,
long id,
int pid));
extern _DtCmsRegistrationInfo *_DtCmsDoDeleteEntryCallback P((
_DtCmsRegistrationInfo *rlist,
char *cal,
char *source,
long id,
int scope,
time_t time,
int pid));
extern _DtCmsRegistrationInfo *_DtCmsDoUpdateEntryCallback P((
_DtCmsRegistrationInfo *rlist,
char *cal,
char *source,
long newid,
long oldid,
int scope,
long time,
int pid));
extern void _DtCmsListRegistration P((_DtCmsRegistrationInfo *rlist,
char *cal));
#endif

View File

@@ -0,0 +1,107 @@
/*******************************************************************************
**
** cm_tbl.i
**
** static char sccsid[] = "@(#)cm_tbl.i 1.1 94/09/05 Copyr 1991 Sun Microsystems, Inc.";
**
** $XConsortium: cm_tbl.i /main/3 1995/11/03 11:08:33 rswiston $
**
** RESTRICTED CONFIDENTIAL INFORMATION:
**
** The information in this document is subject to special
** restrictions in a confidential disclosure agreement between
** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
** document outside HP, IBM, Sun, USL, SCO, or Univel without
** Sun's specific written approval. This document and all copies
** and derivative works thereof must be returned or destroyed at
** Sun's request.
**
** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
**
*******************************************************************************/
/*
* Program table for calendar manager rpc protocol version 5
*/
struct rpcgen_table tableprog_5_table[] = {
(char *(*)())RPCGEN_ACTION(cms_ping_5_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_void, 0,
(char *(*)())RPCGEN_ACTION(cms_list_calendars_5_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_cms_list_calendars_res, sizeof ( cms_list_calendars_res ),
(char *(*)())RPCGEN_ACTION(cms_open_calendar_5_svc),
(xdrproc_t)xdr_cms_open_args, sizeof ( cms_open_args ),
(xdrproc_t)xdr_cms_open_res, sizeof ( cms_open_res ),
(char *(*)())RPCGEN_ACTION(cms_create_calendar_5_svc),
(xdrproc_t)xdr_cms_create_args, sizeof ( cms_create_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
(char *(*)())RPCGEN_ACTION(cms_remove_calendar_5_svc),
(xdrproc_t)xdr_cms_remove_args, sizeof ( cms_remove_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
(char *(*)())RPCGEN_ACTION(cms_register_5_svc),
(xdrproc_t)xdr_cms_register_args, sizeof ( cms_register_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
(char *(*)())RPCGEN_ACTION(cms_unregister_5_svc),
(xdrproc_t)xdr_cms_register_args, sizeof ( cms_register_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
(char *(*)())RPCGEN_ACTION(cms_enumerate_calendar_attr_5_svc),
(xdrproc_t)xdr_cms_name, sizeof ( cms_name ),
(xdrproc_t)xdr_cms_enumerate_calendar_attr_res,sizeof ( cms_enumerate_calendar_attr_res ),
(char *(*)())RPCGEN_ACTION(cms_get_calendar_attr_5_svc),
(xdrproc_t)xdr_cms_get_cal_attr_args, sizeof ( cms_get_cal_attr_args ),
(xdrproc_t)xdr_cms_get_cal_attr_res, sizeof ( cms_get_cal_attr_res ),
(char *(*)())RPCGEN_ACTION(cms_set_calendar_attr_5_svc),
(xdrproc_t)xdr_cms_set_cal_attr_args, sizeof ( cms_set_cal_attr_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
(char *(*)())RPCGEN_ACTION(cms_archive_5_svc),
(xdrproc_t)xdr_cms_archive_args, sizeof ( cms_archive_args ),
(xdrproc_t)xdr_cms_archive_res, sizeof ( cms_archive_res ),
(char *(*)())RPCGEN_ACTION(cms_restore_5_svc),
(xdrproc_t)xdr_cms_restore_args, sizeof ( cms_restore_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
(char *(*)())RPCGEN_ACTION(cms_lookup_reminder_5_svc),
(xdrproc_t)xdr_cms_reminder_args, sizeof ( cms_reminder_args ),
(xdrproc_t)xdr_cms_reminder_res, sizeof ( cms_reminder_res ),
(char *(*)())RPCGEN_ACTION(cms_lookup_entries_5_svc),
(xdrproc_t)xdr_cms_lookup_entries_args, sizeof ( cms_lookup_entries_args ),
(xdrproc_t)xdr_cms_entries_res, sizeof ( cms_entries_res ),
(char *(*)())RPCGEN_ACTION(cms_enumerate_sequence_5_svc),
(xdrproc_t)xdr_cms_enumerate_args, sizeof ( cms_enumerate_args ),
(xdrproc_t)xdr_cms_entries_res, sizeof ( cms_entries_res ),
(char *(*)())RPCGEN_ACTION(cms_get_entry_attr_5_svc),
(xdrproc_t)xdr_cms_get_entry_attr_args, sizeof ( cms_get_entry_attr_args ),
(xdrproc_t)xdr_cms_get_entry_attr_res, sizeof ( cms_get_entry_attr_res ),
(char *(*)())RPCGEN_ACTION(cms_insert_entry_5_svc),
(xdrproc_t)xdr_cms_insert_args, sizeof ( cms_insert_args ),
(xdrproc_t)xdr_cms_entry_res, sizeof ( cms_entry_res ),
(char *(*)())RPCGEN_ACTION(cms_update_entry_5_svc),
(xdrproc_t)xdr_cms_update_args, sizeof ( cms_update_args ),
(xdrproc_t)xdr_cms_entry_res, sizeof ( cms_entry_res ),
(char *(*)())RPCGEN_ACTION(cms_delete_entry_5_svc),
(xdrproc_t)xdr_cms_delete_args, sizeof ( cms_delete_args ),
(xdrproc_t)xdr_u_int, sizeof ( u_int ),
};
int tableprog_5_nproc =
sizeof(tableprog_5_table)/sizeof(tableprog_5_table[0]);

View File

@@ -0,0 +1,295 @@
/*******************************************************************************
**
** cmsattr.c
**
** $XConsortium: cmsattr.c /main/3 1995/11/03 11:08:50 rswiston $
**
** RESTRICTED CONFIDENTIAL INFORMATION:
**
** The information in this document is subject to special
** restrictions in a confidential disclosure agreement between
** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
** document outside HP, IBM, Sun, USL, SCO, or Univel without
** Sun's specific written approval. This document and all copies
** and derivative works thereof must be returned or destroyed at
** Sun's request.
**
** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
**
*******************************************************************************/
#ifndef lint
static char sccsid[] = "@(#)cmsattr.c 1.2 94/10/05 Copyr 1991 Sun Microsystems, Inc.";
#endif
#include <EUSCompat.h>
#include <stdlib.h>
#include <string.h>
#include "csa.h"
#include "cm.h"
#include "attr.h"
#include "cmsdata.h"
extern CSA_return_code
_DtCmsUpdateSint32AttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
cms_attribute_value *val;
if (newval) {
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = newval->type;
*attrval = val;
}
(*attrval)->item.sint32_value = newval->item.sint32_value;
} else if (*attrval) {
free(*attrval);
*attrval = NULL;
}
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsUpdateUint32AttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
cms_attribute_value *val;
if (newval) {
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = newval->type;
*attrval = val;
}
(*attrval)->item.uint32_value = newval->item.uint32_value;
} else if (*attrval) {
free(*attrval);
*attrval = NULL;
}
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsUpdateStringAttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
cms_attribute_value *val;
char *newstring = NULL;
if (newval) {
if (newval->item.string_value &&
(newstring = strdup(newval->item.string_value)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
if (newstring)
free(newstring);
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = newval->type;
} else {
val = *attrval;
if (val->item.string_value)
free(val->item.string_value);
}
val->item.string_value = newstring;
*attrval = val;
} else if (*attrval) {
free((*attrval)->item.string_value);
free(*attrval);
*attrval = NULL;
}
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsUpdateAccessListAttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
cms_attribute_value *val;
cms_access_entry *newlist = NULL;
if (newval && newval->item.access_list_value &&
(newlist = _DtCm_copy_cms_access_list(
newval->item.access_list_value)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
if (newlist)
_DtCm_free_cms_access_entry(newlist);
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_ACCESS_LIST;
} else {
val = *attrval;
_DtCm_free_cms_access_entry(
(cms_access_entry *)val->item.access_list_value);
}
val->item.access_list_value = newlist;
*attrval = val;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsUpdateReminderAttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
CSA_return_code stat;
cms_attribute_value *val;
CSA_reminder *rem = NULL;
if (newval && newval->item.reminder_value) {
if ((stat = _DtCm_copy_reminder(newval->item.reminder_value,
&rem)) != CSA_SUCCESS)
return (CSA_E_INSUFFICIENT_MEMORY);
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
if (rem)
_DtCm_free_reminder(rem);
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = newval->type;
} else {
val = *attrval;
if (val->item.reminder_value)
_DtCm_free_reminder(val->item.reminder_value);
}
val->item.reminder_value = rem;
*attrval = val;
} else if (*attrval) {
_DtCm_free_reminder((*attrval)->item.reminder_value);
free(*attrval);
*attrval = NULL;
}
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsUpdateDateTimeListAttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
cms_attribute_value *val;
CSA_date_time_list dtlist = NULL;
if (newval && newval->item.date_time_list_value) {
if ((dtlist = _DtCm_copy_date_time_list(
newval->item.date_time_list_value)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
if (dtlist)
_DtCm_free_date_time_list(dtlist);
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = newval->type;
} else {
val = *attrval;
if (val->item.date_time_list_value)
_DtCm_free_date_time_list(
val->item.date_time_list_value);
}
val->item.date_time_list_value = dtlist;
*attrval = val;
} else if (*attrval) {
_DtCm_free_date_time_list((*attrval)->item.date_time_list_value);
free(*attrval);
*attrval = NULL;
}
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsUpdateOpaqueDataAttrVal(
cms_attribute_value *newval,
cms_attribute_value **attrval)
{
CSA_return_code stat;
cms_attribute_value *val;
CSA_opaque_data *opq = NULL;
if (newval && newval->item.opaque_data_value) {
if ((stat = _DtCm_copy_opaque_data(
newval->item.opaque_data_value, &opq)) != CSA_SUCCESS)
return (CSA_E_INSUFFICIENT_MEMORY);
if (*attrval == NULL) {
if ((val = (cms_attribute_value *)malloc(
sizeof(cms_attribute_value))) == NULL) {
if (opq) _DtCm_free_opaque_data(opq);
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = newval->type;
} else {
val = *attrval;
if (val->item.opaque_data_value)
_DtCm_free_opaque_data(
val->item.opaque_data_value);
}
val->item.opaque_data_value = opq;
*attrval = val;
} else if (*attrval) {
_DtCm_free_opaque_data((*attrval)->item.opaque_data_value);
free(*attrval);
*attrval = NULL;
}
return (CSA_SUCCESS);
}

View File

@@ -0,0 +1,57 @@
/*******************************************************************************
**
** cmsattr.h
**
** static char sccsid[] = "@(#)cmsattr.h 1.2 94/10/05 Copyr 1991 Sun Microsystems, Inc.";
**
** $XConsortium: cmsattr.h /main/3 1995/11/03 11:09:10 rswiston $
**
** RESTRICTED CONFIDENTIAL INFORMATION:
**
** The information in this document is subject to special
** restrictions in a confidential disclosure agreement between
** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
** document outside HP, IBM, Sun, USL, SCO, or Univel without
** Sun's specific written approval. This document and all copies
** and derivative works thereof must be returned or destroyed at
** Sun's request.
**
** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
**
*******************************************************************************/
#ifndef _CMSATTR_H
#define _CMSATTR_H
#include "ansi_c.h"
#include "cm.h"
#include "cmscalendar.h"
extern CSA_return_code _DtCmsUpdateSint32AttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
extern CSA_return_code _DtCmsUpdateUint32AttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
extern CSA_return_code _DtCmsUpdateStringAttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
extern CSA_return_code _DtCmsUpdateAccessListAttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
extern CSA_return_code _DtCmsUpdateReminderAttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
extern CSA_return_code _DtCmsUpdateDateTimeListAttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
extern CSA_return_code _DtCmsUpdateOpaqueDataAttrVal P((
cms_attribute_value *newval,
cms_attribute_value **attrval));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
/* $XConsortium: cmscalendar.h /main/4 1995/11/09 12:40:57 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.
*/
#ifndef _CMSCALENDAR_H
#define _CMSCALENDAR_H
#include "ansi_c.h"
#include "csa.h"
#include "cm.h"
#include "nametbl.h"
#include "tree.h"
#include "list.h"
#include "data.h"
#include "reminder.h"
#include "rtable4.h"
#include "callback.h"
#include "log.h"
#define GET_R_ACCESS(cal) ((Access_Entry_4 *) (cal->r_access))
#define SET_R_ACCESS(cal,v) (cal)->r_access = (caddr_t) v
#define GET_W_ACCESS(cal) ((Access_Entry_4 *) (cal->w_access))
#define SET_W_ACCESS(cal,v) (cal)->w_access = (caddr_t) v
#define GET_D_ACCESS(cal) ((Access_Entry_4 *) (cal->d_access))
#define SET_D_ACCESS(cal,v) (cal)->d_access = (caddr_t) v
#define GET_X_ACCESS(cal) ((Access_Entry_4 *) (cal->x_access))
#define SET_X_ACCESS(cal,v) (cal)->x_access = (caddr_t) v
#define APPT_TREE(info) ((Rb_tree *) ((info)->tree))
#define REPT_LIST(info) ((Hc_list *) ((info)->list))
#define APPT_KEY(p_appt) ((Appt_4 *) (p_appt))->appt_id.key
#define APPT_TICK(p_appt) ((Appt_4 *) (p_appt))->appt_id.tick
typedef CSA_return_code (*_DtCmGetAttrFunc)();
typedef struct __DtCmsCalendar {
char *owner;
char *calendar;
_DtCmNameTable *cal_tbl;
_DtCmNameTable *entry_tbl;
int *types; /* type associated with entry attrs */
int num_entry_attrs; /* number of entry attrs associated
* with this calendar */
boolean_t hashed; /* true if file converted to hashed
* format */
int fversion;
long lastkey;
boolean_t modified; /* if true, do garbage collection */
Rb_tree *tree; /* for single appointments */
Hc_list *list; /* for repeating appointments */
Rm_que *rm_queue; /* active reminder queue, version 1 */
_DtCmsRemQueue *remq; /* reminder queue, version 4 */
caddr_t r_access; /* read access, version 1 */
caddr_t w_access; /* write access, version 1 */
caddr_t d_access; /* delete access, version 1 */
caddr_t x_access; /* exec access, version 1 */
Access_Entry_4 *alist; /* combined v1 access list */
uint num_attrs; /* number of calendar attrs,version 4 */
cms_attribute *attrs; /* calendar attributes, version 4 */
_DtCmGetAttrFunc *getattrfuncs; /* array of function ptr to get attrs */
_DtCmsRegistrationInfo *rlist; /* client registration list */
boolean_t *checkowner;
struct __DtCmsCalendar *next;
} _DtCmsCalendar;
extern _DtCmsCalendar * _DtCmsMakeCalendar P((
char *owner,
char *name));
extern void _DtCmsPutInCalList P((_DtCmsCalendar *cal));
extern void _DtCmsFreeCalendar P((_DtCmsCalendar *cal));
extern CSA_return_code _DtCmsSetFileVersion P((
_DtCmsCalendar *cal,
int version));
extern CSA_return_code _DtCmsLoadCalendar P((
char *target,
_DtCmsCalendar **cal));
extern char * _DtCmsGetCalendarOwner P((char *target));
extern CSA_return_code _DtCmsGetCalendarByName P((
char *target,
boolean_t load,
_DtCmsCalendar **cal));
extern CSA_return_code _DtCmsInsertEntry4Parser P((
_DtCmsCalendar *cal,
cms_entry *entry));
extern void _DtCmsSetAccess4Parser P((
_DtCmsCalendar *cal,
Access_Entry_4 *list,
int type));
extern void _DtCmsSetCalendarAttrs4Parser P((
_DtCmsCalendar *cal,
int len,
cms_attribute *attrs));
extern void _DtCmsGenerateKey P((_DtCmsCalendar *cal, long *key));
extern CSA_return_code _DtCmsEnumerateUp P((
_DtCmsCalendar *cal,
_DtCmsEnumerateProc doit));
extern void _DtCmsEnumerateDown P((
_DtCmsCalendar *cal,
_DtCmsEnumerateProc doit));
extern CSA_return_code _DtCmsRbToCsaStat P((Rb_Status rb_stat));
extern CSA_return_code _DtCmsGetCalAttrsByName P((
_DtCmsCalendar *cal,
uint num_names,
cms_attr_name *names,
uint *num_attrs_r,
cms_attribute **attrs_r));
extern CSA_return_code _DtCmsGetAllCalAttrs P((
_DtCmsCalendar *cal,
u_int *num_attrs_r,
cms_attribute **attrs_r,
boolean_t returnall));
extern CSA_return_code _DtCmsGetCalAttrNames P((
_DtCmsCalendar *cal,
uint *num_names_r,
cms_attr_name **names_r));
extern void _DtCmsFreeCmsAttrNames P((uint num, cms_attr_name *names));
extern CSA_return_code _DtCmsUpdateCalAttributesAndLog P((
_DtCmsCalendar *cal,
uint numsrc,
cms_attribute *srcattrs,
uint access));
extern CSA_return_code _DtCmsV5TransactLog P((
_DtCmsCalendar *cal,
cms_entry *e,
_DtCmsLogOps op));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
/* $XConsortium: cmsconvert.h /main/4 1995/11/09 12:41:30 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.
*/
#ifndef _CMSCONVERT_H
#define _CMSCONVERT_H
#include <EUSCompat.h>
#include "ansi_c.h"
#include "cm.h"
#include "rtable4.h"
#include "v4ops.h"
extern CSA_return_code _DtCmsCmsentriesToAppt4ForClient P((
cms_entry *entries,
Appt_4 **appt));
extern CSA_return_code _DtCmsCmsentriesToAbbrAppt4ForClient P((
cms_entry *entries,
Abb_Appt_4 **abbr));
extern CSA_return_code _DtCmsCmsentryToAbbrAppt4 P((
cms_entry *entry,
Abb_Appt_4 **abbr));
extern Access_Entry_4 *_DtCmsConvertV5AccessList P((
cms_access_entry *cmslist,
boolean_t strictmode));
extern cms_access_entry *_DtCmsConvertV4AccessList P((
Access_Entry_4 *alist));
extern CSA_return_code _DtCmsReminderRefToReminder P((
cms_reminder_ref *rems,
Reminder_4 **r4));
extern CSA_return_code _DtCmsV4ReminderToReminderRef P((
char *calname,
Reminder_4 *r4,
_DtCmsEntryId *ids,
cms_reminder_ref **rems));
extern CSA_return_code _DtCmsCmsAccessToV4Access P((
cms_access_entry *alist,
Access_Entry_4 **a4));
extern CSA_return_code _DtCmsAppt4ToCmsentriesForClient P((
char *calname,
Appt_4 *appt,
cms_entry **e_r));
extern CSA_return_code _DtCmsAppt4ToCmsentry P((
char *calname,
Appt_4 *a4,
cms_entry **entry_r,
boolean_t rerule));
extern CSA_return_code _DtCmsAttrsToAppt4 P((
uint size,
cms_attribute *attrs,
Appt_4 *appt,
boolean_t check));
#endif

View File

@@ -0,0 +1,181 @@
/* $XConsortium: cmsentry.c /main/4 1995/11/09 12:41:44 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 <string.h>
#include <stdlib.h>
#include "cmsentry.h"
#include "cmsdata.h"
#include "nametbl.h"
#include "attr.h"
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static CSA_return_code
_ExtractEntryAttrsFromEntry(uint srcsize, cms_attribute *srcattrs,
uint *dstsize, cms_attribute **dstattrs, boolean_t time_only);
/*****************************************************************************
* extern functions
*****************************************************************************/
/*
* Given a hashed name table, initialize a new cms_entry with
* the given list of attribute values
*/
extern CSA_return_code
_DtCmsMakeHashedEntry(
_DtCmsCalendar *cal,
uint num,
cms_attribute *attrs,
cms_entry **entry)
{
int i, index;
cms_entry *eptr;
CSA_return_code stat = CSA_SUCCESS;
if (cal == NULL || entry == NULL)
return (CSA_E_INVALID_PARAMETER);
if ((eptr = _DtCm_make_cms_entry(cal->entry_tbl)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
for (i = 0; i < num && stat == CSA_SUCCESS; i++) {
index = _DtCm_get_index_from_table(cal->entry_tbl,
attrs[i].name.name);
if (index > 0) {
/* check type */
if (index > _DtCM_DEFINED_ENTRY_ATTR_SIZE &&
attrs[i].value &&
attrs[i].value->type != cal->types[index])
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
else
stat = _DtCm_copy_cms_attr_val(attrs[i].value,
&eptr->attrs[index].value);
} else if (attrs[i].value) {
if ((stat = _DtCmExtendNameTable(attrs[i].name.name, 0,
attrs[i].value->type, _DtCm_entry_name_tbl,
_DtCM_DEFINED_ENTRY_ATTR_SIZE,
_CSA_entry_attribute_names, &cal->entry_tbl,
&cal->types)) == CSA_SUCCESS) {
attrs[i].name.num = cal->entry_tbl->size;
stat = _DtCmGrowAttrArray(&eptr->num_attrs,
&eptr->attrs, &attrs[i]);
}
}
}
if (stat != CSA_SUCCESS) {
_DtCm_free_cms_entry(eptr);
return (stat);
}
*entry = eptr;
return (CSA_SUCCESS);
}
extern void
_DtCmsFreeEntryAttrResItem(cms_get_entry_attr_res_item *elist)
{
cms_get_entry_attr_res_item *ptr;
while (elist) {
ptr = elist->next;
_DtCm_free_cms_attributes(elist->num_attrs, elist->attrs);
free(elist);
elist = ptr;
}
}
extern CSA_return_code
_DtCmsGetCmsEntryForClient(cms_entry *e, cms_entry **e_r, boolean_t time_only)
{
cms_entry *ptr;
CSA_return_code stat;
if (e == NULL || e_r == NULL)
return (CSA_E_INVALID_PARAMETER);
if ((ptr = (cms_entry *)calloc(1, sizeof(cms_entry))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if ((stat = _ExtractEntryAttrsFromEntry(e->num_attrs, e->attrs,
&ptr->num_attrs, &ptr->attrs,time_only)) != CSA_SUCCESS) {
free(ptr);
return (stat);
} else {
ptr->key = e->key;
*e_r = ptr;
return (CSA_SUCCESS);
}
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static CSA_return_code
_ExtractEntryAttrsFromEntry(
uint srcsize,
cms_attribute *srcattrs,
uint *dstsize,
cms_attribute **dstattrs,
boolean_t time_only)
{
CSA_return_code stat;
int i, j;
cms_attribute *attrs;
if (dstsize == NULL || dstattrs == NULL)
return (CSA_E_INVALID_PARAMETER);
*dstsize = 0;
*dstattrs = NULL;
if (srcsize == 0)
return (CSA_SUCCESS);
if ((attrs = calloc(1, sizeof(cms_attribute) * srcsize)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
for (i = 0, j = 0; i <= srcsize; i++) {
if (srcattrs[i].value == NULL)
continue;
if ((stat = _DtCm_copy_cms_attribute(&attrs[j], &srcattrs[i],
B_TRUE)) != CSA_SUCCESS)
break;
else {
if ( (i == CSA_ENTRY_ATTR_SUMMARY_I) && (time_only == B_TRUE) ) {
if (attrs[j].value && attrs[j].value->item.string_value)
attrs[j].value->item.string_value[0] = '\0';
}
j++;
}
}
if (stat == CSA_SUCCESS && j > 0) {
*dstsize = j;
*dstattrs = attrs;
} else {
_DtCm_free_cms_attributes(j, attrs);
free(attrs);
}
return (stat);
}

View File

@@ -0,0 +1,32 @@
/* $XConsortium: cmsentry.h /main/4 1995/11/09 12:41:58 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.
*/
#ifndef _CMSENTRY_H
#define _CMSENTRY_H
#include <EUSCompat.h>
#include "ansi_c.h"
#include "nametbl.h"
#include "cm.h"
#include "csa.h"
#include "cmscalendar.h"
extern CSA_return_code _DtCmsMakeHashedEntry P((
_DtCmsCalendar *cal,
uint num,
cms_attribute *attrs,
cms_entry **entry));
extern void _DtCmsFreeEntryAttrResItem P((cms_get_entry_attr_res_item *elist));
extern CSA_return_code _DtCmsGetCmsEntryForClient P((
cms_entry *e,
cms_entry **e_r,
boolean_t time_only));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
/* $XConsortium: cmsmatch.c /main/4 1995/11/09 12:42:30 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 <string.h>
#include "cmsmatch.h"
#include "iso8601.h"
#include "misc.h"
#include "match.h"
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static boolean_t _MatchOneAttribute(cms_attribute eattr, cms_attribute mattr,
int op);
/*****************************************************************************
* extern functions
*****************************************************************************/
extern boolean_t
_DtCmsMatchAttributes(
cms_entry *entry,
uint num_attrs,
cms_attribute *attrs,
CSA_enum *ops)
{
int i;
for (i = 0; i < num_attrs; i++) {
if (attrs[i].name.num > entry->num_attrs)
return (B_FALSE);
if (_MatchOneAttribute(entry->attrs[attrs[i].name.num],
attrs[i], (ops ? ops[i] : CSA_MATCH_EQUAL_TO)) == B_FALSE)
return (B_FALSE);
}
return (B_TRUE);
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static boolean_t
_MatchOneAttribute(cms_attribute eattr, cms_attribute mattr, int op)
{
if (eattr.value == NULL) {
if (op == CSA_MATCH_EQUAL_TO && mattr.value == NULL)
return (B_TRUE);
else
return (B_FALSE);
}
switch (eattr.value->type) {
case CSA_VALUE_ENUMERATED:
case CSA_VALUE_SINT32:
return (_DtCm_match_sint32_attribute(eattr.value, mattr.value,
op));
case CSA_VALUE_BOOLEAN:
case CSA_VALUE_FLAGS:
case CSA_VALUE_UINT32:
return (_DtCm_match_uint32_attribute(eattr.value, mattr.value,
op));
case CSA_VALUE_STRING:
case CSA_VALUE_CALENDAR_USER:
case CSA_VALUE_DATE_TIME_RANGE:
return (_DtCm_match_string_attribute(eattr.value, mattr.value,
op));
case CSA_VALUE_DATE_TIME:
return (_DtCm_match_time_attribute(eattr.value, mattr.value,
op));
case CSA_VALUE_TIME_DURATION:
return (_DtCm_match_time_duration_attribute(eattr.value,
mattr.value, op));
case CSA_VALUE_REMINDER:
return (_DtCm_match_reminder_attribute(eattr.value, mattr.value,
op));
default:
return (B_FALSE);
}
}

View File

@@ -0,0 +1,23 @@
/* $XConsortium: cmsmatch.h /main/4 1995/11/09 12:42:42 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.
*/
#ifndef _CMSMATCH_H
#define _CMSMATCH_H
#include <EUSCompat.h>
#include "ansi_c.h"
#include "cm.h"
#include "nametbl.h"
extern boolean_t _DtCmsMatchAttributes P((
cms_entry *entry,
uint num_attrs,
cms_attribute *attrs,
CSA_enum *ops));
#endif

View File

@@ -0,0 +1,39 @@
/* $XConsortium: data.h /main/4 1995/11/09 12:43:12 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.
*/
#ifndef _DATA_H
#define _DATA_H
/*
* Common definition for internal data storage
*/
#include "ansi_c.h"
typedef enum {
rb_ok = 0,
rb_duplicate = 1,
rb_badtable = 2,
rb_notable = 3,
rb_failed = 4,
rb_other = 5
} Rb_Status;
typedef enum {
_DtCmsIsLess,
_DtCmsIsEqual,
_DtCmsIsGreater
} _DtCmsComparisonResult;
typedef caddr_t (*_DtCmsGetKeyProc) (/* caddr_t data */);
typedef _DtCmsComparisonResult (*_DtCmsCompareProc)(/* caddr_t key; caddr_t data */);
typedef boolean_t (*_DtCmsEnumerateProc) (/* caddr_t data */);
#endif

View File

@@ -0,0 +1,405 @@
/* $XConsortium: delete.c /main/4 1995/11/09 12:43:26 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>
#include <values.h>
#ifdef SunOS
#include <sys/systeminfo.h>
#endif
#include "cmscalendar.h"
#include "delete.h"
#include "cm.h"
#include "tree.h"
#include "list.h"
#include "cmsdata.h"
#include "log.h"
#include "access.h"
#include "insert.h"
#include "v5ops.h"
#include "repeat.h"
#include "rerule.h"
#include "reutil.h"
#include "iso8601.h"
#include "attr.h"
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static boolean_t _InSequence(List_node *node, time_t time);
static CSA_return_code _AddException(cms_attribute *attr, time_t time);
static CSA_return_code _AddEndDateToRule(cms_attribute *attr, RepeatEvent *re,
time_t time);
static void _TruncateExceptionDates(cms_entry *newe, time_t ltick);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
extern CSA_return_code
_DtCmsDeleteEntry(
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
cms_entry **entry_r)
{
CSA_return_code stat;
cms_entry *entry;
List_node *lnode = NULL;
Tree_node *tnode;
if ((entry = (cms_entry *)rb_lookup(cal->tree, (caddr_t)key)) == NULL) {
/* find entry in the repeating entry list */
if ((lnode = hc_lookup_node(cal->list, (caddr_t)key)) == NULL)
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
else
entry = (cms_entry *)lnode->data;
}
if (entry == NULL)
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
if (sender && (stat = _DtCmsCheckChangeAccess(sender, access, entry))
!= CSA_SUCCESS)
return (stat);
if (lnode == NULL) {
if ((tnode = rb_delete(cal->tree, (caddr_t)key)) != NULL) {
_DtCmsObsoleteReminder4Entry(cal->remq, entry, NULL,
0, B_FALSE);
free(tnode);
} else
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
} else {
_DtCmsObsoleteReminder4Entry(cal->remq, entry, lnode,
0, B_FALSE);
hc_delete_node(cal->list, lnode);
free(lnode);
}
if (entry_r)
*entry_r = entry;
else
_DtCm_free_cms_entry(entry);
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsDeleteEntryAndLog(
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
cms_entry **entry_r)
{
CSA_return_code stat;
cms_entry *entry;
if ((stat = _DtCmsDeleteEntry(cal, sender, access, key, &entry))
== CSA_SUCCESS) {
if ((stat = _DtCmsV5TransactLog(cal, entry, _DtCmsLogRemove))
!= CSA_SUCCESS) {
(void)_DtCmsInsertEntry(cal, entry);
_DtCm_free_cms_entry(entry);
} else if (entry_r)
*entry_r = entry;
else
_DtCm_free_cms_entry(entry);
}
return (stat);
}
extern CSA_return_code
_DtCmsDeleteInstancesAndLog(
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
int scope,
cms_entry **newe,
cms_entry **olde)
{
CSA_return_code stat;
cms_entry *entry, *nentry;
List_node *lnode;
int fsize, count;
uint tmp_num;
cms_attribute *tmp_attrs, *aptr;
boolean_t delentry = B_FALSE;
if ((lnode = hc_lookup_node(cal->list, (caddr_t)key)) == NULL)
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
entry = (cms_entry *)lnode->data;
if ((stat = _DtCmsCheckChangeAccess(sender, access, entry))
!= CSA_SUCCESS)
return (stat);
if (_DtCmsInExceptionList(entry, key->time) ||
!_InSequence(lnode, key->time))
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
if ((stat = _DtCm_copy_cms_entry(entry, &nentry)) != CSA_SUCCESS)
return (stat);
if (scope == CSA_SCOPE_ONE)
stat = _AddException(
&nentry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I],
key->time);
else {
/* check whether we are deleting from fst instance */
if (key->time == nentry->key.time)
delentry = B_TRUE;
else {
stat = _DtCmsAddEndDateToRule(&nentry->attrs\
[CSA_ENTRY_ATTR_RECURRENCE_RULE_I],
lnode->re, key->time - 1);
lnode->re->re_end_date = key->time - 1;
_TruncateExceptionDates(nentry, key->time);
}
}
if (stat != CSA_SUCCESS) {
_DtCm_free_cms_entry(nentry);
return (stat);
}
if (!delentry) {
if ((stat = _DtCmsSetLastUpdate(nentry)) != SUCCESS) {
_DtCm_free_cms_entry(nentry);
return (stat);
}
/* remove original entry from log */
if ((stat = _DtCmsGetFileSize(cal->calendar, &fsize))
!= CSA_SUCCESS) {
_DtCm_free_cms_entry(nentry);
return (stat);
}
if ((stat = _DtCmsV5TransactLog(cal, entry, _DtCmsLogRemove))
!= CSA_SUCCESS) {
_DtCm_free_cms_entry(nentry);
return (stat);
}
aptr = &nentry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I];
count = CountEvents(nentry->key.time, lnode->re, (aptr->value ?
aptr->value->item.date_time_list_value : NULL));
}
if (count == 0 || delentry) {
/*
* *** obsolete reminders
*/
_DtCmsObsoleteReminder4Entry(cal->remq, entry, lnode,
0, B_FALSE);
hc_delete_node(cal->list, lnode);
free(lnode);
_DtCm_free_cms_entry(nentry);
if (olde)
*olde = entry;
else
_DtCm_free_cms_entry(entry);
if (newe)
*newe = NULL;
} else {
/* add new entry in memory and log in file */
/* update the count */
if (count == 1) {
_DtCmsConvertToOnetime(nentry, lnode->re);
stat = _DtCmsRbToCsaStat(rb_insert(cal->tree,
(caddr_t)nentry, (caddr_t)&(nentry->key)));
} else if (count != RE_INFINITY) {
nentry->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].\
value->item.uint32_value = count;
}
/* the new entry should be copied when it's updated
* with all the info
*/
if (stat == CSA_SUCCESS && newe)
stat = _DtCm_copy_cms_entry(nentry, newe);
if (stat || (stat = _DtCmsV5TransactLog(cal, nentry,
_DtCmsLogAdd)) != CSA_SUCCESS) {
_DtCmsTruncateFile(cal->calendar, fsize);
_DtCm_free_cms_entry(nentry);
if (newe) free(*newe);
} else {
if (count == 1) {
_DtCmsObsoleteReminder4Entry(cal->remq, entry,
lnode, 0, B_FALSE);
hc_delete_node(cal->list, lnode);
free(lnode);
_DtCmsAddReminders4Entry(&cal->remq, nentry, NULL);
} else {
/* need to do the swap since the original entry
* pointer is stored in the reminder info
*/
tmp_num = entry->num_attrs;
tmp_attrs = entry->attrs;
entry->num_attrs = nentry->num_attrs;
entry->attrs = nentry->attrs;
nentry->num_attrs = tmp_num;
nentry->attrs = tmp_attrs;
_DtCmsObsoleteReminder4Entry(cal->remq, entry,
lnode, key->time,
(scope == CSA_SCOPE_ONE ? B_FALSE :
B_TRUE));
if (scope == CSA_SCOPE_FORWARD ||
key->time == lnode->lasttick) {
lnode->lasttick = LastTick(
entry->key.time,
lnode->re);
}
}
if (olde)
*olde = (count == 1) ? entry : nentry;
else
_DtCm_free_cms_entry((count==1)?entry:nentry);
}
}
return (stat);
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static boolean_t
_InSequence(List_node *node, time_t time)
{
time_t tick;
cms_entry *entry = (cms_entry *)node->data;
RepeatEventState *restate;
for (tick = ClosestTick(time, entry->key.time, node->re, &restate);
tick <= node->lasttick;
tick = NextTick(tick, entry->key.time, node->re, restate))
{
if (tick <= 0 || tick > node->lasttick)
break;
if (tick == time)
return (B_TRUE);
}
return (B_FALSE);
}
static CSA_return_code
_AddException(cms_attribute *attr, time_t time)
{
CSA_date_time_entry *dt, *dlist, *prev;
cms_attribute_value *val;
time_t tick;
char buf[20];
if ((dt = (CSA_date_time_entry *)calloc(1, sizeof(CSA_date_time_entry)))
== NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (_csa_tick_to_iso8601(time, buf)) {
free(dt);
return (CSA_E_INVALID_DATE_TIME);
} else if ((dt->date_time = strdup(buf)) == NULL) {
free(dt);
return (CSA_E_INSUFFICIENT_MEMORY);
}
if (attr->value == NULL) {
if ((val = (cms_attribute_value *)calloc(1,
sizeof(cms_attribute_value))) == NULL) {
free(dt->date_time);
free(dt);
return (CSA_E_INSUFFICIENT_MEMORY);
}
attr->value = val;
val->type = CSA_VALUE_DATE_TIME_LIST;
}
if (attr->value->item.date_time_list_value == NULL) {
val->item.date_time_list_value = dt;
} else {
for (dlist = attr->value->item.date_time_list_value, prev=NULL;
dlist != NULL;
prev = dlist, dlist = dlist->next) {
_csa_iso8601_to_tick(dlist->date_time, &tick);
if (time <= tick)
break;
}
dt->next = dlist;
if (prev == NULL)
attr->value->item.date_time_list_value = dt;
else
prev->next = dt;
}
return (CSA_SUCCESS);
}
static void
_TruncateExceptionDates(cms_entry *newe, time_t ltick)
{
time_t tick;
CSA_date_time_list dt, prev, head;
if (newe->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value == NULL ||
newe->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value == NULL)
return;
head = newe->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value;
for (dt = head, prev = NULL; dt != NULL; prev = dt, dt = dt->next) {
_csa_iso8601_to_tick(dt->date_time, &tick);
if (ltick < tick) {
if (prev) {
prev->next = NULL;
_DtCm_free_date_time_list(dt);
} else {
free(newe->attrs\
[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].\
value);
newe->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].\
value = NULL;
}
break;
}
}
}

View File

@@ -0,0 +1,39 @@
/* $XConsortium: delete.h /main/4 1995/11/09 12:43:40 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.
*/
#ifndef _DELETE_H
#define _DELETE_H
#include "ansi_c.h"
#include "cm.h"
#include "cmscalendar.h"
extern CSA_return_code _DtCmsDeleteEntry P((
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
cms_entry **entry_r));
extern CSA_return_code _DtCmsDeleteEntryAndLog P((
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
cms_entry **entry_r));
extern CSA_return_code _DtCmsDeleteInstancesAndLog P((
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
int scope,
cms_entry **newe,
cms_entry **olde));
#endif

View File

@@ -0,0 +1,263 @@
/* $XConsortium: garbage.c /main/6 1996/11/21 19:44:58 drk $ */
/*
* (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 <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define XOS_USE_NO_LOCKING
#define X_INCLUDE_TIME_H
#include <X11/Xos_r.h>
#include "log.h"
#include "rtable4.h"
#include "cm.h"
#include "cmscalendar.h"
#include "tree.h"
#include "garbage.h"
extern char *pgname;
static CSA_return_code dump_error;
static int fd;
/*
* forward declaration of functions used within this file
*/
static boolean_t magic_time(time_t t);
static boolean_t visit1(caddr_t node, caddr_t d);
static boolean_t visit2(caddr_t node, caddr_t d);
static void print_file_error(char *file, char *msg);
extern void
_DtCmsCollectOne(_DtCmsCalendar *cal)
{
Rb_Status status;
CSA_return_code stat;
char *bak, *temp, *clog;
if (cal == NULL)
return;
status = rb_check_tree(APPT_TREE(cal));
clog = _DtCmsGetLogFN(cal->calendar);
temp = _DtCmsGetTmpFN(cal->calendar);
bak = _DtCmsGetBakFN(cal->calendar);
if (status != rb_ok || clog==NULL || temp==NULL || bak==NULL) {
fprintf(stderr, "%s: cannot acquire files to execute garbage collection.\n", pgname);
fprintf(stderr, "possible causes: cannot find home directory.\n");
fprintf(stderr, "\tNIS or your host server might be down.\n");
fprintf(stderr, "damage: none\n\n");
goto cleanup;
}
/* Make sure that the temp file does not exist before garbage collect */
unlink (temp);
if (cal->fversion == _DtCMS_VERSION1)
stat = _DtCmsCreateLogV1(cal->owner, temp);
else
stat = _DtCmsCreateLogV2(cal->owner, temp);
if (stat != CSA_SUCCESS) {
if (stat == (CSA_X_DT_E_BACKING_STORE_PROBLEM))
print_file_error(temp,
"file error during garbage collection");
else {
fprintf(stderr, "%s: file error on %s during garbage collection\n",
pgname, temp);
fprintf(stderr, "Reason: getpwnam() failed. %s%s\n",
"No passwd entry for owner of ",
cal->calendar);
fprintf(stderr, "damage: none\n\n");
}
goto cleanup;
}
if (cal->fversion == _DtCMS_VERSION1)
stat = _DtCmsDumpDataV1(temp, cal);
else
stat = _DtCmsDumpDataV2(temp, cal);
if (stat != CSA_SUCCESS) {
print_file_error(temp,
(stat == (CSA_X_DT_E_BACKING_STORE_PROBLEM) ?
"file error during garbage collection" :
"can't dump data structure to file during garbage collection"));
goto cleanup;
}
/* mv -f .callog .calbak; mv -f temp .callog */
if (rename (clog, bak) < 0) {
perror ("rpc.cmsd: Can't backup callog to .calbak.\nreason:");
goto cleanup;
}
if (rename (temp, clog) < 0) {
perror("rpc.cmsd: Can't move .caltemp to callog.\nreason:");
fprintf(stderr, "%s: you may recover %s from %s.\n", pgname,
clog, bak);
}
cleanup:
if (bak != NULL) {
free(bak);
bak = NULL;
}
if (temp != NULL) {
free(temp);
temp = NULL;
}
if (clog != NULL) {
free(clog);
clog = NULL;
}
}
extern CSA_return_code
_DtCmsDumpDataV1(char *file, _DtCmsCalendar *cal)
{
CSA_return_code stat;
dump_error = CSA_SUCCESS;
/* Keep the temp log file open during garbage collection. */
if ((fd = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0)
{
return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
}
if ((stat = _DtCmsAppendAccessByFD(fd, access_read_4,
GET_R_ACCESS(cal))) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCmsAppendAccessByFD(fd, access_write_4,
GET_W_ACCESS(cal))) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCmsAppendAccessByFD (fd, access_delete_4,
GET_D_ACCESS(cal))) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCmsAppendAccessByFD (fd, access_exec_4,
GET_X_ACCESS(cal))) != CSA_SUCCESS)
return (stat);
_DtCmsEnumerateUp(cal, visit1); /* dump the tree */
if (close(fd) == EOF)
return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
return (dump_error);
}
extern CSA_return_code
_DtCmsDumpDataV2(char *file, _DtCmsCalendar *cal)
{
CSA_return_code stat;
dump_error = CSA_SUCCESS;
/* Keep the temp log file open during garbage collection. */
if ((fd = open(file, O_WRONLY | O_APPEND | O_SYNC)) < 0)
{
return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
}
/* dump calendar attributes */
if (cal->num_attrs > 0) {
if ((stat = _DtCmsAppendCalAttrsByFD(fd, cal->num_attrs,
cal->attrs)) != CSA_SUCCESS)
return (stat);
}
if ((stat = _DtCmsAppendHTableByFD(fd, cal->entry_tbl->size,
cal->entry_tbl->names, cal->types)) != CSA_SUCCESS)
return (stat);
_DtCmsEnumerateUp(cal, visit2); /* dump the tree */
if (close(fd) == EOF)
return (CSA_X_DT_E_BACKING_STORE_PROBLEM);
return (dump_error);
}
static boolean_t
magic_time(time_t t)
{
boolean_t magic = B_FALSE;
struct tm *tm;
_Xltimeparams localtime_buf;
tm = _XLocaltime(&t, localtime_buf);
if (tm->tm_hour == 3 && tm->tm_min == 41)
magic = B_TRUE;
return(magic);
}
static boolean_t
visit1(caddr_t node, caddr_t d)
{
boolean_t stop = B_FALSE;
switch (((Appt_4 *) d)->tag->tag)
{
case otherTag_4:
/*
* otherTags = events read in from files.
* Don't write to log.
*/
return(stop);
case appointment_4:
/*
* a little hack to get us off the
* totally hokey magic-time business.
*/
if (magic_time(((Appt_4 *)d)->appt_id.tick)) {
((Appt_4 *)d)->tag->showtime = 0;
}
break;
}
if ((dump_error = _DtCmsAppendAppt4ByFD(fd, (Appt_4 *)d, _DtCmsLogAdd)) != CSA_SUCCESS)
stop = B_TRUE;
return(stop);
}
static boolean_t
visit2(caddr_t node, caddr_t d)
{
boolean_t stop = B_FALSE;
if ((dump_error = _DtCmsAppendEntryByFD(fd, (cms_entry *)d,
_DtCmsLogAdd)) != CSA_SUCCESS)
stop = B_TRUE;
return(stop);
}
static void
print_file_error(char *file, char *msg)
{
if (file)
fprintf(stderr, "%s: (%s)%s\n", pgname, file, msg);
else
fprintf(stderr, "%s: %s\n", pgname, msg);
fprintf(stderr, "possible causes: %s, %s, %s, %s\n",
"host server is down", "disk is full", "out of memory",
"file protections have changed.");
fprintf(stderr, "damage: none\n\n");
}

View File

@@ -0,0 +1,26 @@
/* $XConsortium: garbage.h /main/4 1995/11/09 12:44:07 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.
*/
#ifndef _GARBAGE_H
#define _GARBAGE_H
#include "ansi_c.h"
/*
** Housekeeping mechanism to clean up the calendar log file. It copies the
** log file to a backup file, dumps the red/black tree to a temp file, copies
** the temp file back to the original log file, and deletes the temp and
** backup files. Any errors encountered along the way abort the process.
** The garbage collector runs at midnight every.
*/
extern void _DtCmsCollectOne P((_DtCmsCalendar *cal));
extern CSA_return_code _DtCmsDumpDataV1 P((char *file, _DtCmsCalendar *cal));
extern CSA_return_code _DtCmsDumpDataV2 P((char *file, _DtCmsCalendar *cal));
#endif

View File

@@ -0,0 +1,361 @@
/* $XConsortium: insert.c /main/5 1996/10/03 10:29:24 drk $ */
/*
* (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>
#include <values.h>
#ifdef SunOS
#include <sys/systeminfo.h>
#endif
#include "insert.h"
#include "cm.h"
#include "cmscalendar.h"
#include "cmsdata.h"
#include "attr.h"
#include "delete.h"
#include "log.h"
#include "tree.h"
#include "list.h"
#include "iso8601.h"
#include "rerule.h"
#include "reutil.h"
#include "lutil.h"
#include "v5ops.h"
#include "repeat.h"
extern char *_DtCm_rule_buf; /* buffer to hold a rule for parser */
extern RepeatEvent *_DtCm_repeat_info; /* parsed recurrence info */
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static boolean_t _IsOnetimeEntry(cms_entry *entry);
static CSA_return_code _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re);
static int _RuleToRepeatType(RepeatEvent *re);
static int _DailyRuleToRepeatType(RepeatEvent *re);
static int _WeeklyRuleToRepeatType(RepeatEvent *re);
static int _MonthlyRuleToRepeatType(RepeatEvent *re);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
extern CSA_return_code
_DtCmsInsertEntry(_DtCmsCalendar *cal, cms_entry *entry)
{
CSA_return_code stat;
Rb_Status rb_stat;
List_node *lnode = NULL;
cms_entry *newptr;
time_t current_time;
time_t key, tick, endtime;
char *date, buf[80];
CSA_opaque_data opq;
cms_attribute *aptr;
RepeatEvent *re = NULL;
RepeatEventState *res;
extern void _DtCm_rule_parser();
uint count;
int i;
if (cal == NULL || entry == NULL)
return (CSA_E_INVALID_PARAMETER);
/* assign key if this is a new appointment */
key = entry->key.id;
_DtCmsGenerateKey(cal, &(entry->key.id));
if (key == 0) {
/* set start date */
date = entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value;
_csa_iso8601_to_tick(date, &entry->key.time);
/* set reference id */
sprintf(buf, "%ld:%s@%s", entry->key.id, cal->calendar,
_DtCmGetHostAtDomain());
opq.size = strlen(buf);
opq.data = (unsigned char *)buf;
if ((stat = _DtCm_set_opaque_attrval(&opq,
&entry->attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value)) != CSA_SUCCESS) {
return (stat);
}
}
/* check recurrence rule */
if (_IsOnetimeEntry(entry) == B_FALSE) {
/* check recurrence rule */
aptr = &entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I];
_DtCm_rule_buf = aptr->value->item.string_value;
_DtCm_rule_parser();
if ((re = _DtCm_repeat_info) == NULL)
return (CSA_E_INVALID_RULE);
/* get number of recurrences */
aptr = &entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I];
count = CountEvents(entry->key.time, re,
(aptr->value ?
aptr->value->item.date_time_list_value : NULL));
if (count == 1) {
/* turn into onetime entry */
_DtCmsConvertToOnetime(entry, re);
re = NULL;
} else {
if (count == 0)
return (CSA_E_INVALID_RULE);
else if (count == RE_INFINITY)
count = CSA_X_DT_DT_REPEAT_FOREVER;
if ((stat = _DtCm_set_uint32_attrval(count,
&entry->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].\
value)) != CSA_SUCCESS)
return (stat);
/* adjust start date */
tick = ClosestTick(entry->key.time, entry->key.time,
re, &res);
if (tick != entry->key.time &&
!_DtCmsInExceptionList(entry, tick)) {
/* start date */
_csa_tick_to_iso8601(tick, entry->attrs\
[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value);
/* end date */
_csa_iso8601_to_tick(entry->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value, &endtime);
endtime += (tick - entry->key.time);
_csa_tick_to_iso8601(endtime, entry->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value);
/* start tick */
entry->key.time = tick;
}
}
}
if ((stat = _DtCmsCheckStartEndTime(entry)) != CSA_SUCCESS)
return (stat);
if ((stat = _RuleToRepeatInfo(entry, re)) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCm_copy_cms_entry(entry, &newptr)) != CSA_SUCCESS)
return (stat);
/* Add the entry into the data structure */
if (re == NULL) {
rb_stat = rb_insert (cal->tree, (caddr_t)newptr,
(caddr_t)&(newptr->key));
} else {
rb_stat = hc_insert (REPT_LIST(cal), (caddr_t)newptr,
(caddr_t)&(newptr->key), re, &lnode);
}
if (rb_stat == rb_ok) {
/* Add the qualified reminder attrs to the reminder queue */
_DtCmsAddReminders4Entry(&cal->remq, newptr, lnode);
}
return (_DtCmsRbToCsaStat(rb_stat));
}
extern CSA_return_code
_DtCmsInsertEntryAndLog(_DtCmsCalendar *cal, cms_entry *entry)
{
CSA_return_code stat;
if ((stat = _DtCmsInsertEntry(cal, entry)) == CSA_SUCCESS) {
/* append entry to the log file */
if ((stat = _DtCmsV5TransactLog(cal, entry, _DtCmsLogAdd))
!= CSA_SUCCESS) {
(void)_DtCmsDeleteEntry(cal, NULL, 0, &entry->key,
NULL);
}
}
return (stat);
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static boolean_t
_IsOnetimeEntry(cms_entry *entry)
{
cms_attribute *attr;
if (entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value == NULL)
return (B_TRUE);
else
return (B_FALSE);
}
static CSA_return_code
_RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re)
{
CSA_return_code stat;
uint duration;
char buf[BUFSIZ];
int type;
if (re == NULL)
return (_DtCm_set_sint32_attrval(CSA_X_DT_REPEAT_ONETIME,
&entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value));
if ((stat = _DtCm_set_sint32_attrval(_RuleToRepeatType(re),
&entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value))
!= CSA_SUCCESS)
return (stat);
type = entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value->\
item.sint32_value;
if (re->re_duration != RE_NOTSET) {
if (re->re_duration == RE_INFINITY) {
duration = 0;
} else if (type == CSA_X_DT_REPEAT_EVERY_NDAY ||
type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
type == CSA_X_DT_REPEAT_EVERY_NMONTH) {
duration = re->re_duration * re->re_interval;
} else
duration = re->re_duration;
if ((stat = _DtCm_set_uint32_attrval(duration,
&entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value))
!= CSA_SUCCESS)
return (stat);
}
if ((stat = _DtCm_set_uint32_attrval(re->re_interval,
&entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value))
!= CSA_SUCCESS)
return (stat);
if (_csa_tick_to_iso8601(re->re_end_date, buf) == 0) {
if ((stat = _DtCm_set_string_attrval(buf,
&entry->attrs[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].\
value, CSA_VALUE_DATE_TIME)) != CSA_SUCCESS)
return (stat);
}
return (CSA_SUCCESS);
}
static int
_RuleToRepeatType(RepeatEvent *re)
{
switch (re->re_type) {
/* not supported in this release
* case RT_MINUTE:
*/
case RT_DAILY:
return (_DailyRuleToRepeatType(re));
case RT_WEEKLY:
return (_WeeklyRuleToRepeatType(re));
case RT_MONTHLY_POSITION:
return (_MonthlyRuleToRepeatType(re));
case RT_MONTHLY_DAY:
return (_MonthlyRuleToRepeatType(re));
case RT_YEARLY_MONTH:
if ((re->re_data.re_yearly->yd_nitems == 1 ||
re->re_data.re_yearly->yd_nitems == 0) &&
re->re_interval == 1)
return (CSA_X_DT_REPEAT_YEARLY);
else
return (CSA_X_DT_REPEAT_OTHER_YEARLY);
case RT_YEARLY_DAY:
return (CSA_X_DT_REPEAT_YEARLY);
default:
return (CSA_X_DT_REPEAT_OTHER);
}
}
static int
_DailyRuleToRepeatType(RepeatEvent *re)
{
if (re->re_interval == 1)
return (CSA_X_DT_REPEAT_DAILY);
else
return (CSA_X_DT_REPEAT_EVERY_NDAY);
}
#define _DtCms_MON_TO_FRI_MASK 0x3e
#define _DtCms_MON_WED_FRI_MASK 0x2a
#define _DtCms_TUE_THUR_MASK 0x14
static int
_WeeklyRuleToRepeatType(RepeatEvent *re)
{
int i, mask, temp;
if (re->re_data.re_weekly->wd_ndaytime == 1 ||
re->re_data.re_weekly->wd_ndaytime == 0) {
if (re->re_interval == 1)
return (CSA_X_DT_REPEAT_WEEKLY);
else if (re->re_interval == 2)
return (CSA_X_DT_REPEAT_BIWEEKLY);
else
return (CSA_X_DT_REPEAT_EVERY_NWEEK);
} else if (re->re_interval > 1)
return (CSA_X_DT_REPEAT_OTHER_WEEKLY);
/* check for MWF, M-F, TuTh */
for (i = 0, mask = 0; i < re->re_data.re_weekly->wd_ndaytime; i++) {
temp = re->re_data.re_weekly->wd_daytime[i].dt_day;
temp = 0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day;
mask |= (0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day);
}
if (mask == _DtCms_MON_TO_FRI_MASK)
return (CSA_X_DT_REPEAT_MON_TO_FRI);
else if (mask == _DtCms_MON_WED_FRI_MASK)
return (CSA_X_DT_REPEAT_MONWEDFRI);
else if (mask == _DtCms_TUE_THUR_MASK)
return (CSA_X_DT_REPEAT_TUETHUR);
else
return (CSA_X_DT_REPEAT_WEEKDAYCOMBO);
}
static int
_MonthlyRuleToRepeatType(RepeatEvent *re)
{
if (re->re_data.re_monthly->md_nitems == 1 ||
re->re_data.re_monthly->md_nitems == 0) {
if (re->re_interval == 1)
if (re->re_type == RT_MONTHLY_POSITION)
return (CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY);
else
return (CSA_X_DT_REPEAT_MONTHLY_BY_DATE);
else
return (CSA_X_DT_REPEAT_EVERY_NMONTH);
} else
return (CSA_X_DT_REPEAT_OTHER_MONTHLY);
}

View File

@@ -0,0 +1,24 @@
/* $XConsortium: insert.h /main/4 1995/11/09 12:44:48 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.
*/
#ifndef _INSERT_H
#define _INSERT_H
#include "ansi_c.h"
#include "cm.h"
#include "cmscalendar.h"
extern CSA_return_code _DtCmsInsertEntry P((
_DtCmsCalendar *cal,
cms_entry *entry));
extern CSA_return_code _DtCmsInsertEntryAndLog P((
_DtCmsCalendar *cal,
cms_entry *entry));
#endif

View File

@@ -0,0 +1,26 @@
/* $XConsortium: lexer.h /main/4 1995/11/09 12:45:02 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.
*/
#ifndef _LEXER_H
#define _LEXER_H
#include "ansi_c.h"
#include "rtable4.h"
extern int yyylineno;
extern int externNumberVal;
extern char *externQuotedString;
extern Period_4 externPeriod;
extern Tag_4 externTag;
extern Appt_Status_4 externApptStatus;
extern Privacy_Level_4 externPrivacy;
extern void setinput P((FILE*));
extern int yyylex P(());
#endif

View File

@@ -0,0 +1,542 @@
/* $TOG: lexit.c /main/5 1998/04/06 13:13:30 mgreess $ */
/*
* (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.
*/
/*
* handcoded lexer to get rid of slow yylook routines
* produced by lex.
*/
#include <EUSCompat.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include "rtable4.h"
#include "parser.h"
#include "ansi_c.h"
extern char *pgname;
int yyylineno;
int externNumberVal;
char *externQuotedString;
Period_4 externPeriod;
Appt_Status_4 externApptStatus;
Tag_4 externTag;
Privacy_Level_4 externPrivacy;
static int hash_string P((register char *));
static char *strescapes P((char *));
static int len;
static caddr_t start_of_mmapped_area;
static caddr_t current_ptr;
static caddr_t end;
#define input_char() ((end == current_ptr)?0:(*(current_ptr++)))
#define unput_char() (((current_ptr>start_of_mmapped_area)?(current_ptr--):0))
#define ALPHA 1
#define DIGIT 2
#define IGNORE 3
#define SENDIT 4
#define EOFILE 5
#define QUOTE 6
#define COMMENT 7
#define NEWLINE 8
#define DASH 9
/*
the following token entry allows us to combine the
hash table, token id and action on token recog
together.
*/
typedef struct token_data {
const char * name; /* lexical token representation */
short first_token; /* index into tokens. points to
first token that hashes to this spot.
subsequent tokens may be found by following
next_token field IN first_token. */
short next_token;
void * info_to_change; /* ptr to 4 byte value to change when token
is found. Ignored if NULL */
int token_value; /* value to set above to. */
int return_value; /* value to return from yyylex when this token
is found */
} token_data_t;
static u_char parse_buffer[BUFSIZ*3];
static u_char initial_mask[255];
static u_int sendit_value[255];
/*
some macros to save my fingers
*/
#define PVAL(a,b) { #a,-1, -1, &externPeriod.period,b,PERIODVAL}
#define AVAL(a,b) { #a,-1, -1, &externApptStatus,b,APPTSTATUSVAL}
#define TVAL(a,b) { #a,-1, -1, &externTag.tag,b,TAGSVAL }
#define SVAL(a,b) { #a,-1, -1, &externPrivacy,b,PRIVACYVAL}
#define EMP(a,b) {#a,-1, -1, NULL,NULL,b}
token_data_t tokens[] = {
PVAL(single, single_4),
PVAL(daily, daily_4),
PVAL(weekly, weekly_4),
PVAL(biweekly, biweekly_4),
PVAL(monthly, monthly_4),
PVAL(yearly, yearly_4),
PVAL(nthWeekday, nthWeekday_4),
PVAL(everyNthDay, everyNthDay_4),
PVAL(everyNthWeek, everyNthWeek_4),
PVAL(everyNthMonth, everyNthMonth_4),
PVAL(monThruFri, monThruFri_4),
PVAL(monWedFri, monWedFri_4),
PVAL(tueThur, tueThur_4),
PVAL(daysOfWeek, daysOfWeek_4),
AVAL(active, active_4),
AVAL(pendingAdd, pendingAdd_4),
AVAL(pendingDelete, pendingDelete_4),
AVAL(committed, committed_4),
AVAL(cancelled, cancelled_4),
AVAL(completed, completed_4),
TVAL(appointment, appointment_4),
TVAL(reminder, reminder_4),
TVAL(otherTag, otherTag_4),
TVAL(holiday, holiday_4),
TVAL(toDo, toDo_4),
SVAL(public, public_4),
SVAL(private, private_4),
SVAL(semiprivate, semiprivate_4),
EMP(attributes,ATTRIBUTES_4),
EMP(attributelist,ATTRIBUTES_5),
EMP(author,AUTHOR),
EMP(Version, VERSION),
EMP(calendarattributes,CALATTRS),
EMP(duration,DURATION),
EMP(period,PERIOD),
EMP(nth,NTH),
EMP(enddate,ENDDATE),
EMP(ntimes,NTIMES),
EMP(what,WHAT),
EMP(details,DETAILS),
EMP(mailto,MAILTO),
EMP(exceptions,EXCEPTION),
EMP(key,KEY),
EMP(read,READ),
EMP(write,WRITE),
EMP(delete,DELETE),
EMP(exec,EXEC),
EMP(apptstat,APPTSTATUS),
EMP(tags,TAGS),
EMP(privacy,PRIVACY),
EMP(add,ADD),
EMP(remove,REMOVE),
EMP(access,ACCESS),
EMP(entrytable, TABLE),
EMP(hashedattributes, HASHEDATTRS),
EMP(deny,DENY)};
#define NUMTOKES (sizeof(tokens)/sizeof(tokens[0]))
/*
load parser masks & build
token hash tables...
we could make this staticly,
inititialized, but it would
be harder to maintain.
*/
/*
static u_char initial_mask[255];
static u_int sendit_value[255];
*/
static void
init()
{
int i;
for(i=0;i<255;i++)
if(isascii(i)) {
if(isalpha(i))
initial_mask[i] = ALPHA;
else if(isdigit(i))
initial_mask[i] = DIGIT;
else if(isspace(i))
initial_mask[i] = IGNORE;
else {
switch(i) {
case '-':
initial_mask[i] = DASH;
break;
case '*':
initial_mask[i] = COMMENT;
break;
case ' ':
initial_mask[i] = IGNORE;
break;
case '"':
initial_mask[i] = QUOTE;
break;
case '(':
initial_mask[i] = SENDIT;
sendit_value[i] = OPENPAREN;
break;
case ')':
initial_mask[i] = SENDIT;
sendit_value[i] = CLOSEPAREN;
break;
case ',':
initial_mask[i] = SENDIT;
sendit_value[i] = COMMA;
break;
case ':':
initial_mask[i] = SENDIT;
sendit_value[i] = COLON;
break;
}
}
}
else if(isspace(i))
initial_mask[i] = IGNORE;
initial_mask[0] = EOFILE;
initial_mask['\n'] = NEWLINE;
/*
build token hash table
*/
for(i=0;i<NUMTOKES;i++) {
int bucket = hash_string((char *) tokens[i].name);
if(tokens[bucket].first_token == -1)
tokens[bucket].first_token = i;
else {
int j = 0;
bucket = tokens[bucket].first_token;
while(tokens[bucket].next_token != -1)
j++, bucket = tokens[bucket].next_token;
tokens[bucket].next_token = i;
}
}
}
extern int
yyylex()
{
static int first_time=1;
if(first_time) {
init();
first_time = 0;
}
while(1) {
register u_char * ptr = parse_buffer;
register u_char c;
switch(initial_mask[ *ptr = input_char()]) {
case IGNORE:
continue;
case NEWLINE:
yyylineno++;
break;
case SENDIT:
*(ptr+1) = 0;
return(sendit_value[*ptr]);
case DASH:
/* make sure next input is a number */
if( initial_mask[*(++ptr)=input_char()] != DIGIT) {
fprintf(stderr, "%s: Unsupported char %c (ascii %d) found in callog file\n",
pgname, *ptr, *ptr);
return(0);
}
/* fall through */
case DIGIT:
while(initial_mask[*(++ptr)=input_char()] == DIGIT)
;
unput_char();
*ptr = NULL;
externNumberVal=atoi((char *)parse_buffer);
return(NUMBER);
case ALPHA:
{
register int bucket;
register token_data_t * t;
while(initial_mask[*(++ptr)=input_char()] == ALPHA)
;
unput_char();
*ptr = NULL;
if ((bucket = tokens[hash_string((char *) parse_buffer)].first_token)
== -1) {
fprintf(stderr, "%s: cannot lex %s in callog file\n",
pgname, parse_buffer);
return(0);
}
while(strcmp(tokens[bucket].name, (char*)parse_buffer) != 0)
if((bucket = tokens[bucket].next_token) == -1) /* end of chain */ {
fprintf(stderr, "%s: cannot lex %s in callog file\n",
pgname, parse_buffer);
return(0);
}
t = tokens + bucket;
if(t->info_to_change)
*((int *) t->info_to_change) = t->token_value;
return(t->return_value);
}
case QUOTE: /* note that code removes leading and trailing quotes
*/
while(1) {
switch(*ptr = input_char())
{
case '\\':
*++ptr = input_char(); /* load next char in any case */
ptr++;
break;
case '"':
*ptr = 0;
strescapes((char *) parse_buffer); /* process any escape sequences */
externQuotedString = (char *) strdup((char *)parse_buffer);
return(QUOTEDSTRING);
case EOFILE:
case '\n':
case '\r':
fprintf(stderr, "%s: missing matching \" in callog file\n", pgname);
return(0);
default:
ptr++;
}
}
case EOFILE:
return(0);
case COMMENT:
{
int i;
for(i=0;i<3;i++) /* look for 4 **** as comment lead-in */
if(initial_mask[*(++ptr)=input_char()]!= COMMENT) {
*(++ptr) = 0;
fprintf(stderr, "%s: cannot lex %s in callog file\n",
pgname, parse_buffer);
return(0);
}
while(input_char() != '\n') /* eat up rest of comment */
;
yyylineno++; /* since we eat the newline here.... */
continue;
}
default:
fprintf(stderr, "%s: Unsupported char %c (ascii %d) found in callog file\n",
pgname, *ptr, *ptr);
return(0);
}
}
}
extern int
yyywrap(FILE *f)
{
fclose (f);
munmap(start_of_mmapped_area, len);
return (1);
}
extern int
setinput (FILE* f)
{
struct stat buff;
if(fstat(fileno(f), & buff) < 0) {
perror("fstat");
return(-1);
}
if((start_of_mmapped_area =
mmap(NULL,
len = buff.st_size,
PROT_READ,
MAP_PRIVATE,
fileno(f),
0)) == (caddr_t) -1) { /* mmap failed??? */
perror("mmap");
return(-1);
}
#if !defined(USL) && !defined(__uxp__) && !defined(linux)
/* no madvise so we lose this optimization */
madvise(start_of_mmapped_area, len, MADV_SEQUENTIAL);
#endif
end = start_of_mmapped_area + len;
current_ptr = start_of_mmapped_area;
yyylineno = 1;
return(0);
}
static int
hash_string(register char *s)
{
register unsigned result = 0;
register int sum;
while(sum = *s++)
result = (result << 4) + sum;
return(result % NUMTOKES);
}
/*---------------------------------------------------------------------------
Strescapes performs escape character processing in a manner similar to the C
compiler. It processes a character string passed to it and performs the
following substitutions in place:
\\ -> \
\" -> "
\e -> 033
\t -> 011
\n -> newline
\0nn -> 0nn
\r -> cr
A single \ in front of other characters is ignored(&removed). As with
most string routines, strescapes returns it's argument. Note that
inserting a \0 will end the string at that location, but the remainder of
the string will be processed.
---------------------------------------------------------------------------*/
static char *
strescapes(char *s)
{
register char * in=s, * out=s;
while(*in)
{
if(*in == '\\')
switch(*(in+1))
{
case 'e': /* an escape character */
*out++ = '\033';
in += 2;
break;
case 't': /* a tab character */
*out++ = '\t';
in += 2;
break;
case 'n': /* a newline */
*out++ = '\n';
in += 2;
break;
case 'r': /* a carriage return */
*out++ = '\r';
in += 2;
break;
case '\\': /* a backslash */
*out++ = '\\';
in += 2;
break;
case '0': /* a octal constant */
{
register int i,result;
in++;
for(result=i=0; (i<=3) && (*in >='0') && (*in <= '7') ; )
{
result <<= 3;
result += (*in++) - '0';
}
*out++ = result & 0377;
break;
}
default: /* not used as escape.... make it disappear */
in++; /* this also handles nulls */
break;
}
else
*out++ = * in++;
}
*out='\0';
return(s);
}
#ifdef TEST
main(int argc, char ** argv)
{
FILE * f;
int d;
if(argc < 2) {
printf("usage: %s filename\n", argv[0]);
exit(1);
}
if((f = fopen(argv[1], "r")) == NULL) {
perror("fopen");
exit(2);
}
if(setinput(f) < 0) {
exit(3);
}
while(d=yyylex()) {
if(argc == 2)
printf("received %d, text <%s>\n", d, parse_buffer);
}
exit(0);
}
#endif

View File

@@ -0,0 +1,325 @@
/* $XConsortium: list.c /main/4 1995/11/09 12:45:31 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 <sys/param.h>
#include "tree.h"
#include "list.h"
extern int debug;
typedef struct {
_DtCmsGetKeyProc get;
_DtCmsEnumerateProc enumerate;
_DtCmsCompareProc compare;
} Private;
extern List_node *
hc_lookup_node (Hc_list *hc_list, caddr_t key)
{
Private *private;
register List_node *p_node;
register _DtCmsComparisonResult result;
p_node = hc_list->root;
private = (Private *) hc_list->private;
while (p_node != NULL)
{
result = private->compare (key, p_node->data);
if (result == _DtCmsIsGreater)
{
p_node = hc_lookup_next (p_node);
}
else if (result == _DtCmsIsEqual)
{
return (p_node);
}
else
{
break;
}
}
return (NULL);
}
extern caddr_t
hc_lookup (Hc_list *hc_list, caddr_t key)
{
List_node *p_node;
p_node = hc_lookup_node (hc_list, key);
if (p_node != NULL)
return ((caddr_t) p_node->data);
return (NULL);
}
extern int
hc_size (Hc_list *hc_list)
{
int n = 0;
register List_node *p_node;
p_node = hc_list->root;
while (p_node != NULL)
{
n++;
p_node = hc_lookup_next (p_node);
}
return (n);
}
extern Hc_list *
hc_create(_DtCmsGetKeyProc get, _DtCmsCompareProc compare)
{
Private *p;
List_node *root = NULL;
Hc_list *list;
p = (Private *) calloc (1, sizeof (*p));
list = (Hc_list *) calloc (1, sizeof (*list));
list->root = NULL;
list->private = (caddr_t) p;
p->get = get;
p->enumerate = NULL;
p->compare = compare;
return (list);
}
extern void
hc_destroy(Hc_list *hc_list, Destroy_proc destroy_func)
{
Private *p;
List_node *p_node, *p_next;
if (hc_list == NULL)
return;
if ((p = (Private *) hc_list->private) != NULL)
free (p);
p_node = hc_list->root;
while (p_node != NULL)
{
p_next = hc_lookup_next(p_node);
if (p_node->data != NULL)
{
if (destroy_func)
destroy_func(p_node->data);
}
free (p_node);
p_node = p_next;
}
}
extern Rb_Status
hc_insert_node (Hc_list *hc_list, register List_node *p_node, caddr_t key)
{
Private *private;
register List_node *p_curr;
if (hc_list == NULL)
return (rb_notable);
private = (Private *) hc_list->private;
p_curr = hc_list->root;
while (p_curr != NULL)
{
if (private->compare (key, p_curr->data) == _DtCmsIsGreater)
{
if (p_curr->rlink != NULL)
p_curr = p_curr->rlink;
else
{
/* Insert at end of the list */
p_curr->rlink = p_node;
p_node->llink = p_curr;
return (rb_ok);
}
}
else
{
/* Insert at head of the list */
if ((p_node->llink = p_curr->llink) == NULL)
break;
/* Insert before the current node */
p_curr->llink = p_node->llink->rlink = p_node;
p_node->rlink = p_curr;
return (rb_ok);
}
}
/* Insert at head of the list */
p_node->rlink = hc_list->root;
if (p_node->rlink != NULL)
p_node->rlink->llink = p_node;
hc_list->root = p_node;
return (rb_ok);
}
extern Rb_Status
hc_insert(
Hc_list *hc_list,
caddr_t data,
caddr_t key,
RepeatEvent *re,
List_node **node_r)
{
List_node *p_node;
Rb_Status stat;
if (hc_list == NULL)
return (rb_notable);
p_node = (List_node *) calloc (1, sizeof(*p_node));
p_node->data = data;
p_node->re = re;
stat = hc_insert_node (hc_list, p_node, key);
if (stat == rb_ok && node_r)
*node_r = p_node;
return (stat);
}
extern List_node *
hc_delete_node (Hc_list *hc_list, List_node *p_node)
{
if (p_node->llink == NULL)
hc_list->root = p_node->rlink;
else
p_node->llink->rlink = p_node->rlink;
if (p_node->rlink != NULL)
p_node->rlink->llink = p_node->llink;
return (p_node);
}
extern List_node *
hc_delete (Hc_list *hc_list, caddr_t key)
{
register List_node *p_node;
register Private *private;
p_node = hc_list->root;
private = (Private *) hc_list->private;
while (p_node != NULL)
{
if (private->compare (key, p_node->data) == _DtCmsIsEqual)
{
(void) hc_delete_node (hc_list, p_node);
return (p_node);
}
p_node = hc_lookup_next(p_node);
}
return (NULL);
}
extern caddr_t
hc_lookup_smallest (Hc_list *hc_list)
{
if ((hc_list == NULL) || (hc_list->root == NULL))
return (NULL);
return ((caddr_t) hc_list->root->data);
}
extern caddr_t
hc_lookup_next_larger (Hc_list *hc_list, caddr_t key)
{
register List_node *p_node;
register Private *private;
p_node = hc_list->root;
private = (Private *) hc_list->private;
while (p_node != NULL)
{
if (private->compare (key, p_node->data) == _DtCmsIsLess)
return ((caddr_t) p_node->data);
p_node = hc_lookup_next(p_node);
}
return (NULL);
}
extern caddr_t
hc_lookup_largest (Hc_list *hc_list)
{
register List_node *p_node;
if ((hc_list == NULL) || (hc_list->root == NULL))
return (NULL);
p_node = hc_list->root;
while (p_node->rlink != NULL)
p_node = hc_lookup_next (p_node);
return ((caddr_t) p_node->data);
}
extern caddr_t
hc_lookup_next_smaller (Hc_list *hc_list, caddr_t key)
{
register List_node *p_node;
register Private *private;
p_node = hc_list->root;
private = (Private *) hc_list->private;
while (p_node != NULL)
{
if (private->compare (key, p_node->data) != _DtCmsIsGreater)
{
if (p_node->llink == NULL)
return (NULL);
else
return ((caddr_t) p_node->llink->data);
}
p_node = hc_lookup_next(p_node);
}
return (NULL);
}
extern Rb_Status
hc_check_list (Hc_list *hc_list)
{
if ((hc_list == NULL) || (hc_list->root == NULL))
return (rb_notable);
return (rb_ok);
}
extern void
hc_enumerate_down(Hc_list *hc_list, _DtCmsEnumerateProc doit)
{
register List_node *p_node;
p_node = hc_list->root;
while (p_node != NULL)
{
if (doit ((caddr_t)p_node, p_node->data))
return;
p_node = p_node->llink;
}
}
extern Rb_Status
hc_enumerate_up(Hc_list *hc_list, _DtCmsEnumerateProc doit)
{
register List_node *p_node;
p_node = hc_list->root;
while (p_node != NULL)
{
if (doit ((caddr_t)p_node, p_node->data))
return (rb_failed);
p_node = hc_lookup_next (p_node);
}
return (rb_ok);
}

View File

@@ -0,0 +1,54 @@
/* $XConsortium: list.h /main/4 1995/11/09 12:45:45 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.
*/
#ifndef _LIST_H
#define _LIST_H
#include "ansi_c.h"
#include "data.h"
#include "rerule.h"
typedef struct lnode {
struct lnode *llink;
struct lnode *rlink;
caddr_t data;
time_t lasttick;
int duration;
RepeatEvent *re;
} List_node;
typedef struct {
List_node *root;
caddr_t private; /* for internal tool state */
} Hc_list;
typedef int(*Destroy_proc)P((caddr_t));
#define hc_lookup_next(p_node) (p_node)->rlink
#define hc_lookup_previous(p_node) (p_node)->llink
extern Rb_Status hc_check_list P((Hc_list*));
extern Hc_list* hc_create P((_DtCmsGetKeyProc, _DtCmsCompareProc));
extern List_node *hc_delete P((Hc_list*, caddr_t key));
extern List_node *hc_delete_node P((Hc_list*, List_node*));
extern void hc_destroy P((Hc_list*, Destroy_proc));
extern void hc_enumerate_down P((Hc_list*, _DtCmsEnumerateProc));
extern Rb_Status hc_enumerate_up P((Hc_list*, _DtCmsEnumerateProc));
extern Rb_Status hc_insert P((Hc_list*, caddr_t data, caddr_t key,
RepeatEvent *re, List_node **node_r));
extern caddr_t hc_lookup P((Hc_list*, caddr_t key));
extern caddr_t hc_lookup_largest P((Hc_list*));
extern caddr_t hc_lookup_next_larger P((Hc_list*, caddr_t key));
extern caddr_t hc_lookup_next_smaller P((Hc_list*, caddr_t key));
extern caddr_t hc_lookup_smallest P((Hc_list*));
extern int hc_size P((Hc_list*));
extern List_node *hc_lookup_node P((Hc_list*, caddr_t key));
extern Hc_list* hc_create P((_DtCmsGetKeyProc, _DtCmsCompareProc));
extern Rb_Status hc_insert_node P((Hc_list *, List_node *, caddr_t key));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
/* $XConsortium: log.h /main/5 1996/10/03 10:26:46 drk $ */
/*
* (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.
*/
#ifndef _LOG_H
#define _LOG_H
#include "ansi_c.h"
#include "cm.h"
#include "rtable4.h"
#define _DtCMS_VERSION1 1
#define _DtCMS_VERSION4 4
#define _DtCMS_DEFAULT_LOG "callog"
#define _DtCMS_DEFAULT_BAK ".calbak"
#define _DtCMS_DEFAULT_TMP ".caltmp"
#define _DtCMS_DEFAULT_DEL ".caldel"
#define _DtCMS_DEFAULT_DIR "/usr/spool/calendar"
#define _DtCMS_DEFAULT_MODE (S_IRUSR|S_IRGRP|S_IWGRP)
typedef enum {
_DtCmsLogAdd, _DtCmsLogRemove
} _DtCmsLogOps;
extern CSA_return_code _DtCmsAppendAppt4ByFN P((char*, Appt_4*, _DtCmsLogOps));
extern CSA_return_code _DtCmsAppendAppt4ByFD P((int, Appt_4*, _DtCmsLogOps));
extern CSA_return_code _DtCmsAppendCalAttrsByFN P((char *file,
int size,
cms_attribute * attrs));
extern CSA_return_code _DtCmsAppendCalAttrsByFD P((int f,
int size,
cms_attribute * attrs));
extern CSA_return_code _DtCmsAppendEntryByFN P((char *,
cms_entry *,
_DtCmsLogOps));
extern CSA_return_code _DtCmsAppendEntryByFD P((int,
cms_entry *,
_DtCmsLogOps));
extern CSA_return_code _DtCmsAppendHTableByFN P((char *file,
uint size,
char **names,
int *types));
extern CSA_return_code _DtCmsAppendHTableByFD P((int fd,
uint size,
char **names,
int *types));
extern CSA_return_code _DtCmsAppendAccessByFN P((char*,
int,
Access_Entry_4 *));
extern CSA_return_code _DtCmsAppendAccessByFD P((int, int, Access_Entry_4 *));
extern CSA_return_code _DtCmsCreateLogV1 P((char*, char *));
extern CSA_return_code _DtCmsCreateLogV2 P((char *owner, char *file));
extern CSA_return_code _DtCmsWriteVersionString P((char *file, int version));
extern int _DtCmsSetFileMode P((char *file,
uid_t uid,
gid_t gid,
mode_t mode,
boolean_t changeeuid,
boolean_t printerr));
extern CSA_return_code _DtCmsRemoveLog P((char *calendar, char *user));
extern char *_DtCmsGetBakFN P((char*));
extern char *_DtCmsGetLogFN P((char*));
extern char *_DtCmsGetTmpFN P((char*));
extern char *_DtCmsGetDelFN P((char*));
extern boolean_t _DtCmsPrintAppt4 P((caddr_t data));
extern void _DtCmsPrintExceptions P((int len, int *exceptions));
extern CSA_return_code _DtCmsGetFileSize P((char *calendar, int *size));
extern void _DtCmsTruncateFile P((char *calendar, int size));
#endif

View File

@@ -0,0 +1,636 @@
/* $XConsortium: lookup.c /main/4 1995/11/09 12:46:28 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>
#include <values.h>
#ifdef SunOS
#include <sys/systeminfo.h>
#endif
#include "attr.h"
#include "cmscalendar.h"
#include "lookup.h"
#include "cm.h"
#include "tree.h"
#include "list.h"
#include "iso8601.h"
#include "rerule.h"
#include "reutil.h"
#include "access.h"
#include "cmsmatch.h"
#include "cmsdata.h"
#include "cmsentry.h"
#include "repeat.h"
#include "v5ops.h"
#include "misc.h"
#define TIME_BUF_LEN 20
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static CSA_return_code _AddToLinkedEntries(cms_entry *eptr, cms_entry **head,
cms_entry **tail, boolean_t sort, boolean_t time_only);
static CSA_return_code _EnumerateSequence(char *sender, uint access,
List_node *lnode, time_t start1,
time_t start2,
boolean_t no_end_time_range, time_t end1,
time_t end2, CSA_uint32 num_attrs,
cms_attribute *attrs, CSA_enum *ops,
cms_entry **head, cms_entry **tail);
static CSA_return_code _GetEntryAttrsByName(_DtCmsCalendar *cal,
cms_entry *entry, uint num_names,
cms_attr_name *names, uint *num_attrs_r,
cms_attribute **attrs_r);
static CSA_return_code _GetAllEntryAttrs(cms_entry *entry, uint *num_attrs_r,
cms_attribute **attrs_r);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
extern CSA_return_code
_DtCmsLookupEntriesById(
_DtCmsCalendar *cal,
char *sender,
uint access,
boolean_t no_start_time_range,
boolean_t no_end_time_range,
time_t start1,
time_t start2,
time_t end1,
time_t end2,
long id,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **entries)
{
CSA_return_code stat = CSA_SUCCESS;
CSA_return_code stat2 = CSA_SUCCESS;
cms_entry *eptr, *head = NULL, *tail = NULL;
cms_key key;
time_t endtick;
cms_attribute *aptr;
if (no_start_time_range) {
start1 = _DtCM_BOT;
start2 = _DtCM_EOT;
}
/* do lookup on repeating entries first */
stat = _DtCmsEnumerateSequenceById(cal, sender, access,
no_start_time_range, no_end_time_range, start1, start2,
end1, end2, id, num_attrs, attrs, ops, &head);
if (stat != CSA_X_DT_E_ENTRY_NOT_FOUND) {
if (stat == CSA_SUCCESS)
*entries = head;
return (stat);
}
key.time = start1;
key.id = id;
*entries = NULL;
while ((eptr = (cms_entry *)rb_lookup_next_larger(cal->tree,
(caddr_t)&key)) && eptr->key.time < start2) {
if (eptr->key.id != id) {
key.time = eptr->key.time;
key.id = eptr->key.id;
} else {
aptr = &eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I];
if (!no_end_time_range) {
if (aptr->value == NULL)
return (CSA_SUCCESS);
_csa_iso8601_to_tick(
aptr->value->item.date_time_value,
&endtick);
if (endtick <= end1 || endtick >= end2)
return (CSA_SUCCESS);
}
if (_DtCmsMatchAttributes(eptr, num_attrs, attrs, ops)
&& ( ((stat2 = _DtCmsCheckViewAccess(sender, access, eptr)) == CSA_SUCCESS) || (stat2 == CSA_E_TIME_ONLY) ) ) {
stat = _AddToLinkedEntries(eptr, &head, &tail,
B_FALSE, B_FALSE);
}
*entries = head;
return (stat);
}
}
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsLookupEntries(
_DtCmsCalendar *cal,
char *sender,
uint access,
time_t start1,
time_t start2,
boolean_t no_end_time_range,
time_t end1,
time_t end2,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **entries)
{
CSA_return_code stat = CSA_SUCCESS;
CSA_return_code stat2 = CSA_SUCCESS;
cms_entry *eptr, *head = NULL, *tail = NULL;
cms_key key;
List_node *lnode;
time_t endtick;
cms_attribute *aptr;
/* do lookup on one-time entries first */
key.time = start1;
key.id = 0;
while ((eptr = (cms_entry *)rb_lookup_next_larger(cal->tree,
(caddr_t)&key)) && eptr->key.time < start2) {
aptr = &eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I];
if (!no_end_time_range) {
if (aptr->value == NULL)
goto nextone;
_csa_iso8601_to_tick(aptr->value->item.date_time_value,
&endtick);
if (endtick <= end1 || endtick >= end2)
goto nextone;
}
if (_DtCmsMatchAttributes(eptr, num_attrs, attrs, ops) &&
_DtCmsCheckViewAccess(sender, access, eptr) == CSA_SUCCESS)
{
/* the last argument "sort" is set to B_FALSE,
* because the entries are in order already
* as we get them out from the tree;
* we don't want to sort it again
*/
if ((stat = _AddToLinkedEntries(eptr, &head, &tail,
B_FALSE, B_FALSE)) != CSA_SUCCESS)
break;
}
nextone:
key.time = eptr->key.time;
key.id = eptr->key.id;
}
/* do lookup on repeating entries */
lnode = cal->list->root;
while (lnode != NULL && stat == CSA_SUCCESS) {
stat = _EnumerateSequence(sender, access, lnode, start1, start2,
no_end_time_range, end1, end2, num_attrs, attrs,
ops, &head, &tail);
lnode = hc_lookup_next(lnode);
}
if (stat == CSA_SUCCESS)
*entries = head;
else if (head)
_DtCm_free_cms_entries(head);
return (stat);
}
extern CSA_return_code
_DtCmsEnumerateSequenceById(
_DtCmsCalendar *cal,
char *sender,
uint access,
boolean_t no_start_time_range,
boolean_t no_end_time_range,
time_t start1,
time_t start2,
time_t end1,
time_t end2,
long id,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **entries)
{
CSA_return_code stat;
cms_entry *head = NULL, *tail = NULL;
cms_key key;
List_node *lnode;
key.id = id;
lnode = hc_lookup_node(cal->list, (caddr_t)&key);
if (lnode == NULL)
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
if ( ((stat = _DtCmsCheckViewAccess(sender, access,
(cms_entry *)lnode->data)) != CSA_SUCCESS) && (stat != CSA_E_TIME_ONLY) )
return (stat);
*entries = NULL;
if (no_start_time_range && no_end_time_range) {
if (_DtCmsMatchAttributes((cms_entry *)lnode->data, num_attrs,
attrs, ops)) {
stat = _DtCmsGetCmsEntryForClient(
(cms_entry *)lnode->data, entries,B_FALSE);
}
} else {
stat = _EnumerateSequence(sender, access, lnode, start1, start2,
no_end_time_range, end1, end2, num_attrs, attrs, ops,
&head, &tail);
if (stat == CSA_SUCCESS)
*entries = head;
else if (head)
_DtCm_free_cms_entries(head);
}
return (stat);
}
extern CSA_return_code
_DtCmsLookupEntriesByKey(
_DtCmsCalendar *cal,
char *user,
uint access,
uint num_keys,
cms_key *keys,
uint num_names,
cms_attr_name *names,
cms_get_entry_attr_res_item **res)
{
CSA_return_code stat = CSA_SUCCESS;
cms_get_entry_attr_res_item *eptr, *head;
int i;
for (i = 0, head = NULL; i < num_keys; i++) {
if ((stat = _DtCmsGetEntryAttrByKey(cal, user, access, keys[i],
num_names, names, NULL, &eptr)) == CSA_SUCCESS) {
eptr->next = head;
head = eptr;
} else {
if (head) _DtCmsFreeEntryAttrResItem(head);
return (stat);
}
}
*res = head;
return (CSA_SUCCESS);
}
/*
* this routine returns either a cms_entry or
* an cms_get_entry_attr_res_item structure
* depending which output argument is not null
*/
extern CSA_return_code
_DtCmsGetEntryAttrByKey(
_DtCmsCalendar *cal,
char *user,
uint access,
cms_key key,
uint num_names,
cms_attr_name *names,
cms_entry **entry_r,
cms_get_entry_attr_res_item **res_r)
{
CSA_return_code stat;
CSA_return_code stat2;
cms_entry *entry = NULL;
char *stime, *etime;
char sbuf[TIME_BUF_LEN], ebuf[TIME_BUF_LEN];
time_t firsttick = 0;
List_node *lnode;
cms_get_entry_attr_res_item *res;
if (entry_r == NULL && res_r == NULL)
return (CSA_E_INVALID_PARAMETER);
if (res_r && (res = (cms_get_entry_attr_res_item *)calloc(1,
sizeof(cms_get_entry_attr_res_item))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
/* do lookup on one-time entries first */
if ((entry = (cms_entry *)rb_lookup(cal->tree, (caddr_t)&key)) == NULL)
{
if ((lnode = (List_node *)hc_lookup_node(cal->list,
(caddr_t)&key)) != NULL)
{
entry = (cms_entry *)lnode->data;
if (_DtCmsInExceptionList(entry, key.time))
entry = NULL;
}
}
if ( (entry == NULL) || ( ((stat2 = _DtCmsCheckViewAccess(user, access, entry)) != CSA_SUCCESS) && (stat2 != CSA_E_TIME_ONLY)) ) {
if (entry == NULL)
stat = CSA_X_DT_E_ENTRY_NOT_FOUND;
else
stat = CSA_E_NO_AUTHORITY;
if (entry_r)
return (stat);
else {
res->stat = stat;
*res_r = res;
return (CSA_SUCCESS);
}
}
if (entry->key.time != key.time) {
/* set start and end time of the instance */
firsttick = entry->key.time;
entry->key.time = key.time;
stime = entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value;
_csa_tick_to_iso8601(key.time, sbuf);
entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value = sbuf;
if (entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
etime = entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].\
value->item.date_time_value;
_csa_tick_to_iso8601(key.time + lnode->duration, ebuf);
entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value = ebuf;
}
}
if (entry_r)
stat = _DtCmsGetCmsEntryForClient(entry, entry_r,B_FALSE);
else {
if (num_names == 0)
stat = _GetAllEntryAttrs(entry, &res->num_attrs,
&res->attrs);
else
stat = _GetEntryAttrsByName(cal, entry, num_names,
names, &res->num_attrs, &res->attrs);
if (stat == CSA_SUCCESS) {
res->key = key;
*res_r = res;
} else
free(res);
}
if (firsttick > 0) {
entry->key.time = firsttick;
entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value = stime;
if (entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value)
entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value = etime;
}
return (stat);
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static CSA_return_code
_AddToLinkedEntries(
cms_entry *eptr,
cms_entry **head,
cms_entry **tail,
boolean_t sort,
boolean_t time_only)
{
CSA_return_code stat;
cms_entry *newptr, *prev, *ptr;
if ((stat = _DtCmsGetCmsEntryForClient(eptr, &newptr,time_only)) != CSA_SUCCESS)
return (stat);
if (sort == B_FALSE) {
/* just add to the end of the list */
if ((*head) == NULL)
*head = newptr;
else
(*tail)->next = newptr;
*tail = newptr;
} else {
/* add item in ascending order */
for (prev = NULL, ptr = *head; ptr != NULL;
prev = ptr, ptr = ptr->next) {
if (eptr->key.time <= ptr->key.time)
break;
}
newptr->next = ptr;
if (prev == NULL)
*head = newptr;
else
prev->next = newptr;
if ((*tail) == prev)
*tail = newptr;
}
return (CSA_SUCCESS);
}
static CSA_return_code
_EnumerateSequence(
char *sender,
uint access,
List_node *lnode,
time_t start1,
time_t start2,
boolean_t no_end_time_range,
time_t end1,
time_t end2,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **head,
cms_entry **tail)
{
CSA_return_code stat = CSA_SUCCESS;
CSA_return_code stat2 = CSA_SUCCESS;
cms_entry *eptr;
time_t fsttick, tick;
RepeatEventState *restate;
eptr = (cms_entry *)lnode->data;
fsttick = eptr->key.time;
if (lnode->lasttick == 0) {
lnode->lasttick = LastTick(fsttick, lnode->re);
lnode->duration = _DtCmsGetDuration(eptr);
}
if (lnode->lasttick <= start1 || fsttick >= start2 ||
(!no_end_time_range &&
eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].value == NULL) ||
(!no_end_time_range && (lnode->lasttick+lnode->duration) <= end1) ||
(!no_end_time_range && (fsttick + lnode->duration) >= end2) ||
_DtCmsCheckViewAccess(sender, access, eptr) ||
!_DtCmsMatchAttributes(eptr, num_attrs, attrs, ops))
return (CSA_SUCCESS);
if (!no_end_time_range && start1 < (end1 - lnode->duration))
start1 = end1 - lnode->duration;
if (!no_end_time_range && ((end2 - lnode->duration) < start2))
start2 = end2 - lnode->duration;
for (tick = ClosestTick(start1, fsttick, lnode->re, &restate);
stat == CSA_SUCCESS && tick < start2;
tick = NextTick(tick, fsttick, lnode->re, restate))
{
char *stime, *etime;
char sbuf[TIME_BUF_LEN], ebuf[TIME_BUF_LEN];
if (tick <= 0 || tick > lnode->lasttick)
break;
if (tick <= start1 || _DtCmsInExceptionList(eptr, tick))
continue;
/* set start and end time of the instance */
eptr->key.time = tick;
stime = eptr->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value;
_csa_tick_to_iso8601(tick, sbuf);
eptr->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value = sbuf;
if (eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
etime = eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].\
value->item.date_time_value;
_csa_tick_to_iso8601(tick + lnode->duration, ebuf);
eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value = ebuf;
}
stat = _AddToLinkedEntries(eptr, head, tail, B_TRUE,B_FALSE);
eptr->key.time = fsttick;
eptr->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value = stime;
if (eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].value)
eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value = etime;
}
return (stat);
}
static CSA_return_code
_GetEntryAttrsByName(
_DtCmsCalendar *cal,
cms_entry *entry,
uint num_names,
cms_attr_name *names,
uint *num_attrs_r,
cms_attribute **attrs_r)
{
CSA_return_code stat = CSA_SUCCESS;
cms_attribute *attrs;
int i;
if ((attrs = calloc(1, sizeof(cms_attribute)*num_names)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
/* return all attrs names with hash number
* so that caller knows which one does not
* have value and which one does not even exist
*/
for (i = 0; i < num_names && stat == CSA_SUCCESS; i++) {
if (names[i].name == NULL)
continue;
if (names[i].num <= 0)
names[i].num = _DtCm_get_index_from_table(
cal->entry_tbl, names[i].name);
if (names[i].num > 0) {
stat = _DtCm_copy_cms_attribute(&attrs[i],
&entry->attrs[names[i].num], B_TRUE);
} else {
attrs[i].name.num = -1;
if ((attrs[i].name.name = strdup(names[i].name))==NULL)
stat = CSA_E_INSUFFICIENT_MEMORY;
}
}
if (stat == CSA_SUCCESS) {
*num_attrs_r = num_names;
*attrs_r = attrs;
} else {
_DtCm_free_cms_attributes(i, attrs);
free(attrs);
}
return (stat);
}
static CSA_return_code
_GetAllEntryAttrs(
cms_entry *entry,
uint *num_attrs_r,
cms_attribute **attrs_r)
{
CSA_return_code stat = CSA_SUCCESS;
cms_attribute *attrs;
int i, j;
if ((attrs = calloc(1, sizeof(cms_attribute)*entry->num_attrs)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
/* first element is not used */
for (i = 1, j = 0; i <= entry->num_attrs && stat == CSA_SUCCESS; i++) {
if (entry->attrs[i].value) {
if ((stat = _DtCm_copy_cms_attribute(&attrs[j],
&entry->attrs[i], B_TRUE))
== CSA_SUCCESS)
{
j++;
}
}
}
if (stat == CSA_SUCCESS) {
if (j > 0) {
*num_attrs_r = j;
*attrs_r = attrs;
} else {
*num_attrs_r = 0;
*attrs_r = NULL;
free(attrs);
}
} else {
_DtCm_free_cms_attributes(j, attrs);
free(attrs);
}
return (stat);
}

View File

@@ -0,0 +1,93 @@
/* $XConsortium: lookup.h /main/4 1995/11/09 12:46:47 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.
*/
#ifndef _LOOKUP_H
#define _LOOKUP_H
#include "ansi_c.h"
#include "cm.h"
#include "cmscalendar.h"
extern _DtCmsComparisonResult _DtCmsCompareEntry P((
cms_key *key,
caddr_t data));
extern _DtCmsComparisonResult _DtCmsCompareRptEntry P((
cms_key *key,
caddr_t data));
extern caddr_t _DtCmsGetEntryKey P((caddr_t data));
extern CSA_return_code _DtCmsLookupEntries P((
_DtCmsCalendar *cal,
char *sender,
uint access,
time_t start1,
time_t start2,
boolean_t no_end_time_range,
time_t end1,
time_t end2,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **entries));
extern CSA_return_code _DtCmsLookupEntriesById P((
_DtCmsCalendar *cal,
char *sender,
uint access,
boolean_t no_start_time_range,
boolean_t no_end_time_range,
time_t start1,
time_t start2,
time_t end1,
time_t end2,
long id,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **entries));
extern CSA_return_code _DtCmsEnumerateSequenceById P((
_DtCmsCalendar *cal,
char *sender,
uint access,
boolean_t no_start_time_range,
boolean_t no_end_time_range,
time_t start1,
time_t start2,
time_t end1,
time_t end2,
long id,
CSA_uint32 num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
cms_entry **entries));
extern CSA_return_code _DtCmsLookupEntriesByKey P((
_DtCmsCalendar *cal,
char *sender,
uint access,
uint num_keys,
cms_key *keys,
uint num_names,
cms_attr_name *names,
cms_get_entry_attr_res_item **res));
extern CSA_return_code _DtCmsGetEntryAttrByKey P((
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key key,
uint num_names,
cms_attr_name *names,
cms_entry **entry_r,
cms_get_entry_attr_res_item **res_r));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/* $XConsortium: programtable.c /main/4 1995/11/09 12:47:18 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.
*/
/* implements the program table for this program number */
/* this module doesn't know anything about the specifics of any */
/* rtable except how many rtables are supported */
/* - ie it doesn't include rtable*.h. */
/* The actual program table entries are filled in by the rtable*.c's */
#include <EUSCompat.h>
#include <stdio.h>
#include <rpc/rpc.h>
#include "rpcextras.h"
program_table ptable[] = {
(struct rpcgen_table *)NULL, 0, /* rtable 0 no longer supported */
(struct rpcgen_table *)NULL, 0, /* rtable 1 no longer supported */
(struct rpcgen_table *)NULL, 0, /* rtable 2 filled in by rtable2.c */
(struct rpcgen_table *)NULL, 0, /* rtable 3 filled in by rtable3.c */
(struct rpcgen_table *)NULL, 0, /* rtable 4 filled in by rtable4.c */
(struct rpcgen_table *)NULL, 0, /* rtable 5 filled in by cmsfunc.c */
};
/* program_num is filled in from one of the rtable*.c's so that */
/* it can be declared from one of the rtable*.h's */
program_object po = {
&ptable[0], 0, 0,
};
program_handle program = &po;
program_handle newph()
{
extern void initrtable2();
extern void initrtable3();
extern void initrtable4();
extern void initfunctable();
program->nvers = sizeof(ptable)/sizeof(ptable[0]);
initrtable2(program);
initrtable3(program);
initrtable4(program);
initfunctable(program);
return(program);
}
program_handle getph()
{
return(program);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,310 @@
/* $XConsortium: recount.c /main/6 1996/11/21 19:45:46 drk $ */
/*
* (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.
*/
#define XOS_USE_NO_LOCKING
#define X_INCLUDE_TIME_H
#include <X11/Xos_r.h>
#include <EUSCompat.h>
#include "csa.h"
#include "rerule.h"
#include "repeat.h"
#include "reutil.h"
#include "iso8601.h"
static int InitialEventsToExclude(time_t, RepeatEvent *);
static int EventsPerMonth(RepeatEvent *);
static int DoBruteForce(const time_t, RepeatEvent *);
/*
* Give a start time, a parsed rule and a list of exception dates, determine
* the number of events that will be generated.
*/
int
CountEvents(
Tick start_time,
RepeatEvent *re,
CSA_date_time_entry *dte)
{
time_t exclude_time,
close_time;
int excluded_days = 0;
unsigned int nevents1 = (unsigned int)-1,
nevents2 = (unsigned int)-1;
if (!re || !start_time) return RE_ERROR;
if (!re->re_end_date && re->re_duration == RE_INFINITY)
return RE_INFINITY;
/*
* Count the number of times an excluded time hits an event time
* generated by the rule.
*/
for (; dte; dte = dte->next) {
RepeatEventState *res;
if (_csa_iso8601_to_tick(dte->date_time, &exclude_time) == -1)
continue;
if (!(close_time = ClosestTick(exclude_time, start_time, re,
&res))) {
time_t last_time;
last_time = LastTick(start_time, re);
if (last_time == exclude_time)
excluded_days++;
} else {
if (close_time == exclude_time)
excluded_days++;
}
_DtCm_free_re_state(res);
}
/*
* If there is an end date, then we must calculate the total number
* of events via the brute force method.
*/
if (re->re_end_date) {
nevents1 = DoBruteForce(start_time, re) - excluded_days;
}
if (re->re_duration == RE_NOTSET)
return nevents1;
switch (re->re_type) {
case RT_MINUTE:
break;
case RT_DAILY:
nevents2 = re->re_duration;
break;
case RT_WEEKLY:
if (!RE_WEEKLY(re)->wd_ndaytime)
nevents2 = re->re_duration;
else
nevents2 = re->re_duration *
RE_WEEKLY(re)->wd_ndaytime;
nevents2 -= InitialEventsToExclude(start_time, re);
break;
case RT_MONTHLY_POSITION: {
int events_per_month = EventsPerMonth(re);
if (!events_per_month) {
nevents2 = DoBruteForce(start_time, re);
} else {
nevents2 = re->re_duration * events_per_month -
InitialEventsToExclude(start_time, re);
}
break;
}
case RT_MONTHLY_DAY: {
int ndays = RE_MONTHLY(re)->md_nitems;
struct tm *start_tm;
_Xltimeparams localtime_buf;
start_tm = _XLocaltime((const time_t *)&start_time, localtime_buf);
/*
* Need to do this by brute force if they want days that may
* not exist in a given month.
*/
if (((!ndays) && start_tm->tm_mday > 28) ||
(ndays && RE_MONTHLY(re)->md_days[ndays - 1] > 28)) {
nevents2 = DoBruteForce(start_time, re);
} else {
if (!ndays)
nevents2 = re->re_duration;
else
nevents2 = re->re_duration * ndays;
nevents2 -= InitialEventsToExclude(start_time, re);
}
break;
}
case RT_YEARLY_MONTH:
if (!RE_YEARLY(re)->yd_nitems)
nevents2 = re->re_duration;
else
nevents2 = re->re_duration *
RE_YEARLY(re)->yd_nitems;
nevents2 -= InitialEventsToExclude(start_time, re);
break;
case RT_YEARLY_DAY:
if (!RE_YEARLY(re)->yd_nitems)
nevents2 = re->re_duration;
else
nevents2 = re->re_duration *
RE_YEARLY(re)->yd_nitems;
nevents2 -= InitialEventsToExclude(start_time, re);
break;
}
nevents2 -= excluded_days;
/*
* If both a duration and and enddate are set the policy is to use
* the lesser of the two.
*/
if (nevents1 < nevents2)
return nevents1;
return nevents2;
}
/*
* If the rule is a weekly or monthly style with specific weekdays listed,
* such as W1 MO WE FR and the start_time indicates the rule starts on say a
* WE, then the first MO would not count as an event day so it must be
* excluded from the total count.
*/
static int
InitialEventsToExclude(
time_t start_time,
RepeatEvent *re)
{
struct tm *start_tm;
_Xltimeparams localtime_buf;
start_tm = _XLocaltime((const time_t *)&start_time, localtime_buf);
if (re->re_type == RT_WEEKLY) {
DayTime *daytime = (DayTime *)RE_WEEKLY(re)->wd_daytime;
int nevent_days = RE_WEEKLY(re)->wd_ndaytime,
i;
if (!nevent_days) return 0;
for (i = 0; i < nevent_days; i++) {
if (daytime[i].dt_day >= start_tm->tm_wday)
return i;
}
return (nevent_days);
} else if (re->re_type == RT_MONTHLY_POSITION) {
WeekDayTime *wdt = (WeekDayTime *)RE_MONTHLY(re)->md_weektime;
int i,
ndays = 0;
for (i = 0; i < RE_MONTHLY(re)->md_nitems; i++) {
int j, k;
time_t date;
for (j = 0;
j < RE_MONTHLY(re)->md_weektime[i].wdt_nweek;
j++) {
for (k = 0;
k < RE_MONTHLY(re)->md_weektime[i].wdt_nday;
k++) {
date = WeekNumberToDay(start_time,
RE_MONTHLY(re)->md_weektime[i].
wdt_week[j],
RE_MONTHLY(re)->md_weektime[i].
wdt_day[k]);
if (!date || date < start_time)
ndays++;
}
}
}
return (ndays);
} else if (re->re_type == RT_MONTHLY_DAY) {
int i;
if (!RE_MONTHLY(re)->md_nitems) return 0;
for (i = 0; i < RE_MONTHLY(re)->md_nitems; i++) {
if (RE_MONTHLY(re)->md_days[i] >= start_tm->tm_mday)
return i;
}
return (RE_MONTHLY(re)->md_nitems);
} else if (re->re_type == RT_YEARLY_MONTH) {
int i;
if (!RE_YEARLY(re)->yd_nitems) return 0;
for (i = 0; i < RE_YEARLY(re)->yd_nitems; i++) {
if (RE_YEARLY(re)->yd_items[i] >= (start_tm->tm_mon +1))
return i;
}
return (RE_YEARLY(re)->yd_nitems);
} else if (re->re_type == RT_YEARLY_DAY) {
int i;
if (!RE_YEARLY(re)->yd_nitems) return 0;
for (i = 0; i < RE_YEARLY(re)->yd_nitems; i++) {
if (RE_YEARLY(re)->yd_items[i] >=
(start_tm->tm_yday + 1))
return i;
}
return (RE_YEARLY(re)->yd_nitems);
}
return 0;
}
/*
* Given a parsed MP rule determine the number of events it would generate
* in a month. If the rule suggests events should occure on the 5th week
* which means the number of events generated in a given month is not
* constant, we return 0.
*/
static int
EventsPerMonth(
RepeatEvent *re)
{
int nevents = 1,
i;
for (i = 0, nevents = 0; i < RE_MONTHLY(re)->md_nitems; i++) {
int j;
/* If 5+ or 5- is used, we must compute count by brute force */
for (j = 0; j < RE_MONTHLY(re)->md_weektime[i].wdt_nweek; j++) {
if ((RE_MONTHLY(re)->md_weektime[i].wdt_week[j] ==
WK_F5) ||
(RE_MONTHLY(re)->md_weektime[i].wdt_week[j] ==
WK_L5))
return 0;
}
nevents += RE_MONTHLY(re)->md_weektime[i].wdt_nday *
RE_MONTHLY(re)->md_weektime[i].wdt_nweek;
}
return nevents;
}
/*
* Given a start time and a parsed rule determine the number events generated
* by walking the event stream until we reach the end.
*/
static int
DoBruteForce(
const time_t start_time,
RepeatEvent *re)
{
RepeatEventState *res;
time_t cur_time;
int nevents = 0;
if (!(cur_time = ClosestTick(start_time, start_time, re, &res)))
return nevents;
nevents = 1;
while ((cur_time = NextTick(cur_time, start_time, re, res))) {
nevents++;
}
_DtCm_free_re_state(res);
return nevents;
}

View File

@@ -0,0 +1,518 @@
/* $XConsortium: relasttick.c /main/6 1996/11/21 19:46:04 drk $ */
/*
* (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.
*/
#define XOS_USE_NO_LOCKING
#define X_INCLUDE_TIME_H
#include <X11/Xos_r.h>
#include <stdlib.h>
#include "rerule.h"
#include "repeat.h"
#include "reutil.h"
static Tick DoMinute(const Tick, const RepeatEvent *);
static Tick DoDay(const Tick, const RepeatEvent *);
static Tick DoWeek(const Tick, RepeatEvent *);
static Tick DoMonthDay(const Tick, const RepeatEvent *);
static Tick DoMonthPos(const Tick, RepeatEvent *);
static Tick DoYearByMonth(const Tick, RepeatEvent *);
static Tick DoYearByDay(const Tick, RepeatEvent *);
static Tick LastOccurence(const Tick, const WeekDayTime *, const unsigned int);
static Tick LastTickFromEndDate(const Tick, const RepeatEvent *);
static int LastDayExists(const struct tm *, const unsigned int,
const unsigned int *);
extern void FillInRepeatEvent(const Tick, RepeatEvent *);
extern Tick ClosestTick(const Tick, const Tick, RepeatEvent *,
RepeatEventState **);
extern Tick PrevTick(const Tick, const Tick, RepeatEvent *, RepeatEventState *);
Tick
LastTick(
const Tick start_time,
RepeatEvent *re)
{
Tick last_time;
if (!re) return (Tick)NULL;
if (re->re_duration == RE_INFINITY) return EOT;
FillInRepeatEvent(start_time, re);
switch (re->re_type) {
case RT_MINUTE:
last_time = DoMinute(start_time, re);
break;
case RT_DAILY:
last_time = DoDay(start_time, re);
break;
case RT_WEEKLY:
last_time = DoWeek(start_time, re);
break;
case RT_MONTHLY_POSITION:
last_time = DoMonthPos(start_time, re);
break;
case RT_MONTHLY_DAY:
last_time = DoMonthDay(start_time, re);
break;
case RT_YEARLY_MONTH:
last_time = DoYearByMonth(start_time, re);
break;
case RT_YEARLY_DAY:
last_time = DoYearByDay(start_time, re);
break;
}
return last_time;
}
static Tick
DoMinute(
const Tick start_time,
const RepeatEvent *re)
{
return (Tick)NULL;
}
static Tick
DoDay(
const Tick start_time,
const RepeatEvent *re)
{
Tick last_time1 = EOT,
last_time2 = EOT;
if (re->re_end_date) {
last_time1 = LastTickFromEndDate(start_time, re);
}
if (re->re_duration != RE_NOTSET) {
struct tm *start_tm;
_Xltimeparams localtime_buf;
start_tm = _XLocaltime((const time_t *)&start_time, localtime_buf);
/* Go to the last day an event can happen on. */
start_tm->tm_mday += (re->re_duration - 1) * re->re_interval;
start_tm->tm_isdst = -1;
/* Go to the last time an event can happen on the last day. */
if (RE_DAILY(re)->dd_ntime) {
start_tm->tm_hour =
RE_DAILY(re)->dd_time[RE_DAILY(re)->dd_ntime - 1] / 100;
start_tm->tm_min =
RE_DAILY(re)->dd_time[RE_DAILY(re)->dd_ntime - 1] % 100;
}
last_time2 = mktime(start_tm);
}
return ((last_time1 < last_time2) ? last_time1 : last_time2);
}
static Tick
DoWeek(
const Tick start_time,
RepeatEvent *re)
{
struct tm *start_tm;
unsigned int wd_ndaytime = RE_WEEKLY(re)->wd_ndaytime,
dt_ntime,
start_hour,
start_min;
Tick _start_time = start_time,
last_time1 = EOT,
last_time2 = EOT;
RepeatEventState *res;
_Xltimeparams localtime_buf;
if (re->re_end_date) {
last_time1 = LastTickFromEndDate(start_time, re);
if (re->re_duration == RE_NOTSET)
return last_time1;
}
/* Find the real start time */
_start_time = ClosestTick(start_time, start_time, re, &res);
free(res);
start_tm = _XLocaltime((const time_t *)&_start_time, localtime_buf);
start_hour = start_tm->tm_hour;
start_min = start_tm->tm_min;
/* Go to the last day an event can happen on. */
start_tm->tm_mday += (re->re_duration - 1) * re->re_interval * 7;
start_tm->tm_isdst = -1;
if (wd_ndaytime) {
_start_time = mktime(start_tm);
start_tm = _XLocaltime((const time_t *)&_start_time, localtime_buf);
/* Normalize to the beginning of the week */
start_tm->tm_mday -= start_tm->tm_wday;
start_tm->tm_sec = start_tm->tm_min = start_tm->tm_hour = 0;
start_tm->tm_isdst = -1;
_start_time = mktime(start_tm);
start_tm = _XLocaltime((const time_t *)&_start_time, localtime_buf);
/* Move forward to the proper week day */
start_tm->tm_mday +=
RE_WEEKLY(re)->wd_daytime[wd_ndaytime - 1].dt_day;
dt_ntime = RE_WEEKLY(re)->wd_daytime[wd_ndaytime - 1].dt_ntime;
/* Set the proper time */
if (dt_ntime) {
start_tm->tm_hour = RE_WEEKLY(re)->
wd_daytime[wd_ndaytime - 1].dt_time[dt_ntime - 1]
/ 100;
start_tm->tm_min = RE_WEEKLY(re)->
wd_daytime[wd_ndaytime - 1].dt_time[dt_ntime - 1]
% 100;
} else {
start_tm->tm_hour = start_hour;
start_tm->tm_min = start_min;
}
}
start_tm->tm_isdst = -1;
last_time2 = mktime(start_tm);
return ((last_time1 < last_time2) ? last_time1 : last_time2);
}
static Tick
DoMonthDay(
const Tick start_time,
const RepeatEvent *re)
{
struct tm start_tm,
*cur_tm;
unsigned int md_nitems = RE_MONTHLY(re)->md_nitems,
*md_days = RE_MONTHLY(re)->md_days,
interval = 1;
Tick cur_time,
last_time1 = EOT,
last_time2 = EOT;
_Xltimeparams localtime_buf;
if (re->re_end_date) {
last_time1 = LastTickFromEndDate(start_time, re);
if (re->re_duration == RE_NOTSET)
return last_time1;
}
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
cur_tm = _XLocaltime((const time_t *)&start_time, localtime_buf);
start_tm.tm_isdst = -1;
/* The 28th - 31st may not exist in a given month thus if only these
* days are specified in a rule it is necessary to calculate the
* correct month by brute force versus as a mathimatical calculation.
*/
if (md_days[0] > 28) {
cur_tm->tm_mday = 1;
/* Compute last event by brute force */
do {
cur_tm->tm_mon += re->re_interval;
cur_tm->tm_isdst = -1;
cur_time = mktime(cur_tm);
cur_tm = _XLocaltime((const time_t *)&cur_time, localtime_buf);
if (DayExists(
DayOfMonth(md_days[0], cur_tm->tm_mon,
cur_tm->tm_year),
cur_tm->tm_mon, cur_tm->tm_year))
interval++;
} while (interval < re->re_duration);
start_tm.tm_mon = cur_tm->tm_mon;
start_tm.tm_year = cur_tm->tm_year;
start_tm.tm_mday = LastDayExists(cur_tm, md_nitems, md_days);
} else if (md_nitems) {
start_tm.tm_mon += (re->re_duration - 1) * re->re_interval;
start_tm.tm_mday = 1;
/* Have the year and month updated */
cur_time = mktime(&start_tm);
start_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/* Get the right day (LASTDAY converted to a real day) */
start_tm.tm_isdst = -1;
start_tm.tm_mday = DayOfMonth(
md_days[md_nitems - 1],
start_tm.tm_mon, start_tm.tm_year);
} else
start_tm.tm_mon += (re->re_duration - 1) * re->re_interval;
last_time2 = mktime(&start_tm);
return ((last_time1 < last_time2) ? last_time1 : last_time2);
}
static Tick
DoMonthPos(
const Tick _start_time,
RepeatEvent *re)
{
struct tm start_tm,
cur_tm;
Tick last_time1 = EOT,
last_time2 = EOT,
start_time = _start_time;
unsigned int nwdt_list = RE_MONTHLY(re)->md_nitems,
num_intervals = 1,
i, j,
brute_force = TRUE;
WeekDayTime *wdt_list = RE_MONTHLY(re)->md_weektime;
RepeatEventState *res;
_Xltimeparams localtime_buf;
if (re->re_end_date) {
last_time1 = LastTickFromEndDate(start_time, re);
if (re->re_duration == RE_NOTSET)
return last_time1;
}
/* Find the real start time */
start_time = ClosestTick(start_time, start_time, re, &res);
free(res);
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
for (i = 0; i < nwdt_list; i++) {
for (j = 0; j < wdt_list[i].wdt_nweek; j++) {
if ((wdt_list[i].wdt_week[j] != WK_F5) &&
(wdt_list[i].wdt_week[j] != WK_L5)) {
brute_force = FALSE;
break;
}
}
if (brute_force == FALSE) break;
}
if (brute_force) {
cur_tm = start_tm;
cur_tm.tm_mday = 1;
while (num_intervals < re->re_duration) {
cur_tm.tm_mon += re->re_interval;
cur_tm.tm_isdst = -1;
last_time2 = mktime(&cur_tm);
cur_tm = *_XLocaltime((const time_t *)&last_time2,
localtime_buf);
if (OccurenceExists(wdt_list, nwdt_list, last_time2))
num_intervals++;
if (!InTimeRange(num_intervals, re->re_duration))
break;
}
} else {
start_tm.tm_mon += (re->re_duration - 1) * re->re_interval;
start_tm.tm_isdst = -1;
start_tm.tm_mday = 1;
last_time2 = mktime(&start_tm);
}
/*
* Given the occurence information, find the last valid day in the
* month.
*/
last_time2 = LastOccurence(last_time2, wdt_list, nwdt_list);
return ((last_time1 < last_time2) ? last_time1 : last_time2);
}
static Tick
DoYearByMonth(
const Tick start_time,
RepeatEvent *re)
{
struct tm *start_tm;
int start_day;
Tick _start_time,
last_time1 = EOT,
last_time2 = EOT;
RepeatEventState *res;
_Xltimeparams localtime_buf;
if (re->re_end_date) {
last_time1 = LastTickFromEndDate(start_time, re);
if (re->re_duration == RE_NOTSET)
return last_time1;
}
/* Find the real start time */
_start_time = ClosestTick(start_time, start_time, re, &res);
free(res);
start_tm = _XLocaltime((const time_t *)&_start_time, localtime_buf);
start_day = start_tm->tm_mday;
/* Go to the last day an event can happen on. */
start_tm->tm_year += (re->re_duration - 1) * re->re_interval;
start_tm->tm_isdst = -1;
/* XXX: If the only month used is Feb and the date is the 29th, then
* we must use a special case.
*/
/* Go to the last time an event can happen on on the last month. */
if (RE_YEARLY(re)->yd_nitems) {
int i;
_start_time = mktime(start_tm);
start_tm = _XLocaltime((const time_t *)&_start_time, localtime_buf);
for (i = RE_YEARLY(re)->yd_nitems - 1; i >= 0; i++) {
if (DayExists(start_day, RE_YEARLY(re)->yd_items[i],
start_tm->tm_year)) {
start_tm->tm_mon = RE_YEARLY(re)->yd_items[i]-1;
start_tm->tm_isdst = -1;
return (mktime(start_tm));
}
}
/* No months have a day that can be used */
return ((Tick)NULL);
}
last_time2 = mktime(start_tm);
return ((last_time1 < last_time2) ? last_time1 : last_time2);
}
static Tick
DoYearByDay(
const Tick start_time,
RepeatEvent *re)
{
struct tm *start_tm;
int start_day;
Tick _start_time,
last_time1 = EOT,
last_time2 = EOT;
RepeatEventState *res;
_Xltimeparams localtime_buf;
if (re->re_end_date) {
last_time1 = LastTickFromEndDate(start_time, re);
if (re->re_duration == RE_NOTSET)
return last_time1;
}
/* Find the real start time */
_start_time = ClosestTick(start_time, start_time, re, &res);
free(res);
start_tm = _XLocaltime((const time_t *)&_start_time, localtime_buf);
/* Go to the last year an event can happen on. */
start_tm->tm_year += (re->re_duration - 1) * re->re_interval;
start_tm->tm_isdst = -1;
/* Go to the last time an event can happen on. */
if (RE_YEARLY(re)->yd_nitems) {
start_tm->tm_mon = 0;
start_tm->tm_mday =
RE_YEARLY(re)->yd_items[RE_YEARLY(re)->yd_nitems - 1];
}
last_time2 = mktime(start_tm);
return ((last_time1 < last_time2) ? last_time1 : last_time2);
}
/*
* Given a month/year (from cur_tm), and a list of days of the month
* determine the last day in that list that is valid in that month.
*/
static int
LastDayExists(
const struct tm *cur_tm,
const unsigned int md_nitems,
const unsigned int *md_days)
{
int i;
int day;
for (i = md_nitems - 1; i >= 0; i--) {
day = DayOfMonth(md_days[i], cur_tm->tm_mon, cur_tm->tm_year);
if (DayExists(day, cur_tm->tm_mon, cur_tm->tm_year))
return(day);
}
return 0;
}
/*
* Given a month/year (in cur_time) determine the last occurence of week/day/
* time in the month.
*/
static Tick
LastOccurence(
const Tick cur_time,
const WeekDayTime *wdt_list,
const unsigned int nwdt_list)
{
int i, j, k;
Tick oldest_time = 0,
current_time;
for (i = 0; i < nwdt_list; i++) {
for (j = 0; j < wdt_list[i].wdt_nweek; j++) {
for (k = 0; k < wdt_list[i].wdt_nday; k++) {
if (current_time = WeekNumberToDay(cur_time,
wdt_list[i].wdt_week[j],
wdt_list[i].wdt_day[k])) {
if (current_time > oldest_time)
oldest_time = current_time;
}
}
}
}
return oldest_time;
}
/*
* Given a time and a rule find the last tick before the end date.
*/
static Tick
LastTickFromEndDate(
const Tick cur_time,
const RepeatEvent *re)
{
RepeatEventState *res;
RepeatEvent *_re = (RepeatEvent *)re;
Tick end_date = re->re_end_date,
last_time;
Duration duration = re->re_duration;
/* Take the end date out of the equation. */
_re->re_end_date = 0;
_re->re_duration = RE_INFINITY;
/* Use the end date to get the closest tick after it, then
* step back one tick to get the last tick before the
* end date.
*/
last_time = ClosestTick(end_date, cur_time, _re, &res);
/*
* An event that occurs at the same time as the end_date is an
* event.
*/
if (last_time != end_date)
last_time = PrevTick(last_time, cur_time, _re, res);
/* Return the re to its original state. */
_re->re_end_date = end_date;
_re->re_duration = duration;
free (res);
return last_time;
}

View File

@@ -0,0 +1,971 @@
/* $XConsortium: reminder.c /main/4 1995/11/09 12:48:20 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 <string.h>
#include <time.h>
#include "cmscalendar.h"
#include "reminder.h"
#include "appt4.h"
#include "repeat.h"
#include "v4ops.h"
#include "v5ops.h"
#include "rerule.h"
#include "reutil.h"
#include "iso8601.h"
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static _DtCmsRemInfo *_BuildReminder4Entry(
cms_entry *entry,
int aindex,
List_node *lnode,
time_t cutoff,
_DtCmsRemInfo **active);
static void _InsertReminder(
_DtCmsRemInfo **head,
_DtCmsRemInfo *rem);
static CSA_return_code _GetNextReminders(
_DtCmsRemQueue *remq,
time_t tick,
cms_reminder_ref **rems);
static CSA_return_code _GetNextRemindersFromQ(
_DtCmsRemQueue *remq,
int qindex,
time_t tick,
cms_reminder_ref **rems);
static cms_reminder_ref *_GetReminderRefFromInfo(
_DtCmsRemInfo *rem,
time_t starttime,
time_t runtime);
static void _RemoveReminderFromQ(
_DtCmsRemQueue *remq,
int qindex,
cms_entry *entry,
List_node *lnode,
time_t starttime,
boolean_t delfwd);
static _DtCmsRemInfo *_RemoveReminderFromList(
_DtCmsRemInfo **remq,
cms_entry *entry,
time_t starttime,
boolean_t delfwd);
static long _GetNextActiveTick(
cms_entry *entry,
time_t target,
time_t lasttick,
RepeatEvent *re);
static void _UpdateReminderQ(_DtCmsRemQueue *remq, int qindex);
static CSA_return_code _GetNextRemindersFromList(
_DtCmsRemInfo *rlist,
time_t giventime,
cms_reminder_ref **rf_r);
static void _DtCmsAddReminder4EntryToQ(
_DtCmsRemQueue *remq,
cms_entry *entry,
int aindex,
List_node *lnode);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
extern void
_DtCmsAddReminderV4(Rm_que **qhead, Rm_que *p_reminder)
{
Rm_que *p_prev;
Rm_que *p_node;
if (p_reminder == NULL)
return;
p_prev = NULL;
p_node = *qhead;
while (p_node != NULL)
{
if (p_reminder->remind_at < p_node->remind_at)
break;
p_prev = p_node;
p_node = p_node->next;
}
if (p_prev == NULL) {
p_reminder->next = *qhead;
*qhead = p_reminder;
} else {
p_reminder->next = p_prev->next;
p_prev->next = p_reminder;
}
}
extern Rm_que *
_DtCmsRemoveReminderV4(Rm_que **qhead, Rm_que *p_prev, Rm_que *p_curr)
{
if (p_prev == NULL)
*qhead = p_curr->next;
else
p_prev->next = p_curr->next;
return (p_curr->next);
}
extern Rm_que *
build_reminder(
time_t current_time,
Appt_4 *p_appt,
Attr_4 p_attr,
time_t start_tick,
u_int start_ord)
{
int ntimes;
Period_4 period;
Rm_que *p_reminder = NULL;
/* Ignore the expired or unqualified reminder. */
p_reminder = NULL;
if (is_appointment(p_appt)) {
/* The event is not expired yet, build the reminder */
if (start_tick >= current_time)
{
if ((p_reminder = (Rm_que *)calloc(1, sizeof(Rm_que)))
== NULL)
return (NULL);
p_reminder->remind_ord = 0;
}
} else {
period = p_appt->period;
ntimes = _DtCms_get_ninstance_v4(p_appt);
while (start_ord <= ntimes) {
/* Event is not expired */
if (start_tick >= current_time) {
/* Event is not cancelled */
if (!_DtCms_marked_4_cancellation (p_appt, start_ord))
{
if ((p_reminder = (Rm_que *)calloc(1,
sizeof(Rm_que))) == NULL)
return (NULL);
p_reminder->remind_ord = start_ord;
break;
}
}
/* Event is expired, advance to next event */
start_tick = _DtCms_next_tick_v4 (start_tick, period);
start_ord++;
}
}
if (p_reminder != NULL) {
p_reminder->remind_at = start_tick;
p_reminder->appt = p_appt;
p_reminder->attr = p_attr;
}
return (p_reminder);
}
extern Reminder_4 *
_DtCmsGetReminderInfoV4(Rm_que *original)
{
Reminder_4 *copy;
if (original == NULL)
return (NULL);
if ((copy = calloc(1, sizeof(Reminder_4))) != NULL) {
copy->tick = original->remind_at;
copy->next = NULL;
if ((copy->attr.attr = strdup(original->attr->attr)) == NULL) {
free(copy);
return (NULL);
}
if ((copy->attr.value = strdup(original->attr->value)) == NULL)
{
_DtCm_free_reminder4(copy);
return (NULL);
}
if ((copy->attr.clientdata = strdup(original->attr->clientdata))
== NULL) {
_DtCm_free_reminder4(copy);
return (NULL);
}
copy->attr.next = NULL;
copy->appt_id.tick = copy->tick + atol (copy->attr.value);
copy->appt_id.key = original->appt->appt_id.key;
}
return (copy);
}
extern void
_DtCmsPrintReminderListV4(Rm_que *qhead)
{
Rm_que *p_node = qhead;
char *temp=NULL;
if (qhead == NULL)
return;
fprintf (stderr, "--- Active Reminder Queue ---\n");
while (p_node != NULL) {
if (temp = strchr(p_node->appt->what, '\n'))
*temp = '\0';
fprintf(stderr, "%s (%d) %s: %s\n", ctime(&p_node->remind_at),
p_node->remind_ord, p_node->attr->attr,
p_node->appt->what);
if (temp)
*temp = '\n';
p_node = p_node->next;
}
}
/*
* Obsolete all reminders (iff ord == 0) whose parent appointment matches a
* given appointment. If ord != 0, then obsolete all active reminders whose
* serving ordinal matches ord in additional to the matching of its parent
* appointment. The reminder of the next available instance will be put on the
* reminder queue.
*/
extern void
_DtCmsObsoleteReminderV4(
Rm_que **qhead,
Appt_4 *p_appt,
int ord,
boolean_t delforward)
{
Rm_que *p_prev;
Rm_que *p_next;
Rm_que *p_node;
Rm_que *p_hdr = NULL;
p_prev = NULL;
p_node = *qhead;
while (p_node != NULL) {
if ((p_node->appt != p_appt) ||
((ord != 0) && (ord != p_node->remind_ord)) ||
((ord != 0) && delforward && p_node->remind_ord < ord)) {
p_next = p_node->next;
} else {
/* Found the obsolete reminder. */
p_next = _DtCmsRemoveReminderV4 (qhead,p_prev,p_node);
if (ord == 0)
free (p_node);
else {
/* Chain the obsolete reminders together to
* re-calculate the new reminders.
*/
p_node->next = p_hdr;
p_hdr = p_node;
}
p_node = p_prev;
}
p_prev = p_node;
p_node = p_next;
}
/* Build the reminders of the next instance from obsoleted reminders.
* Note, we can't put this code in the above 'while'-loop because it
* may confuse the loop.
*/
while (p_hdr != NULL) {
p_next = p_hdr->next;
p_node = build_reminder(p_hdr->remind_at+1,
p_hdr->appt, p_hdr->attr,
p_hdr->remind_at, ord);
_DtCmsAddReminderV4 (qhead, p_node);
free (p_hdr);
p_hdr = p_next;
}
}
#define _DtCms_NUM_REMINDERS 4
extern void
_DtCmsAddReminders4Entry(
_DtCmsRemQueue **remq,
cms_entry *entry,
List_node *lnode)
{
_DtCmsRemQueue *queue;
int i;
if (*remq == NULL) {
if ((queue = (_DtCmsRemQueue *)calloc(1,
sizeof(_DtCmsRemQueue))) == NULL)
return;
/* initialize queues for the cde defined reminders */
if ((queue->aindex = (int *)malloc(sizeof(int) *
_DtCms_NUM_REMINDERS)) == NULL) {
free(queue);
return;
}
if ((queue->names = (char **)malloc(sizeof(char *) *
_DtCms_NUM_REMINDERS)) == NULL) {
free(queue->aindex);
free(queue);
return;
}
if ((queue->active = (_DtCmsRemInfo **)calloc(1,
sizeof(_DtCmsRemInfo) * _DtCms_NUM_REMINDERS)) == NULL) {
free(queue->names);
free(queue->aindex);
free(queue);
return;
}
if ((queue->oldhead = (_DtCmsRemInfo **)calloc(1,
sizeof(_DtCmsRemInfo) * _DtCms_NUM_REMINDERS)) == NULL) {
free(queue->active);
free(queue->names);
free(queue->aindex);
free(queue);
return;
}
queue->num_queues = _DtCms_NUM_REMINDERS;
queue->aindex[0] = CSA_ENTRY_ATTR_AUDIO_REMINDER_I;
queue->names[0] = CSA_ENTRY_ATTR_AUDIO_REMINDER;
queue->aindex[1] = CSA_ENTRY_ATTR_FLASHING_REMINDER_I;
queue->names[1] = CSA_ENTRY_ATTR_FLASHING_REMINDER;
queue->aindex[2] = CSA_ENTRY_ATTR_MAIL_REMINDER_I;
queue->names[2] = CSA_ENTRY_ATTR_MAIL_REMINDER;
queue->aindex[3] = CSA_ENTRY_ATTR_POPUP_REMINDER_I;
queue->names[3] = CSA_ENTRY_ATTR_POPUP_REMINDER;
/* set cutoff to be half an hour earlier than now
* to compensate time difference between machines
*/
queue->cutoff = time(0) - 60 * 30;
*remq = queue;
}
/* Add the qualified reminder attrs to the reminder queue */
for (i = 1; i <= entry->num_attrs; i++) {
if (entry->attrs[i].value == NULL ||
entry->attrs[i].value->type != CSA_VALUE_REMINDER)
continue;
_DtCmsAddReminder4EntryToQ(*remq, entry, i, lnode);
}
}
extern void
_DtCmsObsoleteReminder4Entry(
_DtCmsRemQueue *remq,
cms_entry *entry,
List_node *lnode,
time_t starttime,
boolean_t delfwd)
{
int i;
for (i = 0; i < remq->num_queues; i++) {
if (entry->attrs[remq->aindex[i]].value)
_RemoveReminderFromQ(remq, i, entry, lnode,
starttime, delfwd);
}
}
extern CSA_return_code
_DtCmsLookupReminder(
_DtCmsRemQueue *remq,
time_t tick,
uint num_names,
cms_attr_name *names,
cms_reminder_ref **rems)
{
int i, j;
CSA_return_code stat;
*rems = NULL;
if (remq == NULL)
return (CSA_SUCCESS);
if (num_names == 0)
return (_GetNextReminders(remq, tick, rems));
for (i = 0; i < num_names; i++) {
for (j = 0; j < remq->num_queues; j++) {
if (strcmp(names[i].name, remq->names[j]) == 0) {
names[i].num = remq->aindex[j];
if ((stat = _GetNextRemindersFromQ(remq, i,
tick, rems)) != CSA_SUCCESS) {
if (*rems)
_DtCmsFreeReminderRef(*rems);
return (stat);
}
}
}
}
return (CSA_SUCCESS);
}
extern void
_DtCmsFreeReminderRef(cms_reminder_ref *rems)
{
cms_reminder_ref *next;
while (rems != NULL) {
next = rems->next;
if (rems->reminder_name)
free(rems->reminder_name);
if (rems->entryid)
free(rems->entryid);
free(rems);
rems = next;
}
}
extern void
_DtCmsUpdateReminders(_DtCmsRemQueue *remq)
{
int i;
remq->cutoff = time(0) - 60*30;
for (i = 0; i < remq->num_queues; i++)
_UpdateReminderQ(remq, i);
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static _DtCmsRemInfo *
_BuildReminder4Entry(
cms_entry *entry,
int aindex,
List_node *lnode,
time_t cutoff,
_DtCmsRemInfo **active)
{
_DtCmsRemInfo *rptr, *rptr2;
time_t lead;
time_t tick;
RepeatEventState *restate;
if (active) *active = NULL;
if ((rptr = (_DtCmsRemInfo *)calloc(1, sizeof(_DtCmsRemInfo))) == NULL)
return (NULL);
rptr->lnode = lnode;
rptr->isentry = B_TRUE;
rptr->data.e = entry;
rptr->rem.i = entry->attrs[aindex].name.num;
_csa_iso8601_to_duration(entry->attrs[aindex].value->item.\
reminder_value->lead_time, &lead);
if (lnode == NULL) {
rptr->starttime = entry->key.time;
rptr->runtime = entry->key.time - lead;
} else {
if (lnode->lasttick == 0) {
lnode->lasttick = LastTick(entry->key.time, lnode->re);
lnode->duration = _DtCmsGetDuration(entry);
}
rptr->lasttick = lnode->lasttick;
/* calculate first tick */
tick = _GetNextActiveTick(entry, entry->key.time,
lnode->lasttick, lnode->re);
rptr->starttime = tick;
rptr->runtime = tick - lead;
/* need to calculate the active tick if
* 1. runtime of first tick is before cutoff time,
* 2. runtime of last tick is after cutoff time, and
* 3. there's reminders for instances after the cutoff time
*/
if (active && rptr->runtime < cutoff &&
(lnode->lasttick - lead >= cutoff) &&
(tick = _GetNextActiveTick(entry, cutoff + lead,
lnode->lasttick, lnode->re)) > 0)
{
if ((rptr2 = (_DtCmsRemInfo *)calloc(1,
sizeof(_DtCmsRemInfo))) == NULL) {
free(rptr);
return (NULL);
}
rptr2->lnode = lnode;
rptr2->isentry = B_TRUE;
rptr2->data.e = entry;
rptr2->rem.i = entry->attrs[aindex].name.num;
rptr2->lasttick = lnode->lasttick;
rptr2->starttime = tick;
rptr2->runtime = tick - lead;
*active = rptr2;
}
}
return (rptr);
}
static void
_InsertReminder(
_DtCmsRemInfo **head,
_DtCmsRemInfo *rem)
{
_DtCmsRemInfo *rptr, *prev;
for (rptr = *head, prev = NULL; rptr != NULL;
prev = rptr, rptr = rptr->next) {
if (rem->runtime < rptr->runtime)
break;
}
if (rptr == NULL) {
if (*head == NULL) {
*head = rem;
} else
prev->next = rem;
} else {
rem->next = rptr;
if (prev == NULL)
*head = rem;
else
prev->next = rem;
}
}
static CSA_return_code
_GetNextReminders(_DtCmsRemQueue *remq, time_t tick, cms_reminder_ref **rems)
{
CSA_return_code stat;
cms_reminder_ref *rptr, *head, *tail;
int i;
for (i = 0, head = NULL; i < remq->num_queues; i++) {
rptr = NULL;
if ((stat = _GetNextRemindersFromQ(remq, i, tick, &rptr))
!= CSA_SUCCESS) {
if (head)
_DtCmsFreeReminderRef(head);
return (stat);
}
if (rptr == NULL)
continue;
if (head == NULL)
head = tail = rptr;
else if (rptr->runtime == head->runtime) {
/* combine the list */
for (; tail->next != NULL; tail = tail->next);
tail->next = rptr;
tail = rptr;
} else if (rptr->runtime < head->runtime) {
_DtCmsFreeReminderRef(head);
head = tail = rptr;
} else
_DtCmsFreeReminderRef(rptr);
}
if (head) {
*rems = head;
}
return (CSA_SUCCESS);
}
static CSA_return_code
_GetNextRemindersFromQ(
_DtCmsRemQueue *remq,
int qindex,
time_t tick,
cms_reminder_ref **rems)
{
CSA_return_code stat;
cms_reminder_ref *rem = *rems;
if (tick >= remq->cutoff)
return (_GetNextRemindersFromList(remq->active[qindex], tick,
rems));
else {
if ((stat = _GetNextRemindersFromList(remq->oldhead[qindex],
tick, rems)) == CSA_SUCCESS && rem == *rems)
return (_GetNextRemindersFromList(remq->active[qindex],
tick, rems));
else
return (stat);
}
}
static cms_reminder_ref *
_GetReminderRefFromInfo(_DtCmsRemInfo *rem, time_t starttime, time_t runtime)
{
cms_reminder_ref *rptr;
cms_entry *entry = rem->data.e;
int size;
if ((rptr = (cms_reminder_ref *)calloc(1, sizeof(cms_reminder_ref)))
== NULL)
return (NULL);
if ((rptr->reminder_name = strdup(entry->attrs[rem->rem.i].name.name))
== NULL) {
free(rptr);
return (NULL);
}
size = entry->attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value->item.\
opaque_data_value->size;
if ((rptr->entryid = malloc(size)) == NULL) {
free(rptr->reminder_name);
free(rptr);
return (NULL);
} else
strncpy(rptr->entryid, (char *)entry->attrs\
[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value->item.\
opaque_data_value->data, size);
rptr->key.id = entry->key.id;
rptr->key.time = starttime ? starttime : rem->starttime;
rptr->runtime = runtime ? runtime : rem->runtime;
return (rptr);
}
static void
_RemoveReminderFromQ(
_DtCmsRemQueue *remq,
int qindex,
cms_entry *entry,
List_node *lnode, /* zero for one time entries */
time_t starttime,
boolean_t delfwd)
{
_DtCmsRemInfo *rptr, *rptr1 = NULL, *rptr2 = NULL;
time_t lead;
time_t tick;
boolean_t do_old, do_new;
RepeatEventState *restate;
_csa_iso8601_to_duration(entry->attrs[remq->aindex[qindex]].value->\
item.reminder_value->lead_time, &lead);
if (lnode == 0) {
if (entry->key.time - lead < remq->cutoff)
_RemoveReminderFromList(&remq->oldhead[qindex], entry,
starttime, delfwd);
else
_RemoveReminderFromList(&remq->active[qindex], entry,
starttime, delfwd);
} else {
tick = ClosestTick(entry->key.time, entry->key.time, lnode->re,
&restate);
if (do_old = (tick - lead < remq->cutoff))
rptr1 = _RemoveReminderFromList(&remq->oldhead[qindex],
entry, starttime, delfwd);
if (do_new = (lnode->lasttick - lead >= remq->cutoff))
rptr2 = _RemoveReminderFromList(&remq->active[qindex],
entry, starttime, delfwd);
if (rptr = rptr1 ? rptr1 : rptr2) {
if (do_old && do_new) {
/* need to clean up the other queue
* since add reminder will add to both
* queue
*/
if (rptr1 == NULL)
_RemoveReminderFromList(
&remq->oldhead[qindex], entry,
0, B_FALSE);
else
_RemoveReminderFromList(
&remq->active[qindex], entry,
0, B_FALSE);
}
_DtCmsAddReminder4EntryToQ(remq, entry,
remq->aindex[qindex], rptr->lnode);
if (rptr1) free(rptr1);
if (rptr2) free(rptr2);
}
}
}
static _DtCmsRemInfo *
_RemoveReminderFromList(
_DtCmsRemInfo **qhead,
cms_entry *entry,
time_t starttime,
boolean_t delfwd)
{
_DtCmsRemInfo *rptr, *prev;
/* find reminder in list */
for (rptr = *qhead, prev = NULL; rptr != NULL;
prev = rptr, rptr = rptr->next) {
if (rptr->data.e != entry ||
(starttime > 0 && !delfwd && rptr->starttime != starttime)||
(starttime > 0 && delfwd && rptr->starttime < starttime))
{
continue;
}
if (prev == NULL)
*qhead = rptr->next;
else
prev->next = rptr->next;
if (starttime == 0 || delfwd) {
free(rptr);
return (NULL);
} else
return (rptr);
}
return (NULL);
}
/*
* move all reminders in active queue whose runtime < cutoff
* to old queue
*/
static void
_UpdateReminderQ(_DtCmsRemQueue *remq, int qindex)
{
_DtCmsRemInfo *rptr, *nptr;
cms_entry *entry;
time_t lead, tick;
RepeatEventState *restate;
for (; (rptr = remq->active[qindex]) != NULL &&
rptr->runtime < remq->cutoff; ) {
remq->active[qindex] = rptr->next;
rptr->next = NULL;
if (rptr->lnode == NULL)
_InsertReminder(&remq->oldhead[qindex], rptr);
else {
lead = rptr->starttime - rptr->runtime;
entry = rptr->data.e;
tick = ClosestTick(entry->key.time, entry->key.time,
rptr->lnode->re, &restate);
if (tick == rptr->starttime) {
/* add this to old queue */
_InsertReminder(&remq->oldhead[qindex], rptr);
/* make copy of rptr */
nptr = (_DtCmsRemInfo *)calloc(1,
sizeof(_DtCmsRemInfo));
*nptr = *rptr;
rptr = nptr;
}
if ((rptr->lasttick - lead < remq->cutoff) ||
(tick = _GetNextActiveTick(entry,
remq->cutoff + lead, rptr->lasttick,
rptr->lnode->re)) <= 0)
{
free(rptr);
} else {
rptr->starttime = tick;
rptr->runtime = tick - lead;
_InsertReminder(&remq->active[qindex], rptr);
}
}
}
}
static long
_GetNextActiveTick(
cms_entry *entry,
time_t target,
time_t lasttick,
RepeatEvent *re)
{
RepeatEventState *restate;
time_t tick;
for (tick = ClosestTick(target, entry->key.time, re, &restate);
tick <= lasttick;
tick = NextTick(tick, entry->key.time, re, restate))
{
if (tick <= 0 || !_DtCmsInExceptionList(entry, tick))
break;
}
return (tick);
}
/*
* The reminders found will be linked with the list
* contained in rf_f
*/
static CSA_return_code
_GetNextRemindersFromList(
_DtCmsRemInfo *rlist,
time_t giventime,
cms_reminder_ref **rf_r)
{
cms_reminder_ref *rptr, *head = NULL, *tail;
time_t tick;
int lead;
/* get from active queue */
for (; rlist != NULL; rlist = rlist->next) {
if (giventime < rlist->runtime)
break;
else if (rlist->lnode) {
/* check the next active tick */
lead = rlist->starttime - rlist->runtime;
tick = _GetNextActiveTick(rlist->data.e,
giventime + lead + 1, rlist->lasttick,
rlist->lnode->re);
if (tick > 0 &&
(head == NULL || (tick-lead <= head->runtime)))
{
if ((rptr = _GetReminderRefFromInfo(rlist, tick,
tick-lead)) == NULL) {
if (head)
_DtCmsFreeReminderRef(head);
return (CSA_E_INSUFFICIENT_MEMORY);
}
if (head == NULL)
head = rptr;
else if (head->runtime = rptr->runtime) {
rptr->next = head;
head = rptr;
} else {
_DtCmsFreeReminderRef(head);
head = rptr;
}
}
}
}
if (rlist) {
if (head) {
if (head->runtime > rlist->runtime) {
_DtCmsFreeReminderRef(head);
head = NULL;
} else if (head->runtime < rlist->runtime)
goto _done;
}
/* now do lookup in the remaining list */
while (rlist != NULL) {
if (rptr = _GetReminderRefFromInfo(rlist, 0, 0)) {
rptr->next = head;
head = rptr;
} else {
if (head) _DtCmsFreeReminderRef(head);
return (CSA_E_INSUFFICIENT_MEMORY);
}
if (rlist->next &&
rlist->next->runtime == rlist->runtime)
rlist = rlist->next;
else
break;
}
}
_done:
/* find tail */
if (head) {
for (tail = head; tail->next != NULL; tail = tail->next) ;
tail->next = *rf_r;
*rf_r = head;
}
return (CSA_SUCCESS);
}
static void
_DtCmsAddReminder4EntryToQ(
_DtCmsRemQueue *remq,
cms_entry *entry,
int aindex,
List_node *lnode)
{
_DtCmsRemInfo *rptr, *rptr2;
int i;
if ((rptr = _BuildReminder4Entry(entry, aindex, lnode, remq->cutoff,
&rptr2)) == NULL)
return;
for (i = 0; i < remq->num_queues; i++) {
if (remq->aindex[i] == aindex) {
if (rptr->runtime >= remq->cutoff)
_InsertReminder(&remq->active[i], rptr);
else
_InsertReminder(&remq->oldhead[i], rptr);
if (rptr2)
_InsertReminder(&remq->active[i], rptr2);
break;
}
}
if (i == remq->num_queues) {
/* expand the queue */
}
}

View File

@@ -0,0 +1,99 @@
/* $XConsortium: reminder.h /main/4 1995/11/09 12:48:37 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.
*/
#ifndef _REMINDER_H
#define _REMINDER_H
#include "ansi_c.h"
#include "EUSCompat.h"
#include "cm.h"
#include "rtable4.h"
#include "list.h"
typedef struct _RemInfo {
boolean_t isentry; /* entry vs appt */
time_t runtime; /* run time of reminder */
time_t starttime;
time_t lasttick; /* lasttick of a repeating event */
List_node *lnode;
union {
Appt_4 *a;
cms_entry *e;
} data; /* associated entry */
union {
Attr_4 *a; /* v4 reminder structure */
int i; /* index of attribute name */
} rem; /* associated reminder info */
struct _RemInfo *next; /* next reminder */
} _DtCmsRemInfo;
typedef struct _RemQueue {
time_t cutoff;
uint num_queues;
int *aindex; /* array of attribute index */
char **names; /* array of names */
_DtCmsRemInfo **active; /* array of unexpired reminders */
_DtCmsRemInfo **oldhead; /* head of old reminders list */
} _DtCmsRemQueue;
typedef struct reminder_q {
time_t remind_at;
int remind_ord;
Attr_4 attr;
Appt_4 *appt;
struct reminder_q *next;
} Rm_que;
extern void _DtCmsAddReminderV4 P((Rm_que **qhead, Rm_que *p_reminder));
extern Rm_que *_DtCmsRemoveReminderV4 P((
Rm_que **qhead,
Rm_que *p_prev,
Rm_que *p_curr));
extern Rm_que *build_reminder P((
time_t current_time,
Appt_4 *p_appt,
Attr_4 p_attr,
time_t start_tick,
u_int start_ord));
extern Reminder_4 *_DtCmsGetReminderInfoV4 P((Rm_que *original));
extern void _DtCmsPrintReminderListV4 P((Rm_que *qhead));
extern void _DtCmsObsoleteReminderV4 P((
Rm_que **qhead,
Appt_4 *p_appt,
int ord,
boolean_t delforward));
extern void _DtCmsAddReminders4Entry P((
_DtCmsRemQueue **qhead,
cms_entry *entry,
List_node *lnode));
extern void _DtCmsObsoleteReminder4Entry P((
_DtCmsRemQueue *qhead,
cms_entry *entry,
List_node *lnode,
time_t starttime,
boolean_t delfwd));
extern CSA_return_code _DtCmsLookupReminder P((
_DtCmsRemQueue *remq,
time_t tick,
uint num_names,
cms_attr_name *names,
cms_reminder_ref **rems));
extern void _DtCmsFreeReminderRef P((cms_reminder_ref *rems));
extern void _DtCmsUpdateReminders(_DtCmsRemQueue *remq);
#endif

View File

@@ -0,0 +1,581 @@
/* $XConsortium: renexttick.c /main/5 1996/11/21 19:46:22 drk $ */
/*
* (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.
*/
#define XOS_USE_NO_LOCKING
#define X_INCLUDE_TIME_H
#include <X11/Xos_r.h>
#include "rerule.h"
#include "repeat.h"
#include "reutil.h"
typedef enum {
SameInterval = 0,
NextInterval
} MoveIndicator;
static Tick DoMinute(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoDay(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoWeek(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoMonthDay(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoMonthPos(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoYearByMonth(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoYearByDay(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick NextDayTick(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick NextWeekTick(const struct tm *, const struct tm *,
const RepeatEvent *, const DayTime *,
const MoveIndicator, RepeatEventState *);
static Tick NextMonthTick(const struct tm *, const RepeatEvent *,
const WeekDayTime *, const MoveIndicator,
RepeatEventState *);
extern void FillInRepeatEvent(const Tick, RepeatEvent *);
Tick
NextTick(
const Tick cur_time,
const Tick start_time,
RepeatEvent *re,
RepeatEventState *res)
{
Tick next_time;
if (!re) return (Tick)NULL;
FillInRepeatEvent(start_time, re);
switch (re->re_type) {
case RT_MINUTE:
next_time = DoMinute(cur_time, start_time, re, res);
break;
case RT_DAILY:
next_time = DoDay(cur_time, start_time, re, res);
break;
case RT_WEEKLY:
next_time = DoWeek(cur_time, start_time, re, res);
break;
case RT_MONTHLY_POSITION:
next_time = DoMonthPos(cur_time, start_time, re, res);
break;
case RT_MONTHLY_DAY:
next_time = DoMonthDay(cur_time, start_time, re, res);
break;
case RT_YEARLY_MONTH:
next_time = DoYearByMonth(cur_time, start_time, re, res);
break;
case RT_YEARLY_DAY:
next_time = DoYearByDay(cur_time, start_time, re, res);
break;
}
/*
* If the duration was not set (thus strictly using the end date)
* reset the RepeatEventState duration back to not-set. This is
* cleaner than having conditionals through out the code checking
* to see if the duration needs to be updated.
*/
if (re->re_duration == RE_NOTSET)
res->res_duration = RE_NOTSET;
return next_time;
}
static Tick
DoMinute(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
return (Tick)NULL;
}
static Tick
DoDay(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
Tick next_time;
Duration res_duration = res->res_duration;
unsigned int res_time = RES_DSTATE(res).res_time;
if (RE_DAILY(re)->dd_ntime) {
/* Last event was on the last time for this day. Now must
* move to the next day/interval.
*/
if (RES_DSTATE(res).res_time == RE_DAILY(re)->dd_ntime - 1) {
next_time = NextDayTick(cur_time, start_time, re, res);
RES_DSTATE(res).res_time = 0;
} else {
struct tm *tm;
_Xltimeparams localtime_buf;
/* There is a later valid time on this day, use it */
tm = _XLocaltime(&cur_time, localtime_buf);
tm->tm_hour =
RE_DAILY(re)->
dd_time[++RES_DSTATE(res).res_time] / 100;
tm->tm_min =
RE_DAILY(re)->dd_time[RES_DSTATE(res).res_time]
% 100;
tm->tm_isdst = -1;
next_time = mktime(tm);
}
} else {
/* No alternate times for this day/move to the next interval. */
next_time = NextDayTick(cur_time, start_time, re, res);
}
/* If we went beyond the end date then restore the state info, ret 0 */
if (re->re_end_date && re->re_end_date < next_time) {
res->res_duration = res_duration;
RES_DSTATE(res).res_time = res_time;
return 0;
}
return next_time;
}
static Tick
DoWeek(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
unsigned int res_daytime = RES_WSTATE(res).res_daytime,
res_time = RES_WSTATE(res).res_time,
re_ntime,
re_ndaytime = RE_WEEKLY(re)->wd_ndaytime;
Duration res_duration = res->res_duration;
struct tm cur_tm,
start_tm;
DayTime *daytime = RE_WEEKLY(re)->wd_daytime;
Tick next_time;
_Xltimeparams localtime_buf;
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
re_ntime = daytime[0].dt_ntime;
/*
* We want to stop when the duration == 1 and we have handled all
* the days in the rule for that week.
*/
if ((res->res_duration == 0) || ((res->res_duration == 1) &&
((re_ndaytime - 1) == RES_WSTATE(res).res_daytime)))
return (Tick)0;
/* If these are equal then we are at the end of the time
* slots for this day */
if ((re_ntime - 1) == res_time) {
/* If these are equal then we used up all the
* days for this week */
if ((re_ndaytime - 1) == res_daytime) {
/* End of week */
RES_WSTATE(res).res_daytime = 0;
RES_WSTATE(res).res_time = 0;
next_time = NextWeekTick(&cur_tm, &start_tm, re,
daytime, NextInterval, res);
} else {
/* Move to the next day event (same week), use
* the earliest time.
*/
RES_WSTATE(res).res_time = 0;
RES_WSTATE(res).res_daytime++;
next_time = NextWeekTick(&cur_tm, &start_tm, re,
daytime, SameInterval, res);
}
} else {
/* Move to the next time, same day. */
RES_WSTATE(res).res_time++;
next_time = NextWeekTick(&cur_tm, &start_tm, re, daytime,
SameInterval, res);
}
/* If we went beyond the end date then restore the state info, ret 0 */
if (re->re_end_date && re->re_end_date < next_time) {
res->res_duration = res_duration;
RES_WSTATE(res).res_time = res_time;
RES_WSTATE(res).res_daytime = res_daytime;
return 0;
}
return (next_time);
}
static Tick
DoMonthDay(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
unsigned int *md_days = RE_MONTHLY(re)->md_days,
md_nitems = RE_MONTHLY(re)->md_nitems,
res_day = RES_MSTATE(res).res_day;
Duration res_duration = res->res_duration;
Tick _cur_time;
struct tm start_tm,
cur_tm;
int next_interval = FALSE;
_Xltimeparams localtime_buf;
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/*
* We want to stop when the duration == 1 and we have handled all
* the days listed in the rule for that month.
*/
if ((res->res_duration == 0) || ((res->res_duration == 1) &&
((md_nitems - 1) == RES_MSTATE(res).res_day)))
return (Tick)0;
/* Check each event day in the month, move to the next interval when
* we run out of event days for the month. Make sure the event day
* exists in that month. e.g. the 31st of June does not exist.
*/
do {
if ((md_nitems - 1) == RES_MSTATE(res).res_day) {
cur_tm.tm_mon += 1 * re->re_interval;
RES_MSTATE(res).res_day = 0;
next_interval = TRUE;
} else
RES_MSTATE(res).res_day++;
cur_tm.tm_isdst = -1;
cur_tm.tm_mday = 1;
_cur_time = mktime(&cur_tm);
cur_tm = *_XLocaltime((const time_t *)&_cur_time, localtime_buf);
} while (!DayExists(md_days[RES_MSTATE(res).res_day], cur_tm.tm_mon,
cur_tm.tm_year));
cur_tm.tm_mday = DayOfMonth(md_days[RES_MSTATE(res).res_day],
cur_tm.tm_mon, cur_tm.tm_year);
cur_tm.tm_isdst = -1;
_cur_time = mktime(&cur_tm);
if (next_interval) res->res_duration--;
/* If we went beyond the end date then restore the state info, ret 0 */
if (re->re_end_date && re->re_end_date < _cur_time) {
res->res_duration = res_duration;
RES_MSTATE(res).res_day = res_day;
return 0;
}
return (_cur_time);
}
static Tick
DoMonthPos(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
WeekDayTime *wdt_list = RE_MONTHLY(re)->md_weektime;
struct tm start_tm,
cur_tm;
Tick _cur_time;
Duration res_duration = res->res_duration;
unsigned int md_nitems = RE_MONTHLY(re)->md_nitems,
wdt_nday = wdt_list[md_nitems-1].wdt_nday,
wdt_nweek = wdt_list[md_nitems-1].wdt_nweek,
res_weektime = RES_MSTATE(res).res_weektime,
res_wday = RES_MSTATE(res).res_wday,
res_wtime = RES_MSTATE(res).res_wtime,
res_wweek = RES_MSTATE(res).res_wweek;
_Xltimeparams localtime_buf;
if (res->res_duration == 0)
return (Tick)0;
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/* XXX: This assumes rules of this form only: MP<n> 1+ WE #4 */
if ((wdt_list[res_weektime].wdt_nday - 1) == res_wday) {
if ((wdt_list[res_weektime].wdt_nweek - 1) == res_wweek) {
if ((md_nitems - 1) == res_weektime) {
RES_MSTATE(res).res_weektime = 0;
RES_MSTATE(res).res_wday = 0;
RES_MSTATE(res).res_wtime = 0;
RES_MSTATE(res).res_wweek = 0;
_cur_time = NextMonthTick(&cur_tm, re, wdt_list,
NextInterval, res);
} else {
_cur_time = 0;
}
} else {
_cur_time = 0;
}
} else {
_cur_time = 0;
}
/* If we went beyond the end date then restore the state info, ret 0 */
if (re->re_end_date && re->re_end_date < _cur_time) {
res->res_duration = res_duration;
RES_MSTATE(res).res_weektime = res_weektime;
RES_MSTATE(res).res_wday = res_wday;
RES_MSTATE(res).res_wtime = res_wtime;
RES_MSTATE(res).res_wweek = res_wweek;
return 0;
}
return (_cur_time);
}
static Tick
DoYearByMonth(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
struct tm start_tm,
cur_tm;
Tick _cur_time;
Duration res_duration = res->res_duration;
unsigned int *month_list = RE_YEARLY(re)->yd_items,
nitems = RE_YEARLY(re)->yd_nitems,
res_month = RES_YSTATE(res).res_daymonth;
_Xltimeparams localtime_buf;
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/*
* We want to stop when the duration == 1 and we have handled all
* the months listed in the rule for that year.
*/
if ((res->res_duration == 0) || ((res->res_duration == 1) &&
((nitems - 1) == RES_YSTATE(res).res_daymonth)))
return (Tick)0;
cur_tm.tm_mday = start_tm.tm_mday;
cur_tm.tm_hour = start_tm.tm_hour;
cur_tm.tm_min = start_tm.tm_min;
cur_tm.tm_sec = start_tm.tm_sec;
/* If these equal then we used up all the months for this year.
* We must now move to the next interval.
*/
if ((nitems - 1) == res_month) {
cur_tm.tm_year += re->re_interval;
cur_tm.tm_mon = month_list[0] - 1; /* 0 = January */
RES_YSTATE(res).res_daymonth = 0;
res->res_duration--;
} else {
/* Take the next month in the month_list, same year */
cur_tm.tm_mon = month_list[++RES_YSTATE(res).res_daymonth] - 1;
}
cur_tm.tm_isdst = -1;
_cur_time = mktime(&cur_tm);
/* If we went beyond the end date then restore the state info, ret 0 */
if (re->re_end_date && re->re_end_date < _cur_time) {
res->res_duration = res_duration;
RES_YSTATE(res).res_daymonth = res_month;
return 0;
}
return (_cur_time);
}
static Tick
DoYearByDay(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
struct tm start_tm,
cur_tm;
Tick _cur_time;
Duration res_duration = res->res_duration;
unsigned int *day_list = RE_YEARLY(re)->yd_items,
nitems = RE_YEARLY(re)->yd_nitems,
res_month = RES_YSTATE(res).res_daymonth;
_Xltimeparams localtime_buf;
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/*
* We want to stop when the duration == 1 and we have handled all
* the days listed in the rule for that year.
*/
if ((res->res_duration == 0) || ((res->res_duration == 1) &&
((nitems - 1) == RES_YSTATE(res).res_daymonth)))
return (Tick)0;
cur_tm.tm_mday = start_tm.tm_mday;
cur_tm.tm_hour = start_tm.tm_hour;
cur_tm.tm_min = start_tm.tm_min;
cur_tm.tm_sec = start_tm.tm_sec;
cur_tm.tm_mon = 0;
cur_tm.tm_isdst = -1;
/* If these equal then we used up all the days for this year.
* We must now move to the next interval.
*/
if ((nitems - 1) == res_month) {
cur_tm.tm_year += re->re_interval;
cur_tm.tm_mday = day_list[0];
RES_YSTATE(res).res_daymonth = 0;
res->res_duration--;
} else {
/* Take the next day in the day_list, same year */
cur_tm.tm_mday = day_list[++RES_YSTATE(res).res_daymonth];
}
_cur_time = mktime(&cur_tm);
/* If we went beyond the end date then restore the state info, ret 0 */
if (re->re_end_date && re->re_end_date < _cur_time) {
res->res_duration = res_duration;
RES_YSTATE(res).res_daymonth = res_month;
return 0;
}
return (_cur_time);
}
static Tick
NextDayTick(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
struct tm *tm;
struct tm start_tm;
_Xltimeparams localtime_buf;
if (res->res_duration == 0) return (Tick)0;
res->res_duration--;
start_tm = *_XLocaltime(&start_time, localtime_buf);
tm = _XLocaltime(&cur_time, localtime_buf);
tm->tm_mday += re->re_interval;
tm->tm_hour = start_tm.tm_hour;
tm->tm_min = start_tm.tm_min;
tm->tm_isdst = -1;
return (mktime(tm));
}
static Tick
NextWeekTick(
const struct tm *current_tm,
const struct tm *start_tm,
const RepeatEvent *re,
const DayTime *wd_daytime,
const MoveIndicator move,
RepeatEventState *res)
{
struct tm *cur_tm = (struct tm *)current_tm;
unsigned int res_daytime = RES_WSTATE(res).res_daytime;
unsigned int res_time = RES_WSTATE(res).res_time;
/* Move forward to the next interval (at least another week) */
if (move == (const MoveIndicator) NextInterval) {
/* Normalize the date to the beginning of the week. */
cur_tm->tm_mday -= cur_tm->tm_wday;
cur_tm->tm_sec = cur_tm->tm_min = cur_tm->tm_hour = 0;
cur_tm->tm_isdst = -1;
/* Add an interval */
cur_tm->tm_mday += re->re_interval * 7;
/* Put it on the correct day. */
cur_tm->tm_mday += wd_daytime[0].dt_day;
/* Put it on the correct time. */
cur_tm->tm_hour = wd_daytime[0].dt_time[0] / 100;
cur_tm->tm_min = wd_daytime[0].dt_time[0] % 100;
res->res_duration--;
return (mktime(cur_tm));
}
/* SameInterval */
/* Move the appropriate number of days forward */
cur_tm->tm_mday += GetWDayDiff(cur_tm->tm_wday,
wd_daytime[res_daytime].dt_day);
/* Use the indicated time if available */
if (RE_WEEKLY(re)->wd_daytime[res_daytime].dt_time) {
cur_tm->tm_hour = wd_daytime[res_daytime].dt_time[res_time]
/ 100;
cur_tm->tm_min = wd_daytime[res_daytime].dt_time[res_time]
% 100;
} else {
/* Use the time from the first appt */
cur_tm->tm_hour = start_tm->tm_hour;
cur_tm->tm_min = start_tm->tm_min;
}
cur_tm->tm_isdst = -1;
return (mktime(cur_tm));
}
static Tick
NextMonthTick(
const struct tm *current_time,
const RepeatEvent *re,
const WeekDayTime *wdt_list,
const MoveIndicator move,
RepeatEventState *res)
{
struct tm *cur_tm = (struct tm *)current_time;
unsigned int res_weektime = RES_MSTATE(res).res_weektime,
res_wweek = RES_MSTATE(res).res_wweek,
res_wday = RES_MSTATE(res).res_wday;
Tick next_time;
/* Move forward to the next interval (at least another month) */
if (move == (const MoveIndicator) NextInterval) {
cur_tm->tm_mday = 1;
do {
/* Add an interval */
cur_tm->tm_mon += re->re_interval;
cur_tm->tm_isdst = -1;
} while (!(next_time = WeekNumberToDay(mktime(cur_tm),
wdt_list[res_weektime].wdt_week[res_wweek],
wdt_list[res_weektime].wdt_day[res_wday])));
res->res_duration--;
} else {
/* SameInterval */
next_time = 0;
}
return (next_time);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
/* $XConsortium: repeat.h /main/4 1995/11/09 12:49:18 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.
*/
#ifndef _REPEAT_H
#define _REPEAT_H
#include <EUSCompat.h>
#include "ansi_c.h"
#include "cm.h"
#include "rtable4.h"
#include "rerule.h"
typedef time_t Tick;
extern int monthdays[];
extern void init_time P(());
extern time_t _DtCms_closest_tick_v4 P((time_t target,
time_t ftick,
Period_4 period,
int *ordinal));
extern time_t _DtCms_last_tick_v4 P((time_t ftick,
Period_4 period,
int ntimes));
extern time_t _DtCms_next_tick_v4 P((time_t tick, Period_4 period));
extern time_t _DtCms_prev_tick_v4 P((time_t tick, Period_4 period));
extern time_t _DtCms_first_tick_v4 P((time_t t, Period_4 period, int ordinal));
extern void _DtCms_adjust_appt_startdate P((Appt_4 *appt));
extern time_t next_nmins P((time_t t, int m));
extern time_t next_ndays P((time_t t, int n));
extern int _DtCms_marked_4_cancellation P((Appt_4 *a, int i));
extern int _DtCms_get_new_ntimes_v4 P((Period_4 period,
time_t tick,
int ninstance));
extern int _DtCms_get_ninstance_v4 P((Appt_4 *appt));
extern int _DtCms_in_repeater P((Id_4 *key,
Appt_4 *p_appt,
boolean_t dont_care_cancel));
extern int monthlength P((Tick));
extern int leapyr P((int));
extern int fdom P((Tick));
extern int ldom P((Tick));
/*
* returns the tick of the beginning of the day
*/
extern time_t _DtCmsBeginOfDay(time_t t);
/*
* return the tick since begin of day
*/
extern time_t _DtCmsTimeOfDay(time_t t);
/*
* routines to deal with recurrence rule and exception dates
*/
extern boolean_t _DtCmsInExceptionList P((cms_entry *eptr, time_t tick));
#endif

View File

@@ -0,0 +1,590 @@
/* $XConsortium: reprevtick.c /main/6 1996/11/21 19:46:55 drk $ */
/*
* (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.
*/
#define XOS_USE_NO_LOCKING
#define X_INCLUDE_TIME_H
#include <X11/Xos_r.h>
#include "rerule.h"
#include "repeat.h"
#include "reutil.h"
typedef enum {
SameInterval,
NextInterval
} MoveIndicator;
static Tick DoMinute(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoDay(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoWeek(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoMonthDay(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoMonthPos(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoYearByMonth(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick DoYearByDay(const Tick, const Tick, const RepeatEvent *,
RepeatEventState *);
static Tick PrevDayTick(const Tick, const int, const int, const RepeatEvent *,
RepeatEventState *);
static Tick PrevWeekTick(const struct tm *, const struct tm *,
const RepeatEvent *, const DayTime *,
const MoveIndicator, RepeatEventState *);
static Tick PrevMonthTick(const struct tm *, const RepeatEvent *,
const WeekDayTime *, const MoveIndicator,
RepeatEventState *);
extern void FillInRepeatEvent(const Tick, RepeatEvent *);
static int
DurationCheck(
const Duration res_dur,
const Duration re_dur)
{
if (re_dur == RE_INFINITY || re_dur == RE_NOTSET) return TRUE;
if (res_dur > re_dur)
return FALSE;
return TRUE;
}
Tick
PrevTick(
const Tick cur_time,
const Tick start_time,
RepeatEvent *re,
RepeatEventState *res)
{
Tick next_time;
Tick _start_time;
if (!re) return (Tick)NULL;
if (!start_time)
FillInRepeatEvent(cur_time, re);
else
FillInRepeatEvent(start_time, re);
if (!DurationCheck(res->res_duration, re->re_duration)) return (Tick)0;
switch (re->re_type) {
case RT_MINUTE:
next_time = DoMinute(cur_time, start_time, re, res);
break;
case RT_DAILY:
next_time = DoDay(cur_time, start_time, re, res);
break;
case RT_WEEKLY:
next_time = DoWeek(cur_time, start_time, re, res);
break;
case RT_MONTHLY_POSITION:
next_time = DoMonthPos(cur_time, start_time, re, res);
break;
case RT_MONTHLY_DAY:
next_time = DoMonthDay(cur_time, start_time, re, res);
break;
case RT_YEARLY_MONTH:
next_time = DoYearByMonth(cur_time, start_time, re, res);
break;
case RT_YEARLY_DAY:
next_time = DoYearByDay(cur_time, start_time, re, res);
break;
}
/*
* If the duration was not set (thus strictly using the end date)
* reset the RepeatEventState duration back to not-set. This is
* cleaner than having conditionals through out the code checking
* to see if the duration needs to be updated.
*/
if (re->re_duration == RE_NOTSET)
res->res_duration = RE_NOTSET;
return next_time;
}
/*
* If DoMinute is called, RT_MINUTE must be on top of res stack.
*/
static Tick
DoMinute(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
return (Tick)NULL;
}
static Tick
DoDay(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
Tick prev_time;
Duration res_duration = res->res_duration;
unsigned int dd_ntime = RE_DAILY(re)->dd_ntime,
res_time = RES_DSTATE(res).res_time;
if (dd_ntime) {
/* Last event was on the first time for this day. Now must
* move to the previous day/interval - latest hour.
*/
if (RES_DSTATE(res).res_time == 0) {
prev_time = PrevDayTick(cur_time,
RE_DAILY(re)->dd_time[dd_ntime - 1]/100,
RE_DAILY(re)->dd_time[dd_ntime - 1]%100,
re, res);
RES_DSTATE(res).res_time = dd_ntime - 1;
} else {
struct tm *tm;
_Xltimeparams localtime_buf;
/* There is an earlier valid time on this day, use it */
tm = _XLocaltime(&cur_time, localtime_buf);
tm->tm_hour =
RE_DAILY(re)->
dd_time[--RES_DSTATE(res).res_time] / 100; tm->tm_min =
RE_DAILY(re)->dd_time[RES_DSTATE(res).res_time]
% 100;
tm->tm_isdst = -1;
prev_time = mktime(tm);
}
} else {
struct tm *start_tm;
_Xltimeparams localtime_buf;
/* No alternate times for this day/move to the previous
* interval.
*/
if (start_time)
start_tm = _XLocaltime(&start_time, localtime_buf);
else
start_tm = _XLocaltime(&cur_time, localtime_buf);
prev_time = PrevDayTick(cur_time, start_tm->tm_hour,
start_tm->tm_min, re, res);
}
/* We can not move before the start time. */
if (prev_time < start_time) {
res->res_duration = res_duration;
RES_DSTATE(res).res_time = res_time;
return 0;
}
return prev_time;
}
static Tick
DoWeek(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
unsigned int res_daytime = RES_WSTATE(res).res_daytime,
res_time = RES_WSTATE(res).res_time,
re_ntime,
re_ndaytime = RE_WEEKLY(re)->wd_ndaytime;
Duration res_duration = res->res_duration;
struct tm cur_tm,
start_tm;
DayTime *daytime = RE_WEEKLY(re)->wd_daytime;
Tick prev_time;
_Xltimeparams localtime_buf;
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
if (start_time)
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
else
start_tm = cur_tm;
re_ntime = daytime[0].dt_ntime;
/* If this is 0 then we are at the first time for this day. */
if (!res_time) {
/* If this is 0 then we are at the first day for this week. */
if (!res_daytime) {
/* Beginning of week - move to an earlier week */
RES_WSTATE(res).res_daytime = re_ndaytime - 1;
RES_WSTATE(res).res_time = re_ntime - 1;
prev_time = PrevWeekTick(&cur_tm, &start_tm, re,
daytime, NextInterval, res);
} else {
/* Move to the prev day event (same week), use
* the latest time.
*/
RES_WSTATE(res).res_time = re_ntime - 1;
RES_WSTATE(res).res_daytime--;
prev_time = PrevWeekTick(&cur_tm, &start_tm, re,
daytime, SameInterval, res);
}
} else {
/* Move to an earlier time, same day. */
RES_WSTATE(res).res_time--;
prev_time = PrevWeekTick(&cur_tm, &start_tm, re, daytime,
SameInterval, res);
}
/* We can not move before the start time. */
if (prev_time < start_time) {
res->res_duration = res_duration;
RES_WSTATE(res).res_time = res_time;
RES_WSTATE(res).res_daytime = res_daytime;
return 0;
}
return (prev_time);
}
static Tick
DoMonthDay(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
unsigned int *md_days = RE_MONTHLY(re)->md_days,
md_nitems = RE_MONTHLY(re)->md_nitems,
res_day = RES_MSTATE(res).res_day;
Duration res_duration = res->res_duration;
struct tm cur_tm;
Tick _cur_time;
int next_interval = FALSE;
_Xltimeparams localtime_buf;
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/* Check each event day in the month, move to the previous interval
* when we run out of event days for the month. Make sure the event
* day * exists in that month. e.g. the 31st of June does not exist.
*/
do {
if (!RES_MSTATE(res).res_day) {
cur_tm.tm_mon -= 1 * re->re_interval;
RES_MSTATE(res).res_day = md_nitems - 1;
next_interval = TRUE;
} else
RES_MSTATE(res).res_day--;
cur_tm.tm_isdst = -1;
cur_tm.tm_mday = 1;
_cur_time = mktime(&cur_tm);
cur_tm = *_XLocaltime((const time_t *)&_cur_time, localtime_buf);
} while (!DayExists(md_days[RES_MSTATE(res).res_day], cur_tm.tm_mon,
cur_tm.tm_year));
cur_tm.tm_mday = DayOfMonth(md_days[RES_MSTATE(res).res_day],
cur_tm.tm_mon, cur_tm.tm_year);
cur_tm.tm_isdst = -1;
_cur_time = mktime(&cur_tm);
if (next_interval) res->res_duration++;
/* We can not move before the start time. */
if (_cur_time < start_time) {
res->res_duration = res_duration;
RES_MSTATE(res).res_day = res_day;
return 0;
}
return (_cur_time);
}
static Tick
DoMonthPos(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
WeekDayTime *wdt_list = RE_MONTHLY(re)->md_weektime;
struct tm cur_tm;
Duration res_duration = res->res_duration;
Tick _cur_time;
unsigned int md_nitems = RE_MONTHLY(re)->md_nitems,
res_weektime = RES_MSTATE(res).res_weektime,
res_wday = RES_MSTATE(res).res_wday,
res_wtime = RES_MSTATE(res).res_wtime,
res_wweek = RES_MSTATE(res).res_wweek;
_Xltimeparams localtime_buf;
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
/* XXX: This assumes rules of this form only: MP<n> 1+ WE #4 */
if (!res_wday) {
if (!res_wweek) {
if (!res_weektime) {
RES_MSTATE(res).res_weektime = md_nitems - 1;
RES_MSTATE(res).res_wday =
wdt_list[md_nitems - 1].wdt_nday - 1;
RES_MSTATE(res).res_wtime =
wdt_list[md_nitems - 1].wdt_ntime - 1;
RES_MSTATE(res).res_wweek =
wdt_list[md_nitems - 1].wdt_nweek - 1;
_cur_time = PrevMonthTick(&cur_tm, re, wdt_list,
NextInterval, res);
} else {
_cur_time = 0;
}
} else {
_cur_time = 0;
}
} else {
_cur_time = 0;
}
/* We can not move before the start time. */
if (_cur_time < start_time) {
res->res_duration = res_duration;
RES_MSTATE(res).res_weektime = res_weektime;
RES_MSTATE(res).res_wday = res_wday;
RES_MSTATE(res).res_wtime = res_wtime;
RES_MSTATE(res).res_wweek = res_wweek;
return 0;
}
return (_cur_time);
}
static Tick
DoYearByMonth(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
struct tm start_tm,
cur_tm;
Duration res_duration = res->res_duration;
Tick _cur_time;
unsigned int *month_list = RE_YEARLY(re)->yd_items,
nitems = RE_YEARLY(re)->yd_nitems,
res_month = RES_YSTATE(res).res_daymonth;
_Xltimeparams localtime_buf;
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
if (start_time) {
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
cur_tm.tm_mday = start_tm.tm_mday;
cur_tm.tm_hour = start_tm.tm_hour;
cur_tm.tm_min = start_tm.tm_min;
cur_tm.tm_sec = start_tm.tm_sec;
} else
start_tm = cur_tm;
/* If this equals 0 then we are at the first event slot of the year,
* we must move backward one interval/year.
*/
if (!res_month) {
cur_tm.tm_year -= re->re_interval;
cur_tm.tm_mon = month_list[nitems - 1] - 1; /* 0 = January */
RES_YSTATE(res).res_daymonth = nitems - 1;
res->res_duration++;
} else {
/* Take the next month in the month_list, same year */
cur_tm.tm_mon = month_list[--RES_YSTATE(res).res_daymonth] - 1;
}
cur_tm.tm_isdst = -1;
_cur_time = mktime(&cur_tm);
/* We can not move before the start time. */
if (_cur_time < start_time) {
res->res_duration = res_duration;
RES_YSTATE(res).res_daymonth = res_month;
return 0;
}
return (_cur_time);
}
static Tick
DoYearByDay(
const Tick cur_time,
const Tick start_time,
const RepeatEvent *re,
RepeatEventState *res)
{
struct tm start_tm,
cur_tm;
Duration res_duration = res->res_duration;
Tick _cur_time;
unsigned int *day_list = RE_YEARLY(re)->yd_items,
nitems = RE_YEARLY(re)->yd_nitems,
res_month = RES_YSTATE(res).res_daymonth;
_Xltimeparams localtime_buf;
cur_tm = *_XLocaltime((const time_t *)&cur_time, localtime_buf);
if (start_time)
start_tm = *_XLocaltime((const time_t *)&start_time, localtime_buf);
else
start_tm = cur_tm;
cur_tm.tm_mday = start_tm.tm_mday;
cur_tm.tm_hour = start_tm.tm_hour;
cur_tm.tm_min = start_tm.tm_min;
cur_tm.tm_sec = start_tm.tm_sec;
cur_tm.tm_mon = 0;
cur_tm.tm_isdst = -1;
/* If this equals 0 then we are at the first event slot of the year,
* we must move backward one interval/year.
*/
if (!res_month) {
cur_tm.tm_year -= re->re_interval;
cur_tm.tm_mday = day_list[nitems - 1];
RES_YSTATE(res).res_daymonth = nitems - 1;
res->res_duration++;
} else {
/* Take the next day in the day_list, same year */
cur_tm.tm_mday = day_list[--RES_YSTATE(res).res_daymonth];
}
_cur_time = mktime(&cur_tm);
/* We can not move before the start time. */
if (_cur_time < start_time) {
res->res_duration = res_duration;
RES_YSTATE(res).res_daymonth = res_month;
return 0;
}
return (_cur_time);
}
static Tick
PrevDayTick(
const Tick tick,
const int hour,
const int min,
const RepeatEvent *re,
RepeatEventState *res)
{
struct tm *tm;
_Xltimeparams localtime_buf;
res->res_duration++;
tm = _XLocaltime(&tick, localtime_buf);
tm->tm_mday -= re->re_interval;
tm->tm_hour = hour;
tm->tm_min = min;
return (mktime(tm));
}
static Tick
PrevWeekTick(
const struct tm *current_tm,
const struct tm *start_tm,
const RepeatEvent *re,
const DayTime *wd_daytime,
const MoveIndicator move,
RepeatEventState *res)
{
struct tm *cur_tm = (struct tm *)current_tm;
unsigned int res_daytime = RES_WSTATE(res).res_daytime;
unsigned int res_time = RES_WSTATE(res).res_time;
/* Move backward to the previous interval (at least another week) */
if (move == (const MoveIndicator)NextInterval) {
/* Normalize the date to the beginning of the week. */
cur_tm->tm_mday -= cur_tm->tm_wday;
cur_tm->tm_sec = cur_tm->tm_min = cur_tm->tm_hour = 0;
cur_tm->tm_isdst = -1;
/* Subtract an interval */
cur_tm->tm_mday -= re->re_interval * 7;
/* Put it on the correct day. */
cur_tm->tm_mday += wd_daytime[res_daytime].dt_day;
/* Put it on the correct time. */
if (wd_daytime[res_daytime].dt_time) {
cur_tm->tm_hour =
wd_daytime[res_daytime].dt_time[res_time] / 100;
cur_tm->tm_min =
wd_daytime[res_daytime].dt_time[res_time] % 100;
} else {
/* Use the time from the first appt */
cur_tm->tm_hour = start_tm->tm_hour;
cur_tm->tm_min = start_tm->tm_min;
}
res->res_duration++;
return (mktime(cur_tm));
}
/* SameInterval */
/* Move the appropriate number of days forward */
cur_tm->tm_mday -= GetWDayDiff(
RE_WEEKLY(re)->wd_daytime[res_daytime].dt_day,
cur_tm->tm_wday);
/* Use the indicated time if available */
if (wd_daytime[res_daytime].dt_time) {
cur_tm->tm_hour = wd_daytime[res_daytime].dt_time[res_time]
/ 100;
cur_tm->tm_min = wd_daytime[res_daytime].dt_time[res_time]
% 100;
} else {
/* Use the time from the first appt */
cur_tm->tm_hour = start_tm->tm_hour;
cur_tm->tm_min = start_tm->tm_min;
}
cur_tm->tm_isdst = -1;
return (mktime(cur_tm));
}
static Tick
PrevMonthTick(
const struct tm *current_tm,
const RepeatEvent *re,
const WeekDayTime *wdt_list,
const MoveIndicator move,
RepeatEventState *res)
{
struct tm *cur_tm = (struct tm *)current_tm;
unsigned int res_weektime = RES_MSTATE(res).res_weektime,
res_wweek = RES_MSTATE(res).res_wweek,
res_wday = RES_MSTATE(res).res_wday;
Tick next_time;
/* Move backward to the previous interval (at least another month) */
if (move == (const MoveIndicator)NextInterval) {
cur_tm->tm_mday = 1;
do {
/* Add an interval */
cur_tm->tm_mon -= re->re_interval;
cur_tm->tm_isdst = -1;
} while (!(next_time = WeekNumberToDay(mktime(cur_tm),
wdt_list[res_weektime].wdt_week[res_wweek],
wdt_list[res_weektime].wdt_day[res_wday])));
res->res_duration++;
} else {
/* SameInterval */
next_time = 0;
}
return (next_time);
}

View File

@@ -0,0 +1,406 @@
/* $XConsortium: rerule.c /main/4 1995/11/09 12:50:23 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 <stdio.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "rerule.h"
typedef enum {
NUM_NUM = 0, /* Used in NumsToBuf to tell the proc what */
NUM_DAY, /* type of list we are handing it. */
NUM_WEEK
} NumType;
static void NumsToBuf(unsigned int *, unsigned int, NumType, char *,
unsigned int);
static void WeekNumberToString(WeekNumber, char *);
static void WeekDayToString(WeekDay, char *);
static void ConvertDaily(RepeatEvent *, char *, unsigned int);
static void ConvertWeekly(RepeatEvent *, char *, unsigned int);
static void ConvertMonthly(RepeatEvent *, char *, unsigned int);
static void ConvertYearly(RepeatEvent *, char *, unsigned int);
#define RE_DAILY(re) (re->re_data.re_daily)
#define RE_WEEKLY(re) (re->re_data.re_weekly)
#define RE_MONTHLY(re) (re->re_data.re_monthly)
#define RE_YEARLY(re) (re->re_data.re_yearly)
char *
ReToString(
RepeatEvent *re)
{
char *cmd_buf = NULL;
char *cmd_buf_tmp = NULL;
int cmd_buf_size = 0;
int subcommand_size = 0;
char subcommand[1024]; /* XXX: fixed size */
if (!re) return (char *)NULL;
while (re) {
switch (re->re_type) {
case RT_MINUTE:
sprintf(subcommand, "M%d #%d",
re->re_interval, re->re_duration);
break;
case RT_DAILY:
ConvertDaily(re, subcommand, 1024);
break;
case RT_WEEKLY:
ConvertWeekly(re, subcommand, 1024);
break;
case RT_MONTHLY_POSITION:
case RT_MONTHLY_DAY:
ConvertMonthly(re, subcommand, 1024);
break;
case RT_YEARLY_MONTH:
case RT_YEARLY_DAY:
ConvertYearly(re, subcommand, 1024);
break;
}
cmd_buf_tmp = cmd_buf;
if (cmd_buf) cmd_buf_size = strlen(cmd_buf);
if (subcommand) subcommand_size = strlen(subcommand);
cmd_buf = (char *)calloc(1, cmd_buf_size + subcommand_size + 2);
if (cmd_buf_tmp)
strcat (cmd_buf, cmd_buf_tmp);
if (subcommand) {
if (cmd_buf_tmp)
strcat (cmd_buf, " ");
strcat (cmd_buf, subcommand);
}
memset (subcommand, NULL, 1024);
re = re->re_next;
}
return cmd_buf;
}
/*
* Takes an array of numbers, converts them back into their string
* type (e.g. SU 1W etc) and puts them into a string buffer with end
* marks as necessary, seperated by spaces.
*/
static void
NumsToBuf(
unsigned int *array,
unsigned int array_size,
NumType type,
char *buffer,
unsigned int buf_size)
{
int i,
size = 0;
char tmp_buf[32],
tmp_buf2[32];
for (i = 0; i < array_size; i++) {
if (type == NUM_NUM)
sprintf(tmp_buf2, " %d", RE_MASK_STOP(array[i]));
else if (type == NUM_DAY)
WeekDayToString(RE_MASK_STOP(array[i]), tmp_buf2);
else if (type == NUM_WEEK)
WeekNumberToString(RE_MASK_STOP(array[i]), tmp_buf2);
/* Add end mark if needed */
if (RE_STOP_IS_SET(array[i])) {
sprintf(tmp_buf, "%s$", tmp_buf2);
strcat (buffer, tmp_buf);
size += strlen(tmp_buf);
} else {
strcat (buffer, tmp_buf2);
size += strlen(tmp_buf2);
}
/* Make sure the size of our buffer does not overflow */
if (size > buf_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
}
}
static void
WeekDayToString(
WeekDay day,
char *buffer)
{
switch (RE_MASK_STOP(day)) {
case WD_SUN:
sprintf (buffer, " SU");
break;
case WD_MON:
sprintf (buffer, " MO");
break;
case WD_TUE:
sprintf (buffer, " TU");
break;
case WD_WED:
sprintf (buffer, " WE");
break;
case WD_THU:
sprintf (buffer, " TH");
break;
case WD_FRI:
sprintf (buffer, " FR");
break;
case WD_SAT:
sprintf (buffer, " SA");
break;
}
if (RE_STOP_IS_SET(day))
strcat (buffer, "$");
}
static void
WeekNumberToString(
WeekNumber week,
char *buffer)
{
switch (RE_MASK_STOP(week)) {
case WK_F1:
sprintf (buffer, " 1+");
break;
case WK_F2:
sprintf (buffer, " 2+");
break;
case WK_F3:
sprintf (buffer, " 3+");
break;
case WK_F4:
sprintf (buffer, " 4+");
break;
case WK_F5:
sprintf (buffer, " 5+");
break;
case WK_L1:
sprintf (buffer, " 1-");
break;
case WK_L2:
sprintf (buffer, " 2-");
break;
case WK_L3:
sprintf (buffer, " 3-");
break;
case WK_L4:
sprintf (buffer, " 4-");
break;
case WK_L5:
sprintf (buffer, " 5-");
break;
}
if (RE_STOP_IS_SET(week))
strcat (buffer, "$");
}
static void
ConvertDaily(
RepeatEvent *re,
char *subcommand,
unsigned int buf_size)
{
char tmp_buf[32];
unsigned int size = 0,
num_time,
i;
num_time = RE_DAILY(re)->dd_ntime;
sprintf(subcommand, "D%d", re->re_interval);
size += strlen(subcommand);
NumsToBuf((unsigned int *)RE_DAILY(re)->dd_time, num_time, NUM_NUM,
subcommand, buf_size - size);
/* Tack on the duration information */
sprintf(tmp_buf, " #%d", re->re_duration);
size += strlen(tmp_buf);
if (size > buf_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
strcat (subcommand, tmp_buf);
}
static void
ConvertWeekly(
RepeatEvent *re,
char *subcommand,
unsigned int subcommand_size)
{
char tmp_buf[32];
int size = 0,
num_items,
i;
num_items = RE_WEEKLY(re)->wd_ndaytime;
sprintf(subcommand, "W%d", re->re_interval);
size += strlen(subcommand);
/* walk through Day/time data (e.g. TU 1200 Th 2000) */
for (i = 0; i < num_items; i++) {
/* The day: MO TU TH etc. */
WeekDayToString(RE_WEEKLY(re)->wd_daytime[i].dt_day, tmp_buf);
size += strlen(tmp_buf);
/* Make sure the size of our buffer does not overflow */
if (size > subcommand_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
strcat (subcommand, tmp_buf);
/* The hours: 1000 1400 etc. */
NumsToBuf((unsigned int *)RE_WEEKLY(re)->wd_daytime[i].dt_time,
RE_WEEKLY(re)->wd_daytime[i].dt_ntime, NUM_NUM,
subcommand, subcommand_size - size);
size = strlen(subcommand);
}
/* Tack on the duration information */
sprintf(tmp_buf, " #%d", re->re_duration);
size += strlen(tmp_buf);
if (size > subcommand_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
strcat (subcommand, tmp_buf);
}
static void
ConvertMonthly(
RepeatEvent *re,
char *subcommand,
unsigned int subcommand_size)
{
char tmp_buf[32];
int size = 0,
num_items,
i;
num_items = RE_MONTHLY(re)->md_nitems;
if (re->re_type == RT_MONTHLY_POSITION)
sprintf(subcommand, "MP%d", re->re_interval);
else
sprintf(subcommand, "MD%d", re->re_interval);
size += strlen(subcommand);
if (re->re_type == RT_MONTHLY_POSITION) {
/* walk through Day/time data (e.g. TU 1200 Th 2000) */
for (i = 0; i < num_items; i++) {
/* The week: 1+ 3- etc. */
NumsToBuf(
(unsigned int*)RE_MONTHLY(re)->md_weektime[i].wdt_week,
RE_MONTHLY(re)->md_weektime[i].wdt_nweek, NUM_WEEK,
subcommand, subcommand_size - size);
size = strlen(subcommand);
/* Make sure the size of our buffer does not overflow */
if (size > subcommand_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
/* The day: SU MO TU etc. */
NumsToBuf(
(unsigned int *)RE_MONTHLY(re)->md_weektime[i].wdt_day,
RE_MONTHLY(re)->md_weektime[i].wdt_nday, NUM_DAY,
subcommand, subcommand_size - size);
size = strlen(subcommand);
/* Make sure the size of our buffer does not overflow */
if (size > subcommand_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
/* The hours: 1000 1400 etc. */
NumsToBuf(
(unsigned int *)
RE_MONTHLY(re)->md_weektime[i].wdt_time,
RE_MONTHLY(re)->md_weektime[i].wdt_ntime, NUM_NUM,
subcommand, subcommand_size - size);
size = strlen(subcommand);
}
} else { /* RT_MONTHLY_DAY */
/* The days: 1 15 31 etc. */
NumsToBuf((unsigned int *)RE_MONTHLY(re)->md_days,
num_items, NUM_NUM, subcommand,
subcommand_size - size);
}
/* Tack on the duration information */
sprintf(tmp_buf, " #%d", re->re_duration);
size += strlen(tmp_buf);
if (size > subcommand_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
strcat (subcommand, tmp_buf);
}
static void
ConvertYearly(
RepeatEvent *re,
char *subcommand,
unsigned int subcommand_size)
{
char tmp_buf[32];
int size = 0,
num_items,
i;
num_items = RE_YEARLY(re)->yd_nitems;
if (re->re_type == RT_YEARLY_MONTH)
sprintf(subcommand, "YM%d", re->re_interval);
else
sprintf(subcommand, "YD%d", re->re_interval);
size += strlen(subcommand);
/* An array of days or months */
NumsToBuf(RE_YEARLY(re)->yd_items,
RE_YEARLY(re)->yd_nitems, NUM_NUM,
subcommand, subcommand_size - size);
/* Tack on the duration information */
sprintf(tmp_buf, " #%d", re->re_duration);
size += strlen(tmp_buf);
if (size > subcommand_size) {
printf ("Error: Internal buffer size exceeded\n");
return;
}
strcat (subcommand, tmp_buf);
}

View File

@@ -0,0 +1,371 @@
/* $XConsortium: reutil.c /main/7 1996/11/21 19:47:12 drk $ */
/*
* (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 <time.h>
#include <stdlib.h>
#include <string.h>
#include "rerule.h"
#include "reutil.h"
#include "repeat.h"
#define XOS_USE_NO_LOCKING
#define X_INCLUDE_TIME_H
#include <X11/Xos_r.h>
extern int monthdays[12];
extern RepeatEvent *_DtCm_repeat_info;
extern char *_DtCm_rule_buf;
extern void _DtCm_rule_parser();
extern char *ReToString(RepeatEvent *);
/*
* Check to make sure the current interval number is not greater than the
* duration.
*/
int
InTimeRange(
const unsigned int ninterval,
const Duration duration)
{
if (duration == RE_INFINITY || duration == RE_NOTSET) return TRUE;
if (ninterval >= duration)
return FALSE;
return TRUE;
}
/*
* Given two days of the week, compute the forward difference between them.
*/
int
GetWDayDiff(
const int start,
const int end)
{
if (start <= end)
return end - start;
return (7 - (start - end));
}
/*
* Returns true if a day exists in the specified month and year.
*/
int
DayExists(
const int day,
const int month,
const int year)
{
int valid_day = DayOfMonth(day, month, year);
if (valid_day < 29) return TRUE;
/* month = 0 = January */
if ((month == 1) && leapyr(year + 1900)) {
if (valid_day == 29)
return TRUE;
else
return FALSE;
}
if (valid_day <= monthdays[month])
return TRUE;
return FALSE;
}
/*
* Given a date (specifically a month and year) determine if any of the
* occurences of a weekday (e.g. 4th Sunday) exist in the given month.
*/
int
OccurenceExists(
const WeekDayTime *wdt_list,
const unsigned int nwdt_list,
const Tick date)
{
int i, j, k;
for (i = 0; i < nwdt_list; i++) {
for (j = 0; j < wdt_list[i].wdt_nweek; j++) {
for (k = 0; k < wdt_list[i].wdt_nday; k++) {
if (WeekNumberToDay(date,
wdt_list[i].wdt_week[j],
wdt_list[i].wdt_day[k])) {
return TRUE;
}
}
}
}
return FALSE;
}
WeekNumber
GetWeekNumber(
const Tick date)
{
switch (DayToWeekNumber(date)) {
case 1:
return WK_F1;
case 2:
return WK_F2;
case 3:
return WK_F3;
case 4:
return WK_F4;
case 5:
return WK_F5;
default:
return WK_L1;
}
}
/*
* Calculate the position of a week day (e.g. SU) in the month:
* 7/1/94 would return 1 since this is the first Friday of the month.
* 7/6/94 would return 1 even though it is in the second week since this
* is the first Wed of the month.
* 7/15/94 would return 3.
*/
WeekNumber
DayToWeekNumber(
const Tick date)
{
_Xltimeparams localtime_buf;
struct tm *date_tm = _XLocaltime(&date, localtime_buf);
int week_number;
week_number = date_tm->tm_mday / 7;
if (date_tm->tm_mday % 7)
week_number++;
return week_number;
}
/*
* Given a week number and a day of the week determine what day of the month
* it falls on given a month in ``date''.
*/
Tick
WeekNumberToDay(
const Tick date,
const WeekNumber week,
const WeekDay weekday)
{
_Xltimeparams localtime_buf;
struct tm *date_tm = _XLocaltime(&date, localtime_buf);
int first_weekday,
last_weekday,
day_of_month,
initial_month_number = date_tm->tm_mon;
Tick _date;
/* From the first day (or last day in the WK_L* cases) of the month
* work forward (or backward) to find the weekday requested.
*/
if (week <= (const WeekDay)WK_F5) {
day_of_month = 1;
first_weekday = fdom(date);
if (weekday != first_weekday)
day_of_month += GetWDayDiff(first_weekday, weekday);
} else {
day_of_month = monthlength(date);
last_weekday = ldom(date);
if (weekday != last_weekday)
day_of_month -= GetWDayDiff(weekday, last_weekday);
}
/* Now move forward or backward through the month added or subtracting
* the appropriate number of weeks to get to the correct location.
*/
if (week <= (const WeekDay)WK_F5) {
date_tm->tm_mday = day_of_month + (int)week * 7;
} else {
/* ((int)week - WK_L1) normalizes the WK_L* to the values
* of 0 to 4. See the WeekNumber enum.
*/
date_tm->tm_mday = day_of_month - ((int)week - WK_L1) * 7;
}
date_tm->tm_isdst = -1;
_date = mktime(date_tm);
date_tm = _XLocaltime(&_date, localtime_buf);
/* It is possible that the requested week number is not in this
* month.
*/
if (date_tm->tm_mon != initial_month_number)
return ((Tick)NULL);
return (_date);
}
unsigned int
DayOfMonth(
const int day,
const int month,
const int year)
{
if (day != RE_LASTDAY) return day;
/* month = 0 = January */
if ((month == 1) && leapyr(year + 1900))
return 29;
else
return monthdays[month];
}
int
same_week(
struct tm *tm1,
struct tm *tm2)
{
struct tm tm11 = *tm1;
struct tm tm22 = *tm2;
Tick time1, time2;
_Xltimeparams localtime_buf;
tm11.tm_mday -= tm11.tm_wday;
tm22.tm_mday -= tm22.tm_wday;
time1 = mktime(&tm11);
time2 = mktime(&tm22);
tm11 = *_XLocaltime(&time1, localtime_buf);
tm22 = *_XLocaltime(&time2, localtime_buf);
if (tm11.tm_yday == tm22.tm_yday)
return TRUE;
return FALSE;
}
Tick
DeriveNewStartTime(
const Tick start_time,
RepeatEvent *old_re,
const Tick current_time,
const Tick target_time,
RepeatEvent *new_re)
{
Tick end_date;
Tick an_event;
int num_events;
RepeatEventState *res;
/* Count the number of events from the start time to the current time */
end_date = old_re->re_end_date;
old_re->re_end_date = current_time;
/* XXX: Need to deal with excluded events */
num_events = CountEvents(start_time, old_re, NULL);
old_re->re_end_date = end_date;
if (!ClosestTick(current_time, start_time, old_re, &res)) {
/* XXX: Are we at the last tick or are there other problems? */
return 0;
}
an_event = target_time;
/* Walk backwards from the new target time to where the new start
* time should be.
*/
while (--num_events &&
(an_event = PrevTick(an_event, NULL, new_re, res))) {
;
}
return an_event;
}
/*
* Return True if rule1 is the same as rule2. This function returns True
* if the rule portion of the rules are == reguardless of the duration or
* end_date's.
* re1 should point to the RepeatEvent struct for rule1. If you pass in
* NULL for re1 the function *may* parse rule1 for you and return the
* RepeatEvent struct through re1. You will need to free it.
* The same applies for re2.
*/
boolean_t
RulesMatch(
char *rule1,
char *rule2)
{
Duration old_duration;
time_t old_end_date;
char *new_rule1,
*new_rule2;
RepeatEvent *re1,
*re2;
/* If rules are the same then we are done */
if (!strcmp(rule1, rule2))
return TRUE;
_DtCm_rule_buf = rule1;
_DtCm_rule_parser();
if (!_DtCm_repeat_info) {
/* Bad rule - fail */
return FALSE;
}
re1 = _DtCm_repeat_info;
_DtCm_rule_buf = rule2;
_DtCm_rule_parser();
if (!_DtCm_repeat_info) {
/* Bad rule - fail */
_DtCm_free_re(re1);
return FALSE;
}
re2 = _DtCm_repeat_info;
/* If rule1 != rule2 and the duration and end_date are the same
* then the rules themselves must be different.
*/
if (re1->re_duration == re2->re_duration &&
re1->re_end_date == re2->re_end_date) {
_DtCm_free_re(re1);
_DtCm_free_re(re2);
return FALSE;
}
/* If the duration or end_date are different, the rules themselves
* may still be different. So we make the durations and end_dates
* the same and reconstruct the rules.
*/
old_duration = re2->re_duration;
old_end_date = re2->re_end_date;
re2->re_duration = re1->re_duration;
re2->re_end_date = re1->re_end_date;
new_rule1 = ReToString(re1);
new_rule2 = ReToString(re2);
re2->re_duration = old_duration;
re2->re_end_date = old_end_date;
if (!strcmp(new_rule1, new_rule2)) {
_DtCm_free_re(re1);
_DtCm_free_re(re2);
free(new_rule1);
free(new_rule2);
return TRUE;
}
free(new_rule1);
free(new_rule2);
_DtCm_free_re(re1);
_DtCm_free_re(re2);
return FALSE;
}

View File

@@ -0,0 +1,62 @@
/* $XConsortium: reutil.h /main/4 1995/11/09 12:51:01 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.
*/
#ifndef _REUTIL_H
#define _REUTIL_H
#include "rerule.h"
#include "repeat.h"
#define EOT 2147483647
#define RE_DAILY(re) (re->re_data.re_daily)
#define RE_WEEKLY(re) (re->re_data.re_weekly)
#define RE_MONTHLY(re) (re->re_data.re_monthly)
#define RE_YEARLY(re) (re->re_data.re_yearly)
#define RES_DSTATE(res) (res->res_data.ds)
#define RES_WSTATE(res) (res->res_data.ws)
#define RES_MSTATE(res) (res->res_data.ms)
#define RES_YSTATE(res) (res->res_data.ys)
#define SAME_DAY(tm1, tm2) (((tm1)->tm_year == (tm2)->tm_year && \
(tm1)->tm_mon == (tm2)->tm_mon && \
(tm1)->tm_mday == (tm2)->tm_mday))
#define SAME_MONTH(tm1, tm2) (((tm1)->tm_year == (tm2)->tm_year && \
(tm1)->tm_mon == (tm2)->tm_mon))
#define TIME_OF_DAY(tm) ((tm)->tm_hour * 60 * 60 + \
(tm)->tm_min * 60 + \
(tm)->tm_sec)
#define TIMEOFMONTH(tm) (((tm)->tm_mday - 1) * 24 * 60 * 60 + \
(tm)->tm_hour * 60 * 60 + \
(tm)->tm_min * 60 + \
(tm)->tm_sec)
#define HOURTOSEC(time) ((time/100) * 60 * 60 + \
(time%100) * 60)
extern int GetWDayDiff(const int, const int);
extern int DayExists(const int, const int, const int);
extern WeekNumber GetWeekNumber(const Tick);
extern WeekNumber DayToWeekNumber(const Tick);
extern Tick WeekNumberToDay(const Tick, const WeekNumber, const WeekDay);
extern int OccurenceExists(const WeekDayTime *, const unsigned int, const Tick);
extern unsigned int DayOfMonth(const int, const int, const int);
extern int InTimeRange(const unsigned int, const Duration);
extern int same_week(struct tm *, struct tm *);
extern Tick ClosestTick(const Tick, const Tick, RepeatEvent *,
RepeatEventState **);
extern Tick NextTick(const Tick, const Tick, RepeatEvent *,
RepeatEventState *);
extern Tick PrevTick(const Tick, const Tick, RepeatEvent *,
RepeatEventState *);
extern Tick LastTick(const Tick, RepeatEvent *);
extern int CountEvents(Tick, RepeatEvent *re, CSA_date_time_entry *);
extern Tick DeriveNewStartTime(const Tick, RepeatEvent *old_re, const Tick,
const Tick, RepeatEvent *new_re);
#endif /* _REUTIL_H */

View File

@@ -0,0 +1,42 @@
/* $XConsortium: rpcextras.h /main/4 1995/11/09 12:51:20 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.
*/
#ifndef _RPCEXTRAS_H
#define _RPCEXTRAS_H
#include "ansi_c.h"
#define RPCGEN_ACTION(routine) routine
struct rpcgen_table {
char *(*proc)();
xdrproc_t xdr_arg;
unsigned len_arg;
xdrproc_t xdr_res;
unsigned len_res;
};
/* you might want to consider a program list rather than a table */
/* a list would be cleaner, a table easier. it's a table here for clarity */
typedef struct prog_table {
struct rpcgen_table *vers;
u_long nproc;
} program_table;
typedef struct prog_object {
program_table *prog;
u_long nvers;
u_long program_num;
} program_object;
typedef program_object *program_handle;
extern program_handle newph P(());
extern program_handle getph P(());
#endif

View File

@@ -0,0 +1,425 @@
/* $XConsortium: rtable2.c /main/4 1995/11/09 12:51:38 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.
*/
/*
veneer layered on top of the real data structures for abstraction.
implements Version 2 in terms of Version 4 types
*/
#include <EUSCompat.h>
#include <stdio.h>
#include "rtable4.h"
#include "rtable2.h"
#include <sys/param.h>
#include <sys/time.h>
#include <rpc/rpc.h>
#include "rpcextras.h"
#include "convert2-4.h"
#include "convert4-2.h"
#include "rtable2_tbl.i"
/*************** V2 PROTOCOL IMPLEMENTATION PROCS *****************/
extern void *
_DtCm_rtable_ping_2_svc(args, svcrq)
void *args;
struct svc_req *svcrq;
{
char dummy;
return((void *)&dummy); /* for RPC reply */
}
/* PROC #1 */
extern Table_Res_2 *
_DtCm_rtable_lookup_2_svc (args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_lookup_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #2 */
extern Table_Res_2 *
_DtCm_rtable_lookup_next_larger_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_lookup_next_larger_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #3 */
extern Table_Res_2 *
_DtCm_rtable_lookup_next_smaller_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_lookup_next_smaller_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #4 */
extern Table_Res_2 *
_DtCm_rtable_lookup_range_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_lookup_range_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #5 */
extern Table_Res_2 *
_DtCm_rtable_abbreviated_lookup_range_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_abbreviated_lookup_range_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #6 */
extern Table_Res_2 *
_DtCm_rtable_insert_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_insert_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #7 */
extern Table_Res_2 *
_DtCm_rtable_delete_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tabledelargs2_to_tabledelargs4(args, do_all_4);
newres = _DtCm_rtable_delete_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #8 */
extern Table_Res_2 *
_DtCm_rtable_delete_instance_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tabledelargs2_to_tabledelargs4(args, do_one_4);
newres = _DtCm_rtable_delete_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #9 */
extern Table_Res_2 *
_DtCm_rtable_change_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_change_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #10 */
extern Table_Res_2 *
_DtCm_rtable_change_instance_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newargs->args.Args_4_u.apptid.option = do_one_4;
newres = _DtCm_rtable_change_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #11 */
extern Table_Res_2 *
_DtCm_rtable_lookup_next_reminder_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Res_2 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_2, (char*)res);
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_lookup_next_reminder_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #12 */
extern Table_Status_2 *
_DtCm_rtable_check_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Status_2 res;
Table_Args_4 *newargs;
Table_Status_4 *newres;
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_check_4_svc(newargs, svcrq);
res = _DtCm_tablestat4_to_tablestat2(*newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(&res);
}
/* PROC #13 */
extern Table_Status_2 *
_DtCm_rtable_flush_table_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static Table_Status_2 res;
Table_Args_4 *newargs;
Table_Status_4 *newres;
newargs = _DtCm_tableargs2_to_tableargs4(args);
newres = _DtCm_rtable_flush_table_4_svc(newargs, svcrq);
res = _DtCm_tablestat4_to_tablestat2(*newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(&res);
}
/* PROC #14 */
extern int *
_DtCm_rtable_size_2_svc(args, svcrq)
Table_Args_2 *args;
struct svc_req *svcrq;
{
static int size;
Table_Args_4 *newargs;
newargs = _DtCm_tableargs2_to_tableargs4(args);
size = (*(_DtCm_rtable_size_4_svc(newargs, svcrq)));
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(&size);
}
/* PROC #15 */
Registration_Status_2 *
_DtCm_register_callback_2_svc(r, svcrq)
Registration_2 *r;
struct svc_req *svcrq;
{
static Registration_Status_2 stat;
Registration_4 *newreg;
Registration_Status_4 *newstat;
newreg = _DtCm_reg2_to_reg4(r);
newstat = _DtCm_register_callback_4_svc(newreg, svcrq);
stat = _DtCm_regstat4_to_regstat2(*newstat);
if (newreg!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Registration_4, (char*)newreg);
return(&stat);
}
/* PROC #16 */
Registration_Status_2 *
_DtCm_deregister_callback_2_svc(r, svcrq)
Registration_2 *r;
struct svc_req *svcrq;
{
static Registration_Status_2 stat;
Registration_4 *newreg;
Registration_Status_4 *newstat;
newreg = _DtCm_reg2_to_reg4(r);
newstat = _DtCm_deregister_callback_4_svc(newreg, svcrq);
stat = _DtCm_regstat4_to_regstat2(*newstat);
if (newreg!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Registration_4, (char*)newreg);
return(&stat);
}
/* PROC #17 */
extern Access_Status_2 *
_DtCm_rtable_set_access_2_svc(args, svcrq)
Access_Args_2 *args;
struct svc_req *svcrq;
{
static Access_Status_2 stat;
Access_Args_4 *newargs;
Access_Status_4 *newstat;
newargs = _DtCm_accargs2_to_accargs4(args);
newstat = _DtCm_rtable_set_access_4_svc(newargs, svcrq);
stat = _DtCm_accstat4_to_accstat2(*newstat);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Access_Args_4, (char*)newargs);
return(&stat);
}
/* PROC #18 */
extern Access_Args_2 *
_DtCm_rtable_get_access_2_svc(args, svcrq)
Access_Args_2 *args;
struct svc_req *svcrq;
{
static Access_Args_2 *res = NULL;
Access_Args_4 *newargs;
Access_Args_4 *newres;
if (res!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Access_Args_2, (char*)res);
newargs = _DtCm_accargs2_to_accargs4(args);
newres = _DtCm_rtable_get_access_4_svc(newargs, svcrq);
res = _DtCm_accargs4_to_accargs2(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Access_Args_4, (char*)newargs);
return(res);
}
void initrtable2(ph)
program_handle ph;
{
int ver = TABLEVERS_2;
ph->program_num = TABLEPROG;
ph->prog[TABLEVERS_2].vers = &tableprog_2_table[0];
ph->prog[TABLEVERS_2].nproc = sizeof(tableprog_2_table)/sizeof(tableprog_2_table[0]);
}

View File

@@ -0,0 +1,115 @@
/*******************************************************************************
**
** rtable2_tbl.i
**
** static char sccsid[] = "@(#)rtable2_tbl.i 1.1 94/09/05 Copyr 1991 Sun Microsystems, Inc.";
**
** $XConsortium: rtable2_tbl.i /main/3 1995/11/03 11:21:36 rswiston $
**
** RESTRICTED CONFIDENTIAL INFORMATION:
**
** The information in this document is subject to special
** restrictions in a confidential disclosure agreement between
** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
** document outside HP, IBM, Sun, USL, SCO, or Univel without
** Sun's specific written approval. This document and all copies
** and derivative works thereof must be returned or destroyed at
** Sun's request.
**
** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
**
*******************************************************************************/
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#define access_none_2 0x0 /* owner only */
#define access_read_2 0x1
#define access_write_2 0x2
#define access_delete_2 0x4
#define access_exec_2 0x8 /* execution permission is a hack! */
#define VOIDPID -1 /* pre-V3 tools do present pids */
struct rpcgen_table tableprog_2_table[] = {
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_ping_2_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_void, 0,
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_larger_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_smaller_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_range_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_abbreviated_lookup_range_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_insert_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_delete_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_delete_instance_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_change_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_change_instance_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_reminder_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Res_2, sizeof ( Table_Res_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_check_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Status_2, sizeof ( Table_Status_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_flush_table_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)_DtCm_xdr_Table_Status_2, sizeof ( Table_Status_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_size_2_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_2, sizeof ( Table_Args_2 ),
(xdrproc_t)xdr_int, sizeof ( int ),
(char *(*)())RPCGEN_ACTION(_DtCm_register_callback_2_svc),
(xdrproc_t)_DtCm_xdr_Registration_2, sizeof ( Registration_2 ),
(xdrproc_t)_DtCm_xdr_Registration_Status_2, sizeof ( Registration_Status_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_deregister_callback_2_svc),
(xdrproc_t)_DtCm_xdr_Registration_2, sizeof ( Registration_2 ),
(xdrproc_t)_DtCm_xdr_Registration_Status_2, sizeof ( Registration_Status_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_set_access_2_svc),
(xdrproc_t)_DtCm_xdr_Access_Args_2, sizeof ( Access_Args_2 ),
(xdrproc_t)_DtCm_xdr_Access_Status_2, sizeof ( Access_Status_2 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_get_access_2_svc),
(xdrproc_t)_DtCm_xdr_Access_Args_2, sizeof ( Access_Args_2 ),
(xdrproc_t)_DtCm_xdr_Access_Args_2, sizeof ( Access_Args_2 ),
};
int tableprog_2_nproc =
sizeof(tableprog_2_table)/sizeof(tableprog_2_table[0]);

View File

@@ -0,0 +1,441 @@
/* $XConsortium: rtable3.c /main/4 1995/11/09 12:51:59 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.
*/
/*
veneer layered on top of the real data structures for abstraction.
implements Version 3 in terms of Version 4 types
*/
#include <EUSCompat.h>
#include <stdio.h>
#include "rtable4.h"
#include "rtable3.h"
#include <sys/param.h>
#include <sys/time.h>
#include <rpc/rpc.h>
#include "rpcextras.h"
#include "convert3-4.h"
#include "convert4-3.h"
#include "rtable3_tbl.i"
/*************** V3 PROTOCOL IMPLEMENTATION PROCS *****************/
extern void *
_DtCm_rtable_ping_3_svc(args, svcrq)
void *args;
struct svc_req *svcrq;
{
char dummy;
return((void *)&dummy); /* for RPC reply */
}
/* PROC #1 */
extern Table_Res_3 *
_DtCm_rtable_lookup_3_svc (args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_lookup_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #2 */
extern Table_Res_3 *
_DtCm_rtable_lookup_next_larger_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_lookup_next_larger_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #3 */
extern Table_Res_3 *
_DtCm_rtable_lookup_next_smaller_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_lookup_next_smaller_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #4 */
extern Table_Res_3 *
_DtCm_rtable_lookup_range_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_lookup_range_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #5 */
extern Table_Res_3 *
_DtCm_rtable_abbreviated_lookup_range_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_abbreviated_lookup_range_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #6 */
extern Table_Res_3 *
_DtCm_rtable_insert_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_insert_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #7 */
extern Table_Res_3 *
_DtCm_rtable_delete_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tabledelargs3_to_tabledelargs4(args, do_all_4);
newres = _DtCm_rtable_delete_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #8 */
extern Table_Res_3 *
_DtCm_rtable_delete_instance_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tabledelargs3_to_tabledelargs4(args, do_one_4);
newres = _DtCm_rtable_delete_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #9 */
extern Table_Res_3 *
_DtCm_rtable_change_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_change_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #10 */
extern Table_Res_3 *
_DtCm_rtable_change_instance_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newargs->args.Args_4_u.apptid.option = do_one_4;
newres = _DtCm_rtable_change_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #11 */
extern Table_Res_3 *
_DtCm_rtable_lookup_next_reminder_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_lookup_next_reminder_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #12 */
extern Table_Status_3 *
_DtCm_rtable_check_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Status_3 res;
Table_Args_4 *newargs;
Table_Status_4 *newres;
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_check_4_svc(newargs, svcrq);
res = _DtCm_tablestat4_to_tablestat3(*newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(&res);
}
/* PROC #13 */
extern Table_Status_3 *
_DtCm_rtable_flush_table_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Status_3 res;
Table_Args_4 *newargs;
Table_Status_4 *newres;
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_flush_table_4_svc(newargs, svcrq);
res = _DtCm_tablestat4_to_tablestat3(*newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(&res);
}
/* PROC #14 */
extern int *
_DtCm_rtable_size_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static int size;
Table_Args_4 *newargs;
newargs = _DtCm_tableargs3_to_tableargs4(args);
size = (*(_DtCm_rtable_size_4_svc(newargs, svcrq)));
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(&size);
}
/* PROC #15 */
Registration_Status_3 *
_DtCm_register_callback_3_svc(r, svcrq)
Registration_3 *r;
struct svc_req *svcrq;
{
static Registration_Status_3 stat;
Registration_4 *newreg;
Registration_Status_4 *newstat;
newreg = _DtCm_reg3_to_reg4(r);
newstat = _DtCm_register_callback_4_svc(newreg, svcrq);
stat = _DtCm_regstat4_to_regstat3(*newstat);
if (newreg!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Registration_4, (char*)newreg);
return(&stat);
}
/* PROC #16 */
Registration_Status_3 *
_DtCm_deregister_callback_3_svc(r, svcrq)
Registration_3 *r;
struct svc_req *svcrq;
{
static Registration_Status_3 stat;
Registration_4 *newreg;
Registration_Status_4 *newstat;
newreg = _DtCm_reg3_to_reg4(r);
newstat = _DtCm_deregister_callback_4_svc(newreg, svcrq);
stat = _DtCm_regstat4_to_regstat3(*newstat);
if (newreg!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Registration_4, (char*)newreg);
return(&stat);
}
/* PROC #17 */
extern Access_Status_3 *
_DtCm_rtable_set_access_3_svc(args, svcrq)
Access_Args_3 *args;
struct svc_req *svcrq;
{
static Access_Status_3 stat;
Access_Args_4 *newargs;
Access_Status_4 *newstat;
newargs = _DtCm_accargs3_to_accargs4(args);
newstat = _DtCm_rtable_set_access_4_svc(newargs, svcrq);
stat = _DtCm_accstat4_to_accstat3(*newstat);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Access_Args_4, (char*)newargs);
return(&stat);
}
/* PROC #18 */
extern Access_Args_3 *
_DtCm_rtable_get_access_3_svc(args, svcrq)
Access_Args_3 *args;
struct svc_req *svcrq;
{
static Access_Args_3 *res = NULL;
Access_Args_4 *newargs;
Access_Args_4 *newres;
if (res!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Access_Args_3, (char*)res);
newargs = _DtCm_accargs3_to_accargs4(args);
newres = _DtCm_rtable_get_access_4_svc(newargs, svcrq);
res = _DtCm_accargs4_to_accargs3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Access_Args_4, (char*)newargs);
return(res);
}
/* PROC #19 */
extern Table_Res_3 *
_DtCm_rtable_abbreviated_lookup_key_range_3_svc(args, svcrq)
Table_Args_3 *args;
struct svc_req *svcrq;
{
static Table_Res_3 *res = NULL;
Table_Args_4 *newargs;
Table_Res_4 *newres;
if (res!=NULL) xdr_free ((xdrproc_t)_DtCm_xdr_Table_Res_3, (char*)res);
newargs = _DtCm_tableargs3_to_tableargs4(args);
newres = _DtCm_rtable_abbreviated_lookup_key_range_4_svc(newargs, svcrq);
res = _DtCm_tableres4_to_tableres3(newres);
if (newargs!=NULL) xdr_free((xdrproc_t)_DtCm_xdr_Table_Args_4, (char*)newargs);
return(res);
}
/* PROC #20 */
extern long *
_DtCm_rtable_gmtoff_3_svc(args, svcrq)
void *args;
struct svc_req *svcrq;
{
static long gmtoff;
gmtoff = (*(_DtCm_rtable_gmtoff_4_svc(NULL, svcrq)));
return(&gmtoff);
}
void initrtable3(ph)
program_handle ph;
{
ph->program_num = TABLEPROG;
ph->prog[TABLEVERS_3].vers = &tableprog_3_table[0];
ph->prog[TABLEVERS_3].nproc = sizeof(tableprog_3_table)/sizeof(tableprog_3_table[0]);
}

View File

@@ -0,0 +1,122 @@
/*******************************************************************************
**
** rtable3_tbl.i
**
** static char sccsid[] = "@(#)rtable3_tbl.i 1.1 94/09/05 Copyr 1991 Sun Microsystems, Inc.";
**
** $XConsortium: rtable3_tbl.i /main/3 1995/11/03 11:22:05 rswiston $
**
** RESTRICTED CONFIDENTIAL INFORMATION:
**
** The information in this document is subject to special
** restrictions in a confidential disclosure agreement between
** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
** document outside HP, IBM, Sun, USL, SCO, or Univel without
** Sun's specific written approval. This document and all copies
** and derivative works thereof must be returned or destroyed at
** Sun's request.
**
** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
**
*******************************************************************************/
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#define access_none_3 0x0 /* owner only */
#define access_read_3 0x1
#define access_write_3 0x2
#define access_delete_3 0x4
#define access_exec_3 0x8 /* execution permission is a hack! */
struct rpcgen_table tableprog_3_table[] = {
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_ping_3_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_void, 0,
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_larger_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_smaller_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_range_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_abbreviated_lookup_range_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_insert_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_delete_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_delete_instance_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_change_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_change_instance_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_reminder_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_check_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Status_3, sizeof ( Table_Status_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_flush_table_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Status_3, sizeof ( Table_Status_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_size_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)xdr_int, sizeof ( int ),
(char *(*)())RPCGEN_ACTION(_DtCm_register_callback_3_svc),
(xdrproc_t)_DtCm_xdr_Registration_3, sizeof ( Registration_3 ),
(xdrproc_t)_DtCm_xdr_Registration_Status_3, sizeof ( Registration_Status_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_deregister_callback_3_svc),
(xdrproc_t)_DtCm_xdr_Registration_3, sizeof ( Registration_3 ),
(xdrproc_t)_DtCm_xdr_Registration_Status_3, sizeof ( Registration_Status_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_set_access_3_svc),
(xdrproc_t)_DtCm_xdr_Access_Args_3, sizeof ( Access_Args_3 ),
(xdrproc_t)_DtCm_xdr_Access_Status_3, sizeof ( Access_Status_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_get_access_3_svc),
(xdrproc_t)_DtCm_xdr_Access_Args_3, sizeof ( Access_Args_3 ),
(xdrproc_t)_DtCm_xdr_Access_Args_3, sizeof ( Access_Args_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_abbreviated_lookup_key_range_3_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_3, sizeof ( Table_Args_3 ),
(xdrproc_t)_DtCm_xdr_Table_Res_3, sizeof ( Table_Res_3 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_gmtoff_3_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_long, sizeof ( long ),
};
int tableprog_3_nproc =
sizeof(tableprog_3_table)/sizeof(tableprog_3_table[0]);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
/*******************************************************************************
**
** rtable4_tbl.i
**
** static char sccsid[] = "@(#)rtable4_tbl.i 1.1 94/09/05 Copyr 1991 Sun Microsystems, Inc.";
**
** $XConsortium: rtable4_tbl.i /main/3 1995/11/03 11:22:53 rswiston $
**
** RESTRICTED CONFIDENTIAL INFORMATION:
**
** The information in this document is subject to special
** restrictions in a confidential disclosure agreement between
** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
** document outside HP, IBM, Sun, USL, SCO, or Univel without
** Sun's specific written approval. This document and all copies
** and derivative works thereof must be returned or destroyed at
** Sun's request.
**
** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
**
*******************************************************************************/
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#define access_none_4 0x0 /* owner only */
#define access_read_4 0x1
#define access_write_4 0x2
#define access_delete_4 0x4
#define access_exec_4 0x8 /* execution permission is a hack! */
#define WORLD "world" /* special user */
/*
* rtable_delete and rtable_change take over the functionality of
* rtable_delete_instance and rtable_change_instance repectively.
* rtable_delete_instance and rtable_change_instance are now dummy
* routines exist for backward compatibility purpose and return
* access_notsupported.
*/
struct rpcgen_table tableprog_4_table[] = {
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_ping_4_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_void, 0,
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_larger_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_smaller_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_range_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_abbreviated_lookup_range_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_insert_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_delete_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_delete_instance_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_change_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_change_instance_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_lookup_next_reminder_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_check_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Status_4, sizeof ( Table_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_flush_table_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Status_4, sizeof ( Table_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_size_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)xdr_int, sizeof ( int ),
(char *(*)())RPCGEN_ACTION(_DtCm_register_callback_4_svc),
(xdrproc_t)_DtCm_xdr_Registration_4, sizeof ( Registration_4 ),
(xdrproc_t)_DtCm_xdr_Registration_Status_4, sizeof ( Registration_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_deregister_callback_4_svc),
(xdrproc_t)_DtCm_xdr_Registration_4, sizeof ( Registration_4 ),
(xdrproc_t)_DtCm_xdr_Registration_Status_4, sizeof ( Registration_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_set_access_4_svc),
(xdrproc_t)_DtCm_xdr_Access_Args_4, sizeof ( Access_Args_4 ),
(xdrproc_t)_DtCm_xdr_Access_Status_4, sizeof ( Access_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_get_access_4_svc),
(xdrproc_t)_DtCm_xdr_Access_Args_4, sizeof ( Access_Args_4 ),
(xdrproc_t)_DtCm_xdr_Access_Args_4, sizeof ( Access_Args_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_abbreviated_lookup_key_range_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Args_4, sizeof ( Table_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Res_4, sizeof ( Table_Res_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_gmtoff_4_svc),
(xdrproc_t)xdr_void, 0,
(xdrproc_t)xdr_long, sizeof ( long ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_create_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Op_Args_4, sizeof ( Table_Op_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Status_4, sizeof ( Table_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_remove_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Op_Args_4, sizeof ( Table_Op_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Status_4, sizeof ( Table_Status_4 ),
(char *(*)())RPCGEN_ACTION(_DtCm_rtable_rename_4_svc),
(xdrproc_t)_DtCm_xdr_Table_Op_Args_4, sizeof ( Table_Op_Args_4 ),
(xdrproc_t)_DtCm_xdr_Table_Status_4, sizeof ( Table_Status_4 ),
};
int tableprog_4_nproc =
sizeof(tableprog_4_table)/sizeof(tableprog_4_table[0]);

View File

@@ -0,0 +1,744 @@
/* $TOG: svcmain.c /main/10 1998/04/06 13:13:49 mgreess $ */
/*
* (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 <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#ifdef SVR4
#ifndef _NETINET_IN_H
#include <netinet/in.h>
#endif /* _NETINET_IN_H */
#endif
#if defined(SunOS) || defined(USL) || defined(__uxp__)
#include <netconfig.h>
#include <netdir.h>
#include <sys/stropts.h>
#include <tiuser.h>
#endif /* SunOS || USL || __uxp__ */
#include <sys/param.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <rpc/rpc.h>
#include <sys/file.h>
#include <sys/signal.h>
#include <pwd.h>
#include <grp.h>
#include "rpcextras.h"
#include "log.h"
#include "cmscalendar.h"
#include "repeat.h"
#include "lutil.h"
#include "cmsdata.h"
#ifndef S_IRWXU
#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)
#endif
#ifndef S_IRWXG
#define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)
#endif
#ifndef S_IRWXO
#define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)
#endif
#define S_MASK (S_INPUT|S_HIPRI|S_ERROR|S_HANGUP)
int debug;
static int standalone; /* default is 0 */
static int received_sighup = 0; /* 1 means we get SIGHUP */
static int rpc_in_process = 0; /* 1 means processing client request */
static int garbage_collection_time = 240; /* in min; default time is 4:00am */
char *pgname;
uid_t daemon_uid;
gid_t daemon_gid;
/*
* get garbage collection time
* the given string should be in the format hhmm
* where hh is 0 - 23 and mm is 00 - 59
*/
static int
_GetGtime(char *timestr)
{
int hour, minute, len, i;
if (timestr == NULL)
goto error;
if ((len = strlen(timestr)) > 4)
goto error;
for (i = 0; i < len; i++) {
if (timestr[i] < '0' || timestr[i] > '9')
goto error;
}
minute = atoi(&timestr[len - 2]);
timestr[len - 2] = NULL;
hour = atoi(timestr);
if (hour > 23 || minute > 59)
goto error;
garbage_collection_time = hour * 60 + minute;
return (0);
error:
fprintf(stderr, "The time specified is invalid.\n");
return (-1);
}
static void
parse_args(int argc, char **argv)
{
int opt;
if (pgname = strrchr (argv[0], '/'))
pgname++;
else
pgname = argv[0];
while ((opt = getopt (argc, argv, "dsg:")) != -1)
{
switch (opt)
{
case 'd':
debug = 1;
break;
case 's':
standalone = 1;
break;
case 'g':
if (_GetGtime(optarg))
goto error;
break;
case '?':
goto error;
}
}
if (optind == argc)
return;
#if defined(_aix)
/*
* rpc.cmsd gets started by the inetd.
* On AIX inetd requires that two arguments be supplied to the RPC
* programs as follows (from the inetd.conf man page):
*
* ServerArgs Specifies the command line arguments that the
* inetd daemon should use to execute the server. The maximum number
* of arguments is five. The first argument specifies the name of the
* server used. If the SocketType parameter is sunrpc_tcp or
* sunrpc_udp, * the second argument specifies the program name and
* the third argument specifies the version of the program. For
* services that the inetd daemon provides internally, this field
* should be empty.
*/
else if (optind == 1 && argc >= 3)
{
int i,j;
char **argv_r;
if (argc == 3)
return;
argv_r = (char **) malloc(argc * sizeof(char *));
argv_r[0] = argv[0];
for (i=optind+2, j=1; i<argc; i++,j++)
argv_r[j] = argv[i];
parse_args(argc-2, argv_r);
free((void *) argv_r);
return;
}
#endif
error:
fprintf (stderr, "Usage: %s [-d] [-s] [-g hhmm]\n", pgname);
exit (-1);
}
static void
init_dir()
{
char *dir = _DtCMS_DEFAULT_DIR;
char msgbuf[BUFSIZ];
int create_dir;
struct stat info;
mode_t mode;
if (geteuid() != 0)
{
fprintf (stderr,
"%s: must be run in super-user mode! Exited.\n",
pgname);
exit (-1);
}
create_dir = 0;
if (stat(dir, &info))
{
/* if directory does not exist, create the directory */
if ((errno != ENOENT) || mkdir(dir, S_IRWXU|S_IRWXG|S_IRWXO))
{
if (errno == ENOENT)
sprintf(msgbuf, "%s: cannot create %s.\n%s: %s",
pgname, dir, pgname, "System error");
else
sprintf(msgbuf, "%s: cannot access %s.\n%s: %s",
pgname, dir, pgname, "System error");
perror (msgbuf);
exit (-1);
}
create_dir = 1;
}
/* if dir is just created, we need to do chmod and chown.
* Otherwise, only do chmod and/or chown if permssion and/or
* ownership is wrong.
*/
mode = S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO;
if (create_dir || info.st_mode != (mode | S_IFDIR)) {
/* set directory permission to be "rwxrwsrwt" */
if (chmod(dir, mode)) {
sprintf(msgbuf, "%s: Permission on %s%s\n%s%s\n%s%s",
pgname, dir,
" is wrong but cannot be corrected.", pgname,
": This might happen if you are mounting the directory.",
pgname, ": System error");
perror(msgbuf);
if (create_dir)
rmdir(dir);
exit(-1);
}
}
if (create_dir || info.st_uid!=daemon_uid || info.st_gid!=daemon_gid) {
/* set directory ownership to: owner = 1, group = 1 */
if (chown(dir, daemon_uid, daemon_gid)) {
sprintf(msgbuf, "%s: Ownership on %s%s\n%s%s\n%s%s",
pgname, dir,
" is wrong but cannot be corrected.", pgname,
": This might happen if you are mounting the directory.",
pgname, ": System error");
perror(msgbuf);
if (create_dir)
rmdir(dir);
exit(-1);
}
}
/* Change current directory, so core file can be dumped. */
chdir (dir);
}
/*
* send a SIGHUP signal to the rpc.cmsd that is already running
*/
static void
send_hup()
{
FILE *fp = NULL;
char buf[BUFSIZ];
pid_t pid, mypid = getpid();
extern FILE *popen(const char *, const char *);
extern int pclose(FILE *);
sprintf(buf, "ps -e|grep rpc.cmsd|grep -v grep");
if ((fp = popen(buf, "r")) == NULL) {
if (debug)
fprintf(stderr, "rpc.cmsd: popen failed\n");
} else {
while (fgets(buf, sizeof(buf), fp) != NULL) {
if ((pid = atol(buf)) != mypid) {
if (kill(pid, SIGHUP))
perror("rpc.cmsd: failed to send SIGHUP");
if (debug)
fprintf(stderr, "rpc.cmsd: %s %ld\n",
"sent SIGHUP to", (long)pid);
}
}
pclose(fp);
}
}
/*
* We only allow one rpc.cmsd to run on each machine.
*/
static int
lock_it()
{
char *dir = _DtCMS_DEFAULT_DIR;
char buff [MAXPATHLEN];
int error;
int fd;
#ifdef SVR4
struct flock locker;
locker.l_type = F_WRLCK;
locker.l_whence = 0;
locker.l_start = 0;
locker.l_len = 0;
#endif /* SVR4 */
strcpy (buff, dir);
strcat (buff, "/.lock.");
/*
* /var/spool might be mounted. Use .lock.hostname to
* prevent more than one cms running in each host.
*/
strcat(buff, _DtCmGetLocalHost());
fd = open(buff, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
if (fd < 0)
{
perror (buff);
exit (-1);
}
/*
* Note, we have to use flock() instead of lockf() because cms process
* is run in each host.
*/
#ifdef SVR4
if (fcntl (fd, F_SETLK, &locker) != 0)
#else
if (flock (fd, LOCK_EX|LOCK_NB) != 0)
#endif /* SVR4 */
{
error = errno;
close(fd);
if (error != EWOULDBLOCK && error != EACCES) {
perror ("rpc.cmsd: failed to lock lockfile");
fprintf(stderr, "error = %d\n", error);
exit (-1);
} else {
if (debug)
fprintf(stderr, "rpc.cmsd: %s\n",
"lock_it failed due to another process");
/* cms has been running.... */
return(error);
}
}
return (0);
}
static void
program(struct svc_req *rqstp, register SVCXPRT *transp)
{
char *result;
char *argument = NULL;
program_handle ph = getph();
struct rpcgen_table *proc;
/* set rpc_in_process so that sighup handler won't exit right away */
rpc_in_process = 1;
/* first do some bounds checking: */
if (rqstp->rq_vers >= ph->nvers) {
svcerr_noproc(transp);
goto done;
}
if (ph->prog[rqstp->rq_vers].nproc == 0) {
svcerr_noproc(transp);
goto done;
}
if (rqstp->rq_proc >= ph->prog[rqstp->rq_vers].nproc) {
svcerr_noproc(transp);
goto done;
}
if (rqstp->rq_proc == NULLPROC) {
if (debug) fprintf(stderr, "rpc.cmsd: ping\n");
(void)svc_sendreply(transp, (xdrproc_t)xdr_void, (caddr_t)NULL);
goto done;
}
/* assert - the program number, version and proc numbers are valid */
proc = &(ph->prog[rqstp->rq_vers].vers[rqstp->rq_proc]);
argument = (char*)calloc(proc->len_arg, sizeof(char));
if (!svc_getargs(transp, proc->xdr_arg, argument)) {
svcerr_decode(transp);
goto done;
}
result = (*proc->proc)(argument, rqstp);
if (result != NULL && !svc_sendreply(transp, proc->xdr_res, result)) {
svcerr_systemerr(transp);
}
if (!svc_freeargs(transp, proc->xdr_arg, argument)) {
(void)fprintf(stderr, "unable to free arguments");
exit(1);
}
free(argument);
done:
rpc_in_process = 0;
/* exit if we have received the SIGHUP signal */
if (received_sighup == 1) {
if (debug)
fprintf(stderr, "rpc.cmsd: received SIGHUP, %s",
"exiting after finished processing\n");
exit(0);
}
}
/*
* Signal handler for SIGHUP.
* If we are in the middle of processing a client request,
* finish processing before we exit.
*/
static void
sighup_handler(int sig_num)
{
if (debug)
fprintf(stderr, "rpc.cmsd: sighup received\n");
if (rpc_in_process == 0) {
if (debug)
fprintf(stderr, "rpc.cmsd: exit from sighup_handler\n");
exit(0);
} else {
if (debug)
fprintf(stderr, "rpc.cmsd: set received_sighup to 1\n");
received_sighup = 1;
}
}
/*
* garbage_collection_time (in min) is the time to do garbage collection
* each day
* This routine returns the difference between the first garbage collection
* time and now so that the calling routine can set the alarm.
*/
static int
_GetFirstGarbageCollectionTime()
{
int n=0, midnight=0, gtime=0;
n = time(0);
/* try today first */
midnight = next_ndays(n, 0);
gtime = next_nmins(midnight, garbage_collection_time);
if (gtime < n) {
/* the first garbage collection will be done tomorrow */
midnight = next_ndays(n, 1);
gtime = next_nmins(midnight, garbage_collection_time);
}
return (gtime - n);
}
static void
init_alarm()
{
int next;
extern void garbage_collect();
extern void debug_switch();
#if defined(SVR4) && !defined(linux)
extern void (*sigset(int, void (*)(int)))(int);
sigset(SIGUSR1, garbage_collect);
sigset(SIGALRM, garbage_collect);
sigset(SIGUSR2, debug_switch);
#else
signal(SIGUSR1, garbage_collect);
signal(SIGALRM, garbage_collect);
signal(SIGUSR2, debug_switch);
#endif /* SVR4 */
next = _GetFirstGarbageCollectionTime();
alarm((unsigned) next);
}
main(int argc, char **argv)
{
u_long version;
program_handle ph = newph();
struct passwd *pw;
struct group *gr;
struct rlimit rl;
struct sockaddr_in saddr;
int asize = sizeof (saddr);
SVCXPRT *tcp_transp = (SVCXPRT *)-1;
SVCXPRT *udp_transp = (SVCXPRT *)-1;
int fd, error;
#if defined(SunOS) || defined(USL) || defined(__uxp__)
struct netconfig *nconf_udp;
struct netconfig *nconf_tcp;
struct t_info info;
#if !defined(USL) || (defined(USL) && (OSMAJORVERSION > 1))
char mname[FMNAMESZ+1];
#endif
#endif /* SunOS || USL */
pw = (struct passwd *)getpwnam("daemon");
gr = (struct group *)getgrnam("daemon");
if (pw != NULL)
daemon_uid = pw->pw_uid;
else
daemon_uid = 1;
if (gr != NULL)
daemon_gid = gr->gr_gid;
else
daemon_gid = 1;
parse_args(argc, argv);
/* check to see if we are started by inetd */
if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {
standalone = 0;
#if defined(SunOS) || defined(USL) || defined(__uxp__)
#if !defined(USL) || (defined(USL) && (OSMAJORVERSION > 1))
/* we need a TLI endpoint rather than a socket */
if (ioctl(0, I_LOOK, mname) != 0) {
perror("rpc.cmsd: ioctl failed to get module name");
exit(1);
}
if (strcmp(mname, "sockmod") == 0) {
/* Change socket fd to TLI fd */
if (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, "timod")) {
perror("rpc.cmsd: ioctl I_POP/I_PUSH failed");
exit(1);
}
} else if (strcmp(mname, "timod") != 0) {
fprintf(stderr, "rpc.cmsd: fd 0 is not timod\n");
exit(1);
}
#else /* !USL || (USL && OSMAJORVERSION > 1) */
if (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, "timod")) {
perror("rpc.cmsd: ioctl I_POP/I_PUSH failed");
exit(1);
}
#endif /* !USL || (USL && OSMAJORVERSION > 1) */
} else if (t_getinfo(0, &info) == 0) {
standalone = 0;
#endif /* SunOS || USL */
} else
standalone = 1;
/*
* if it is started by inetd, make stderr to be
* output to console.
*/
if (!standalone) {
if ((fd = open ("/dev/console", O_WRONLY)) >= 0) {
if (fd != 2) {
dup2(fd, 2);
close (fd);
}
}
}
/* Set up private directory and switch euid/egid to daemon. */
umask (S_IWOTH);
init_dir();
/* Don't allow multiple cms processes running in the same host. */
if ((error = lock_it()) != 0 && !standalone) {
/* we are invoked by inetd but another rpc.cmsd
* is alreay running, so send SIGHUP to it
*/
send_hup();
/* try to lock it again */
if (lock_it() != 0) {
if (debug)
fprintf(stderr, "cm: rpc.cmsd is still running\n");
exit(0);
}
} else if (error != 0) {
fprintf(stderr, "rpc.cmsd: rpc.cmsd is already running.\n");
exit(0);
}
/* use signal because we only need it once */
signal(SIGHUP, sighup_handler);
#if defined(SunOS) || defined(USL) || defined(__uxp__)
/* raise the soft limit of number of file descriptor */
/* this is to prevent the backend from running out of open file des */
getrlimit(RLIMIT_NOFILE, &rl);
rl.rlim_cur = (rl.rlim_max <= 256) ? rl.rlim_max : 256;
setrlimit(RLIMIT_NOFILE, &rl);
#endif
#if defined(SunOS) || defined(USL) || defined(__uxp__)
nconf_udp = getnetconfigent("udp");
nconf_tcp = getnetconfigent("tcp");
for (version = 0; version < ph->nvers; version++) {
/* don't register unsupported versions: */
if (ph->prog[version].nproc == 0) continue;
if (standalone) {
rpcb_unset(ph->program_num, version, NULL);
if (debug)
fprintf(stderr,
"rpc.cmsd: rpcb_unset for version %ld\n",
version);
}
/* brought up by inetd, use fd 0 which must be a TLI fd */
if (udp_transp == (SVCXPRT *)-1) {
udp_transp = svc_tli_create(standalone ? RPC_ANYFD : 0,
nconf_udp, (struct t_bind*) NULL, 0, 0);
if (udp_transp == NULL) {
t_error("rtable_main.c: svc_tli_create(udp)");
exit(2);
}
}
if (svc_reg(udp_transp, ph->program_num, version, program,
standalone ? nconf_udp : NULL) == 0) {
t_error("rtable_main.c: svc_reg");
exit(3);
}
/* Set up tcp for calls that potentially return */
/* large amount of data. This transport is not */
/* registered with inetd so need to register it */
/* with rpcbind ourselves. */
rpcb_unset(ph->program_num, version, nconf_tcp);
if (tcp_transp == (SVCXPRT *)-1) {
tcp_transp = svc_tli_create(RPC_ANYFD, nconf_tcp,
(struct t_bind *)NULL, 0, 0);
if (tcp_transp == NULL) {
t_error("rtable_main.c: svc_til_create(tcp)");
exit(2);
}
}
if (svc_reg(tcp_transp, ph->program_num, version, program,
nconf_tcp) == 0) {
t_error("rtable_main.c: svc_reg(tcp)");
exit(3);
}
}/*for*/
if (nconf_udp)
freenetconfigent(nconf_udp);
if (nconf_tcp)
freenetconfigent(nconf_tcp);
#else
for (version = 0; version < ph->nvers; version++) {
/* don't register unsupported versions: */
if (ph->prog[version].nproc == 0) continue;
#ifndef HPUX
if (standalone)
#endif
(void) pmap_unset(ph->program_num, version);
if (udp_transp == (SVCXPRT *)-1) {
udp_transp = svcudp_create(standalone ? RPC_ANYSOCK : 0
#if defined(_AIX) || defined(hpV4) || defined(__osf__) || defined(linux)
);
#else
,0,0);
#endif
if (udp_transp == NULL) {
(void)fprintf(stderr,
"rtable_main.c: cannot create udp service.\n");
exit(1);
}
}
#ifndef HPUX
if (!svc_register(udp_transp, ph->program_num, version, program,
standalone ? IPPROTO_UDP : 0)) {
#else
if (!svc_register(udp_transp, ph->program_num, version, program,
IPPROTO_UDP)) {
#endif
(void)fprintf(stderr, "rtable_main.c: unable to register");
exit(1);
}
/* Set up tcp for calls that potentially return */
/* large amount of data. This transport is not */
/* registered with inetd so need to register it */
/* with rpcbind ourselves. */
if (tcp_transp == (SVCXPRT *)-1) {
tcp_transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (tcp_transp == NULL) {
(void)fprintf(stderr,
"rtable_main.c: cannot create tcp service.\n");
exit(1);
}
}
if (!svc_register(tcp_transp, ph->program_num, version, program,
IPPROTO_TCP)) {
(void)fprintf(stderr, "rtable_main.c: unable to register(tcp)");
exit(1);
}
}
#endif /* SunOS || USL */
#ifndef AIX
#ifdef HPUX
setgid (daemon_gid);
setuid (daemon_uid);
#else
setegid (daemon_gid);
seteuid (daemon_uid);
#endif /* HPUX */
#endif /* AIX */
init_time();
init_alarm();
_DtCm_init_hash();
svc_run();
(void)fprintf(stderr, "rpc.cmsd: svc_run returned\n");
return(1);
}

View File

@@ -0,0 +1,652 @@
/* $XConsortium: tree.c /main/4 1995/11/09 12:53:11 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.
*/
/* 2-3-4 tree, a.k.a. red-black tree, implementation */
#include <EUSCompat.h>
#include <sys/param.h>
#include <unistd.h>
#include <stdlib.h>
#include "tree.h"
extern int debug;
typedef struct {
int size; /* used in insert and size */
int count; /* used in checktree only */
Rb_Status status; /* used in checktree and insert */
caddr_t data; /* used in lookups only */
Tree_node *i; /* used in insert only */
caddr_t key; /* used in insert only */
Tree_node *d; /* used in delete only */
Tree_node *y; /* dummy that is at both links of z */
Tree_node *z; /* dummy used as child of leaf nodes */
Rb_tree *tree; /* back link to parent tree */
_DtCmsGetKeyProc get;
_DtCmsEnumerateProc enumerate;
_DtCmsCompareProc compare;
} Private;
typedef void (*Action_proc)
(/* Private *private; Tree_node *y, *z, *root */);
static Tree_node *
balance(Tree_node *gg, Tree_node *g, Tree_node *f, Tree_node *x)
{
Tree_node *t;
Color tc;
if (gg == NULL || g == NULL) exit (-1);
if (f == g->llink) {
if (x == f->rlink) {
f->rlink = x->llink;
x->llink = f;
t = f;
f = x;
x = t;
}
}
else {
if (x == f->llink) {
f->llink = x->rlink;
x->rlink = f;
t = f;
f = x;
x = t;
}
}
if (x == f->llink) {
g->llink = f->rlink;
f->rlink = g;
}
else {
g->rlink = f->llink;
f->llink = g;
}
if (g == gg->rlink) gg->rlink = f;
else gg->llink = f;
tc = g->color;
g->color = f->color;
f->color = tc;
return(f);
}
static void
doit(Rb_tree *tree, Action_proc proc)
{
Private *private;
Tree_node *root;
if (tree==NULL) return;
private = (Private *) tree->private;
root = tree->root;
if (root == NULL || root->llink != NULL) {
private->status = rb_badtable;
return;
}
proc(private, private->y, private->z, root);
}
extern Rb_tree *
rb_create (_DtCmsGetKeyProc get, _DtCmsCompareProc compare)
{
Private *p;
Tree_node *root, *y, *z;
Rb_tree *tree;
p = (Private *) calloc (1, sizeof(Private));
p->size = 0;
p->count = 0;
p->status = rb_ok;
p->data = NULL;
p->i = NULL;
p->key = 0;
p->d = NULL;
p->y = (Tree_node *) calloc (1, sizeof(Tree_node));
p->z = (Tree_node *) calloc (1, sizeof(Tree_node));
p->get = get;
p->enumerate = NULL;
p->compare = compare;
root = (Tree_node *) calloc (1, sizeof(Tree_node));
y = p->y;
z = p->z;
tree = (Rb_tree *) calloc (1, sizeof(Rb_tree));
tree->root = root;
tree->private = (caddr_t) p;
p->tree = tree; /* link back so callbacks can access */
root->color = black;
root->llink = NULL;
root->rlink = z;
y->color = red;
y->llink = y->rlink = NULL;
z->color = black;
z->llink = z->rlink = y;
return(tree);
}
extern void
rb_destroy(Rb_tree *tree, _DtCmsEnumerateProc destroy)
{
Private *p = NULL;
caddr_t data = NULL;
Tree_node *node = NULL;
caddr_t key;
/* NOTE:there is a client data field
associated with the tree struct.
It is up to the client to destroy
these. */
if (tree==NULL) return;
p = (Private *) tree->private;
data = rb_lookup_smallest(tree);
/* enumerate tree, destroying data */
while(data != NULL) {
key = p->get(data);
node = rb_delete(tree, key);
if (destroy)
destroy(data);
free(node);
data = rb_lookup_next_larger(tree, key);
}
/* destroy the private internal struct */
free(p->y);
free(p->z);
free(p);
/* destroy the root node */
free(tree->root);
/* destroy the tree */
free(tree);
}
/* ARGSUSED */
static void
size_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
/* dummy proc for monitor */
}
extern int
rb_size(Rb_tree *tree)
{
Private *p;
if (tree==NULL) return(0);
p = (Private *) tree->private;
if (tree != NULL) {
doit(tree, size_callback);
return(p->size);
}
else return(0);
}
/* ARGSUSED */
static void
insert_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
Tree_node *x=NULL, *gg=NULL, *g=NULL, *f=NULL;
_DtCmsComparisonResult c = _DtCmsIsGreater;
f = root;
x = f->rlink;
for (;;) {
if (x->llink->color == red && x->rlink->color == red) {
if (x == z) {
if (c == _DtCmsIsEqual) {
private->status = rb_duplicate;
root->rlink->color = black;
return;
}
x = private->i;
x->llink = z;
x->rlink = z;
if (c == _DtCmsIsLess) f->llink = x; else f->rlink = x;
c = _DtCmsIsEqual;
private->size++;
}
x->llink->color = black;
x->rlink->color = black;
x->color = red;
if (f->color == red) {
g = balance (gg, g, f, x);
x = g;
}
}
if (c == _DtCmsIsEqual) break;
gg = g; g = f; f = x;
c = private->compare (private->key, x->data);
if (c==_DtCmsIsEqual) {
private->status=rb_duplicate;
root->rlink->color=black;
return;
}
x = (c == _DtCmsIsLess) ? x->llink : x-> rlink;
}
root->rlink->color = black;
}
extern Rb_Status
rb_insert_node(Rb_tree *tree, Tree_node *node, caddr_t key)
{
Private *private;
if (tree==NULL) return(rb_notable);
private = (Private *) tree->private;
private->status = rb_ok;
private->i = node;
private->key = key;
doit (tree, insert_callback);
return (private->status);
}
extern Rb_Status
rb_insert(Rb_tree *tree, caddr_t data, caddr_t key)
{
Tree_node *node;
if (tree==NULL) return(rb_notable);
node = (Tree_node *)calloc(1, sizeof(Tree_node));
node->data = data;
return(rb_insert_node(tree, node, key));
}
static void
delete_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
Tree_node *f, *result, *parent;
Tree_node *x, *g, *b;
_DtCmsComparisonResult c;
f = root;
x = f->rlink;
result = NULL;
if (x == z) return;
y->color = black;
if (x->llink->color == black && x->rlink->color == black)
x->color = red;
c = private->compare(private->key, x->data);
if (c == _DtCmsIsEqual) {
result = x;
parent = f;
}
for (;;) {
g = f;
f = x;
if (c == _DtCmsIsLess) {
b = x->rlink;
x = x->llink;
}
else {
b = x->llink;
x = x->rlink;
}
if (x != z) {
c = private->compare(private->key, x->data);
if (c == _DtCmsIsEqual) {
result = x;
parent = f;
}
}
if (x->color == red || x->llink->color == red ||
x->rlink->color == red) continue;
if (b->color == red) {
if (b == f->llink) {
f->llink = b->rlink;
b->rlink = f;
}
else {
f->rlink = b->llink;
b->llink = f;
}
f->color = red;
b->color = black;
if (f == g->llink) g->llink = b;
else g->rlink = b;
x = b;
c = private->compare(private->key, x->data);
continue;
}
if (x == z) break;
x->color = red;
if (b->llink->color == red) {
b->llink->color = black;
x = balance (g, f, b, b->llink);
c = private->compare(private->key, x->data);
continue;
}
if (b->rlink->color == red) {
b->rlink->color = black;
x = balance(g, f, b, b->rlink);
c = private->compare(private->key, x->data);
continue;
}
f->color = black;
b->color = red;
} /* end for-loop */
root->rlink->color = black;
z->color = black;
y->color = red;
if (result != NULL) {
if (g->llink == f) g->llink = z;
else g->rlink = z;
if (f != result) {
if (parent->llink == result) parent->llink = f;
else parent->rlink = f;
f->llink = result->llink;
f->rlink = result->rlink;
f->color = result->color;
}
private->size--;
}
private->d = result;
}
extern Tree_node *
rb_delete(Rb_tree *tree, caddr_t key)
{
Private *p;
if (tree==NULL) return((Tree_node *)NULL);
p = (Private *) tree->private;
p->key = key;
p->d = NULL; /* in case the key is not found */
doit (tree, delete_callback);
return(p->d);
}
/* ARGSUSED */
static void
lookup_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
_DtCmsComparisonResult c;
Tree_node *eq = root->rlink;
for (;;) {
if (eq == z) return;
c = private->compare(private->key, eq->data);
switch(c) {
case _DtCmsIsEqual:
goto bye;
case _DtCmsIsLess:
eq = eq->llink;
break;
case _DtCmsIsGreater:
eq = eq->rlink;
break;
default:
break;
}
}
bye: private->data = eq->data;
}
extern caddr_t
rb_lookup(Rb_tree *tree, caddr_t key)
{
Private *private;
if (tree==NULL) return((caddr_t)NULL);
private = (Private *)tree->private;
private->key = key;
private->data = NULL; /* might have been previously used */
doit (tree, lookup_callback);
return (private->data);
}
/* ARGSUSED */
static void
lookup_smallest_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
Tree_node *smallest = root->rlink;
if (smallest == z) return;
while (smallest->llink != z) {
smallest = smallest->llink;
}
private->data = smallest->data;
}
extern caddr_t
rb_lookup_smallest(Rb_tree *tree)
{
Private *private;
if (tree==NULL) return((caddr_t)NULL);
private = (Private *)tree->private;
private->data = NULL; /* might have been previously used */
doit (tree, lookup_smallest_callback);
return (private->data);
}
/* ARGSUSED */
static void
next_larger_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
Tree_node *larger = NULL;
Tree_node *x = root->rlink;
while (x != z) {
if (private->compare (private->key, x->data) == _DtCmsIsLess) {
larger = x;
x = x->llink;
}
else x= x->rlink;
}
if (larger != NULL) private->data = larger->data;
}
extern caddr_t
rb_lookup_next_larger(Rb_tree *tree, caddr_t key)
{
Private *private;
if (tree==NULL) return((caddr_t)NULL);
private = (Private *) tree->private;
private->key = key;
private->data = NULL; /* might have been previously used */
doit (tree, next_larger_callback);
return(private->data);
}
/* ARGSUSED */
static void
lookup_largest_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
Tree_node *largest = root->rlink;
if (largest == z) return;
while (largest->rlink != z) {
largest = largest->rlink;
}
private->data = largest->data;
}
extern caddr_t
rb_lookup_largest(Rb_tree *tree)
{
Private *private;
if (tree==NULL) return((caddr_t)NULL);
private = (Private *) tree->private;
private->data = NULL; /* might have been previously used */
doit (tree, lookup_largest_callback);
return (private->data);
}
/* ARGSUSED */
static void
next_smaller_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
Tree_node *smaller = NULL;
Tree_node *x = root->rlink;
while (x != z) {
if (private->compare(private->key, x->data) == _DtCmsIsGreater) {
smaller = x;
x = x->rlink;
}
else x = x->llink;
}
if (smaller != NULL) private->data = smaller->data;
}
extern caddr_t
rb_lookup_next_smaller(Rb_tree *tree, caddr_t key)
{
Private *private;
if (tree==NULL) return((caddr_t)NULL);
private = (Private *) tree->private;
private->key = key;
private->data = NULL; /* might have been previously used */
doit (tree, next_smaller_callback);
return(private->data);
}
typedef enum {up, down} Direction;
static boolean_t
visit_subtree(Tree_node *node, Private *p, Tree_node *z, Direction dir)
{
Tree_node *link;
link = (dir == up) ? node->llink : node->rlink;
if (link != z && visit_subtree(link, p, z, dir)) return(B_TRUE);
if (p->enumerate((caddr_t)node, node->data)) return(B_TRUE);
link = (dir == up) ? node->rlink : node->llink;
if (link != z) return(visit_subtree(link, p, z, dir));
else return(B_FALSE);
}
/* ARGSUSED */
static boolean_t
enumerate_up_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
if (root == NULL || root->rlink == z) return (B_FALSE);
return (visit_subtree(root->rlink, private, z, up));
}
extern Rb_Status
rb_enumerate_up(Rb_tree *tree, _DtCmsEnumerateProc proc)
{
Private *private;
if (tree==NULL) return (rb_badtable);
private = (Private *) tree->private;
private->enumerate = proc;
if (tree->root == NULL || tree->root->llink != NULL)
return rb_badtable;
if (enumerate_up_callback(private, private->y, private->z, tree->root))
return (rb_failed);
else
return (rb_ok);
}
/* ARGSUSED */
static void
enumerate_down_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
if (root == NULL || root->rlink == z) return;
(void) visit_subtree(root->rlink, private, z, down);
}
extern void
rb_enumerate_down(Rb_tree *tree, _DtCmsEnumerateProc proc)
{
Private *private;
if (tree==NULL) return;
private = (Private *) tree->private;
private->enumerate = proc;
doit (tree, enumerate_down_callback);
}
/* --------------------DEBUGGING-------------------------*/
static int
assert(int p)
{
return(p);
}
typedef struct {caddr_t max; int i; boolean_t bool;} Rec;
static void
check1(Tree_node *x, caddr_t max, Tree_node *z, Rec *rec, Private *private)
{
int dl, dr;
boolean_t redchild;
Rec localrec; Rec *localp = &localrec;
if (x == z) {
rec->max = max;
rec->i = 0;
rec->bool = B_FALSE;
return;
}
check1(x->llink, max, z, localp, private);
if (private->status == rb_badtable) return;
max = localp->max;
dl = localp->i;
redchild = localp->bool;
if (!assert (!(redchild && (x->color == red)))) {
private->status = rb_badtable;
return;
}
if (!assert (private->compare(max, x->data) ==
(private->count == 0 ? _DtCmsIsEqual : _DtCmsIsLess))) {
private->status = rb_badtable;
return;
}
private->count++;
check1(x->rlink, private->get(x->data), z, localp, private);
if (private->status == rb_badtable) return;
max = localp->max;
dr = localp->i;
redchild = localp->bool;
if (!assert (!(redchild && (x->color == red)))) {
private->status = rb_badtable;
return;
}
if (!assert (dl == dr)) {
private->status = rb_badtable;
return;
}
rec->max = max;
rec->i = dl + ((x->color == black) ? 1 : 0);
rec->bool = ((x->color == red) ? B_TRUE : B_FALSE);
}
static void
check_tree_callback(Private *private, Tree_node *y, Tree_node *z, Tree_node *root)
{
if (!assert (z->llink == y)) {
private->status = rb_badtable;
return;
}
if (!assert (z->rlink == y)) {
private->status = rb_badtable;
return;
}
if (root->rlink != z) {
Rec localrec;
Rec *localp = &localrec;
Tree_node *smallest = root->rlink;
while (smallest->llink != z) {
smallest = smallest->llink;
}
check1(root->rlink, private->get(smallest->data), z, localp, private);
if (private->status == rb_badtable) return;
}
}
extern Rb_Status
rb_check_tree(Rb_tree *tree)
{
Private *p;
if (tree==NULL) return(rb_notable);
p = (Private *) tree->private;
p->status = rb_ok;
p->count = 0;
doit (tree, check_tree_callback);
return(p->status);
}

View File

@@ -0,0 +1,61 @@
/* $XConsortium: tree.h /main/4 1995/11/09 12:53:31 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.
*/
#ifndef _TREE_H
#define _TREE_H
#include "ansi_c.h"
#include "data.h"
/*
** 2-3-4 tree, a.k.a. red-black tree
*/
typedef enum {red=0, black=1} Color;
typedef struct node {
struct node *llink;
struct node *rlink;
Color color;
caddr_t data;
} Tree_node;
typedef struct {
Tree_node *root;
caddr_t private; /* for internal tool state */
} Rb_tree;
extern Rb_tree* rb_create P((_DtCmsGetKeyProc, _DtCmsCompareProc));
extern void rb_destroy P((Rb_tree*, _DtCmsEnumerateProc));
extern int rb_size P((Rb_tree*t));
extern Rb_Status rb_insert P((Rb_tree*, caddr_t data, caddr_t key));
extern Rb_Status rb_insert_node P((Rb_tree*, Tree_node*, caddr_t key));
extern Tree_node * rb_delete P((Rb_tree*, caddr_t key));
extern caddr_t rb_lookup P((Rb_tree*, caddr_t key));
extern caddr_t rb_lookup_next_larger P((Rb_tree*, caddr_t key));
extern caddr_t rb_lookup_next_smaller P((Rb_tree*, caddr_t key));
extern caddr_t rb_lookup_smallest P((Rb_tree*));
extern caddr_t rb_lookup_largest P((Rb_tree*));
extern Rb_Status rb_enumerate_up P((Rb_tree*, _DtCmsEnumerateProc));
extern void rb_enumerate_down P((Rb_tree*, _DtCmsEnumerateProc));
extern Rb_Status rb_check_tree P((Rb_tree *));
#endif

View File

@@ -0,0 +1,589 @@
/* $XConsortium: update.c /main/4 1995/11/09 12:53:47 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>
#include <values.h>
#ifdef SunOS
#include <sys/systeminfo.h>
#endif
#include "cmscalendar.h"
#include "update.h"
#include "cm.h"
#include "attr.h"
#include "updateattrs.h"
#include "cmsdata.h"
#include "cmsentry.h"
#include "access.h"
#include "repeat.h"
#include "delete.h"
#include "insert.h"
#include "log.h"
#include "v5ops.h"
#include "iso8601.h"
#include "rerule.h"
#include "reutil.h"
extern char *_DtCm_rule_buf; /* buffer to hold a rule for parser */
extern RepeatEvent *_DtCm_repeat_info; /* parsed recurrence info */
extern boolean_t RulesMatch(char *rule1, char *rule2);
/******************************************************************************
* forward declaration of static functions used within the file
******************************************************************************/
static boolean_t _SameRecurrenceRule(
cms_attribute_value *newval,
cms_attribute_value *oldval);
static CSA_return_code _SetNewStartDate(
cms_entry *olde,
RepeatEvent *oldre,
cms_entry *newe,
RepeatEvent *newre,
cms_key *key);
static CSA_return_code _AdjustStartEndTimeForUpdateInst(
cms_entry *newe,
cms_entry *olde,
cms_key *key,
uint num_attrs,
cms_attribute *attrs);
static CSA_return_code _AdjustStartEndTimeForUpdateEntry(
List_node *lnode,
cms_entry *newe,
cms_key *key,
uint num_attrs,
cms_attribute *attrs);
static void _GetStartEndIndex(
uint num_attrs,
cms_attribute *attrs,
int *starti,
int *endi);
static void _AdjustExceptionDates(cms_entry *entry, time_t delta);
static int _NumberExceptionDates(cms_entry *entry);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
extern CSA_return_code
_DtCmsUpdateEntry(
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
uint num_attrs,
cms_attribute *attrs,
cms_entry **oldentry,
cms_entry **newentry)
{
CSA_return_code stat;
cms_entry *olde, *newe;
List_node *lnode = NULL;
int file_size;
/* get the entry from the tree */
if ((olde = (cms_entry *)rb_lookup(cal->tree, (caddr_t)key)) == NULL) {
/* find entry in the repeating entry list */
if ((lnode = hc_lookup_node(cal->list, (caddr_t)key)) == NULL)
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
else
olde = (cms_entry *)lnode->data;
}
if (olde == NULL)
return (CSA_X_DT_E_ENTRY_NOT_FOUND);
/* check access rights */
if ((stat = _DtCmsCheckChangeAccess(sender, access, olde))
!= CSA_SUCCESS)
return (stat);
/* copy the entry and apply updates */
if ((stat = _DtCm_copy_cms_entry(olde, &newe)) != CSA_SUCCESS)
return (stat);
if ((stat = _DtCmUpdateAttributes(num_attrs, attrs, &newe->num_attrs,
&newe->attrs, &cal->entry_tbl, B_FALSE, &cal->types, B_FALSE))
!= CSA_SUCCESS) {
_DtCm_free_cms_entry(newe);
return (stat);
}
/* update start date */
_csa_iso8601_to_tick(newe->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
item.date_time_value, &newe->key.time);
if (lnode != NULL && (stat = _AdjustStartEndTimeForUpdateEntry(
lnode, newe, key, num_attrs, attrs)) != CSA_SUCCESS) {
_DtCm_free_cms_entry(newe);
return (stat);
}
/* make sure end time is not earlier than start time */
if ((stat = _DtCmsCheckStartEndTime(newe)) != CSA_SUCCESS) {
_DtCm_free_cms_entry(newe);
return (stat);
}
/* set last update */
if ((stat = _DtCmsSetLastUpdate(newe)) != CSA_SUCCESS) {
_DtCm_free_cms_entry(newe);
return (stat);
}
/* save file size in case we need to roll back */
if ((stat = _DtCmsGetFileSize(cal->calendar, &file_size))
!= CSA_SUCCESS) {
_DtCm_free_cms_entry(newe);
return (stat);
}
/* remove old entry */
if ((stat = _DtCmsDeleteEntryAndLog(cal, NULL, 0, key, &olde))
!= CSA_SUCCESS){
_DtCm_free_cms_entry(newe);
return (stat);
}
/* insert new entry */
if ((stat = _DtCmsInsertEntryAndLog(cal, newe)) != CSA_SUCCESS) {
_DtCmsTruncateFile(cal->calendar, file_size);
_DtCmsInsertEntry(cal, olde);
_DtCm_free_cms_entry(newe);
_DtCm_free_cms_entry(olde);
} else {
if (newentry)
*newentry = newe;
else
_DtCm_free_cms_entry(newe);
if (oldentry)
*oldentry = olde;
else
_DtCm_free_cms_entry(olde);
}
return (stat);
}
extern CSA_return_code
_DtCmsUpdateInstances(
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
int scope,
uint num_attrs,
cms_attribute *attrs,
cms_entry **oldentry,
cms_entry **newentry)
{
CSA_return_code stat;
cms_entry *olde, *newe = NULL, *updatedold;
List_node *lnode = NULL;
int file_size;
int i, remain, rulei;
cms_attribute_value *oaptr, *naptr;
/* save file size in case we need to roll back */
if ((stat = _DtCmsGetFileSize(cal->calendar, &file_size))
!= CSA_SUCCESS)
return (stat);
/* remove old entry */
if ((stat = _DtCmsDeleteInstancesAndLog(cal, sender, access, key, scope,
&updatedold, &olde))
!= CSA_SUCCESS)
return (stat);
/* copy the entry and apply updates */
if ((stat = _DtCm_copy_cms_entry(olde, &newe)) != CSA_SUCCESS)
goto _cleanup;
if ((stat = _DtCmUpdateAttributes(num_attrs, attrs, &newe->num_attrs,
&newe->attrs, &cal->entry_tbl, B_FALSE, &cal->types, B_FALSE))
!= CSA_SUCCESS)
goto _cleanup;
/* check recurrence rule */
for (i = 0, rulei = -1; i < num_attrs; i++) {
if (attrs[i].name.num == CSA_ENTRY_ATTR_RECURRENCE_RULE_I) {
rulei = i;
break;
}
}
if (scope == CSA_SCOPE_ONE) {
if (rulei == -1) {
_DtCmUpdateSint32AttrVal(NULL, &newe->attrs\
[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].value);
_DtCmUpdateStringAttrVal(NULL, &newe->attrs\
[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value);
_DtCmUpdateSint32AttrVal(NULL, &newe->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value);
_DtCmUpdateSint32AttrVal(NULL, &newe->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value);
_DtCmUpdateSint32AttrVal(NULL, &newe->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value);
_DtCmUpdateSint32AttrVal(NULL, &newe->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I].\
value);
_DtCmUpdateStringAttrVal(NULL, &newe->attrs\
[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].value);
}
} else {
if (rulei == -1 ||
_SameRecurrenceRule(attrs[rulei].value, olde->\
attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value)) {
/*
* if recurrence info is not changed, replace
* the deleted part with the new one, i.e.,
* duration of new equals to the number of
* deleted instances of the old one.
* Also, update the exception list.
*/
if (newe->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value)
{
_DtCmsCleanupExceptionDates(newe, key->time);
}
oaptr = olde->attrs\
[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].value;
naptr = (updatedold == NULL) ? NULL :
updatedold->attrs[\
CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].\
value;
if (oaptr->item.uint32_value == 0)
remain = 0;
else
remain = oaptr->item.uint32_value -
(naptr ? naptr->item.uint32_value : 0) +
_DtCmsNumberExceptionDates(newe);
if ((stat = _DtCmsUpdateDurationInRule(newe, remain))
!= CSA_SUCCESS)
goto _cleanup;
}
}
if ((stat = _AdjustStartEndTimeForUpdateInst(newe, olde, key,
num_attrs, attrs)) != CSA_SUCCESS)
goto _cleanup;
/* set last update */
if ((stat = _DtCmsSetLastUpdate(newe)) != CSA_SUCCESS)
goto _cleanup;
/* insert new entry */
newe->key.id = 0;
if ((stat = _DtCmsInsertEntryAndLog(cal, newe)) != CSA_SUCCESS) {
goto _cleanup;
}
if (newentry)
*newentry = newe;
else
_DtCm_free_cms_entry(newe);
if (oldentry)
*oldentry = olde;
else
_DtCm_free_cms_entry(olde);
if (updatedold) _DtCm_free_cms_entry(updatedold);
return (stat);
_cleanup:
_DtCmsTruncateFile(cal->calendar, file_size);
if (updatedold == NULL)
_DtCmsInsertEntry(cal, olde);
else {
_DtCm_free_cms_entry(updatedold);
if (lnode = hc_lookup_node(cal->list, (caddr_t)key)) {
updatedold = (cms_entry *)lnode->data;
lnode->data = (caddr_t)olde;
olde = updatedold;
}
}
_DtCm_free_cms_entry(olde);
if (newe) _DtCm_free_cms_entry(newe);
return (stat);
}
/*****************************************************************************
* static functions used within the file
*****************************************************************************/
static boolean_t
_SameRecurrenceRule(cms_attribute_value *newval, cms_attribute_value *oldval)
{
if (newval == NULL || newval->item.string_value == NULL)
return (B_FALSE);
if (strcmp(newval->item.string_value, oldval->item.string_value))
return (B_FALSE);
else
return (B_TRUE);
}
static CSA_return_code
_AdjustStartEndTimeForUpdateInst(
cms_entry *newe,
cms_entry *olde,
cms_key *key,
uint num_attrs,
cms_attribute *attrs)
{
CSA_return_code stat;
time_t oldbod, newbod, endtime, delta;
int i, starti, endi;
/* update start date */
_GetStartEndIndex(num_attrs, attrs, &starti, &endi);
oldbod = _DtCmsBeginOfDay(olde->key.time);
if (starti >= 0 && endi == -1 &&
newe->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
/* adjust end date */
_csa_iso8601_to_tick(newe->attrs[CSA_ENTRY_ATTR_START_DATE_I].\
value->item.date_time_value, &newe->key.time);
newbod = _DtCmsBeginOfDay(newe->key.time);
_csa_iso8601_to_tick(newe->attrs[CSA_ENTRY_ATTR_END_DATE_I].\
value->item.date_time_value, &endtime);
endtime += (newbod - oldbod);
_csa_tick_to_iso8601(endtime, newe->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->item.\
date_time_value);
} else if (starti == -1 && endi >= 0) {
/* ajust start date */
if (newe->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
_csa_iso8601_to_tick(newe->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value, &endtime);
newbod = _DtCmsBeginOfDay(endtime);
} else
newbod = _DtCmsBeginOfDay(key->time);
newe->key.time += (newbod - oldbod);
_csa_tick_to_iso8601(newe->key.time, newe->attrs\
[CSA_ENTRY_ATTR_START_DATE_I].value->item.\
date_time_value);
} else if (starti == -1 && endi == -1) {
/* adjust both start and end date */
newe->key.time = key->time;
_csa_tick_to_iso8601(key->time, newe->attrs[\
CSA_ENTRY_ATTR_START_DATE_I].value->item.\
date_time_value);
if (newe->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
newbod = _DtCmsBeginOfDay(newe->key.time);
_csa_iso8601_to_tick(newe->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value, &endtime);
endtime += (newbod - oldbod);
_csa_tick_to_iso8601(endtime, newe->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->\
item.date_time_value);
}
} else {
_csa_iso8601_to_tick(newe->attrs[CSA_ENTRY_ATTR_START_DATE_I].\
value->item.date_time_value, &newe->key.time);
}
if ((stat = _DtCmsCheckStartEndTime(newe)) != CSA_SUCCESS) {
return (stat);
}
if ((delta = _DtCmsTimeOfDay(newe->key.time) -
_DtCmsTimeOfDay(key->time)) != 0)
_AdjustExceptionDates(newe, delta);
return (CSA_SUCCESS);
}
static CSA_return_code
_SetNewStartDate(
cms_entry *olde,
RepeatEvent *oldre,
cms_entry *newe,
RepeatEvent *newre,
cms_key *key)
{
if ((newe->key.time = DeriveNewStartTime(olde->key.time, oldre,
key->time, newe->key.time, newre)) == 0)
return (CSA_E_FAILURE);
if (_csa_tick_to_iso8601(newe->key.time, newe->attrs\
[CSA_ENTRY_ATTR_START_DATE_I].value->item.date_time_value))
return (CSA_E_FAILURE);
return (CSA_SUCCESS);
}
/*
* The assumption is that there's only one instance per day.
* When we support more than one instance per day, this
* needs to be updated.
*/
static void
_AdjustExceptionDates(cms_entry *entry, time_t delta)
{
time_t tick;
CSA_date_time_list dt, head;
if (entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value == NULL ||
entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value == NULL)
return;
head = entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value;
for (dt = head; dt != NULL; dt = dt->next) {
_csa_iso8601_to_tick(dt->date_time, &tick);
tick += delta;
_csa_tick_to_iso8601(tick, dt->date_time);
}
}
static void
_GetStartEndIndex(
uint num_attrs,
cms_attribute *attrs,
int *starti,
int *endi)
{
int i;
for (i = 0, *starti = -1, *endi = -1; i < num_attrs; i++) {
if (attrs[i].name.num == CSA_ENTRY_ATTR_START_DATE_I)
*starti = i;
else if (attrs[i].name.num == CSA_ENTRY_ATTR_END_DATE_I)
*endi = i;
}
}
static CSA_return_code
_AdjustStartEndTimeForUpdateEntry(
List_node *lnode,
cms_entry *newe,
cms_key *key,
uint num_attrs,
cms_attribute *attrs)
{
CSA_return_code stat;
cms_entry *olde = (cms_entry *)lnode->data;
time_t newbod, instbod, fstbod, newfstbod, endtime;
int starti, endi, enddelta = 0;
cms_attribute_value *oldaptr, *newaptr, *endaptr;
RepeatEvent *newre;
extern void _DtCm_rule_parser();
/* check to make sure repeating type is not changed */
oldaptr = olde->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value;
newaptr = newe->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value;
endaptr = newe->attrs[CSA_ENTRY_ATTR_END_DATE_I].value;
if (endaptr)
_csa_iso8601_to_tick(endaptr->item.date_time_value, &endtime);
if (key->time != olde->key.time &&
(newaptr == NULL || newaptr->item.string_value == NULL ||
RulesMatch(oldaptr->item.string_value, newaptr->item.string_value)
== B_FALSE)) {
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
_GetStartEndIndex(num_attrs, attrs, &starti, &endi);
newbod = _DtCmsBeginOfDay(newe->key.time);
instbod = _DtCmsBeginOfDay(key->time);
fstbod = _DtCmsBeginOfDay(olde->key.time);
if (starti >= 0 && key->time != olde->key.time) {
if (newbod == instbod) {
/* keep the same start day */
newe->key.time -= (newbod - fstbod);
_csa_tick_to_iso8601(newe->key.time,
newe->attrs[CSA_ENTRY_ATTR_START_DATE_I].\
value->item.date_time_value);
if (endi >= 0)
enddelta = newbod - fstbod;
} else {
/* parse the rule */
_DtCm_rule_buf = newaptr->item.string_value;
_DtCm_rule_parser();
if ((newre = _DtCm_repeat_info) == NULL)
return (CSA_E_INVALID_RULE);
/* get new start date */
if ((stat = _SetNewStartDate(olde, lnode->re,
newe, newre, key)) != CSA_SUCCESS) {
_DtCm_free_re(newre);
return (stat);
}
_DtCm_free_re(newre);
newfstbod = _DtCmsBeginOfDay(newe->key.time);
if (endi < 0)
enddelta = fstbod - newfstbod;
else
enddelta = newbod - newfstbod;
}
} else if (starti >= 0 && endi < 0 && newbod != fstbod) {
enddelta = fstbod - newbod;
} else if (starti < 0 && endi >= 0 && key->time != olde->key.time &&
endaptr)
{
enddelta = _DtCmsBeginOfDay(endtime) - fstbod;
}
/* fix end date */
if (enddelta && endaptr) {
endtime -= enddelta;
_csa_tick_to_iso8601(endtime, endaptr->item.date_time_value);
}
return (CSA_SUCCESS);
}

View File

@@ -0,0 +1,42 @@
/* $XConsortium: update.h /main/4 1995/11/09 12:54:08 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.
*/
#ifndef _UPDATE_H
#define _UPDATE_H
#include "ansi_c.h"
#include "cm.h"
#include "cmscalendar.h"
extern CSA_return_code _DtCmsUpdateCalAttrs P((
_DtCmsCalendar *cal,
uint num_attrs,
cms_attribute *attrs));
extern CSA_return_code _DtCmsUpdateEntry P((
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
uint num_attrs,
cms_attribute *attrs,
cms_entry **oldentry,
cms_entry **newentry));
extern CSA_return_code _DtCmsUpdateInstances P((
_DtCmsCalendar *cal,
char *sender,
uint access,
cms_key *key,
int scope,
uint num_attrs,
cms_attribute *attrs,
cms_entry **oldentry,
cms_entry **newentry));
#endif

View File

@@ -0,0 +1,84 @@
/* $XConsortium: utility.c /main/4 1995/11/09 12:54:25 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 <string.h>
#include <rpc/rpc.h>
#if defined(SunOS) || defined(USL) || defined(__uxp__)
#include <netdb.h>
#include <sys/systeminfo.h>
#endif
#include "utility.h"
#include "lutil.h"
extern char * strdup(const char *);
/*
* calendar_name@host[.domain] -> calendar_name
*/
extern char *
_DtCmsTarget2Name(char *target)
{
return(_DtCmGetPrefix(target, '@'));
}
/*
* calendar_name@host[.domain] -> host[.domain]
*/
extern char *
_DtCmsTarget2Location(char *target)
{
char *ptr;
if (target == NULL)
return (NULL);
if (ptr = strchr(target, '@')) {
return (strdup(++ptr));
} else
return (NULL);
}
/*
* calendar_name@host[.domain] -> host
*/
extern char *
_DtCmsTarget2Host(char *target)
{
char *location, *host;
if ((location = _DtCmsTarget2Location(target)) != NULL) {
host = _DtCmGetPrefix(location, '.');
free(location);
return(host);
} else
return(NULL);
}
/*
* calendar_name@host[.domain] -> domain
*/
extern char *
_DtCmsTarget2Domain(char *target)
{
char *location, *domain, *ptr;
if ((location = _DtCmsTarget2Location(target)) != NULL) {
if (ptr = strchr(location, '.'))
domain = strdup(++ptr);
else
domain = NULL;
free(location);
return(domain);
} else
return(NULL);
}

View File

@@ -0,0 +1,22 @@
/* $XConsortium: utility.h /main/4 1995/11/09 12:54:43 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.
*/
#ifndef _UTILITY_H
#define _UTILITY_H
#include "ansi_c.h"
extern char *_DtCmsTarget2Name P((char *target));
extern char *_DtCmsTarget2Location P((char *target));
extern char *_DtCmsTarget2Host P((char *target));
extern char *_DtCmsTarget2Domain P((char *target));
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
/* $XConsortium: v4ops.h /main/4 1995/11/09 12:55:26 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.
*/
#ifndef _V4OPS_H
#define _V4OPS_H
#include "ansi_c.h"
#include "rtable4.h"
#include "cm.h"
#include "log.h"
#include "cmscalendar.h"
#define is_appointment(p_appt) ((p_appt)->period.period == single_4)
#define is_repeater(p_appt) ((p_appt)->period.period != single_4)
typedef struct __DtCmsEntryId {
long id;
struct __DtCmsEntryId *next;
} _DtCmsEntryId;
extern CSA_return_code _DtCmsInsertAppt P((_DtCmsCalendar *cal, Appt_4 *appt4));
extern CSA_return_code _DtCmsDeleteAppt P((
_DtCmsCalendar *cal,
char *user,
uint access,
Id_4 *p_key,
Appt_4 **appt_r));
extern CSA_return_code _DtCmsDeleteApptAndLog P((
_DtCmsCalendar *cal,
char *user,
uint access,
Id_4 *key,
Appt_4 **oldappt));
extern CSA_return_code _DtCmsDeleteApptInstancesAndLog P((
_DtCmsCalendar *cal,
char *source,
uint access,
Id_4 *key,
Options_4 option,
int *remain,
Appt_4 **oldappt));
extern CSA_return_code _DtCmsChangeAll P((
_DtCmsCalendar *cal,
char *source,
uint access,
Id_4 *p_key,
Appt_4 *newa,
Appt_4 **oldappt));
extern CSA_return_code _DtCmsChangeSome P((
_DtCmsCalendar *cal,
char *source,
uint access,
Id_4 *p_key,
Appt_4 *p_appt,
Options_4 option,
Appt_4 **oldappt));
extern CSA_return_code _DtCmsInsertApptAndLog P((
_DtCmsCalendar *cal,
Appt_4 *appt));
extern _DtCmsComparisonResult _DtCmsCompareAppt P((Id_4 *key, caddr_t data));
extern _DtCmsComparisonResult _DtCmsCompareRptAppt P((Id_4 *key, caddr_t data));
extern caddr_t _DtCmsGetApptKey P((caddr_t data));
extern CSA_return_code v4_transact_log P((
char *calendar,
Appt_4 *a,
_DtCmsLogOps op));
extern CSA_return_code _DtCmsLookupRangeV4 P((
_DtCmsCalendar *cal,
char *user,
uint access,
Range_4 *p_range,
boolean_t no_end_time_range,
long end1,
long end2,
boolean_t (*match_func)(),
uint num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
Appt_4 **appt_r,
Abb_Appt_4 **abbr_r));
extern CSA_return_code _DtCmsLookupKeyrangeV4 P((
_DtCmsCalendar *cal,
char *user,
uint access,
boolean_t no_start_time_range,
boolean_t no_end_time_range,
time_t start1,
time_t start2,
time_t end1,
time_t end2,
long id,
boolean_t (*match_func)(),
uint num_attrs,
cms_attribute *attrs,
CSA_enum *ops,
Appt_4 **appt_r,
Abb_Appt_4 **abbr_r));
extern CSA_return_code _AddToLinkedAppts P((
Appt_4 *p_appt,
char *user,
uint access,
caddr_t *ilp));
extern CSA_return_code _AddToLinkedAbbrAppts P((
Appt_4 *p_appt,
char *user,
uint access,
caddr_t *ilp));
extern Privacy_Level_4 _GetAccessLevel P((
char *user,
uint access,
Appt_4 *p_appt));
extern Appt_4 * _AddApptInOrder P((Appt_4 * head, Appt_4 * aptr));
extern Abb_Appt_4 * _AddAbbApptInOrder P((Abb_Appt_4 *head, Abb_Appt_4 *aptr));
extern CSA_return_code _DtCmsSetV4AccessListAndLog P((
_DtCmsCalendar *cal,
Access_Entry_4 *alist));
extern CSA_return_code _DtCmsGetV4Reminders P((
_DtCmsCalendar *cal,
long tick,
Reminder_4 **rem_r,
_DtCmsEntryId **ids_r));
extern void _DtCmsFreeEntryIds P((_DtCmsEntryId *ids));
extern CSA_return_code _DtCmsTruncateElist P((
Appt_4 *parent_p,
int remain,
Except_4 **excpt));
extern CSA_return_code _DtCmsSetV4AccessListInCal P((
_DtCmsCalendar *cal,
Access_Entry_4 *e));
#endif

View File

@@ -0,0 +1,352 @@
/* $XConsortium: v5ops.c /main/4 1995/11/09 12:55:44 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 <string.h>
#include <time.h>
#include "v5ops.h"
#include "iso8601.h"
#include "attr.h"
#include "updateattrs.h"
#include "rerule.h"
#include "repeat.h"
#include "reutil.h"
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
extern _DtCmsComparisonResult
_DtCmsCompareEntry(cms_key *key, caddr_t data)
{
cms_entry *entry = (cms_entry *)data;
/* check the time only if it's not zero */
if (key->time < entry->key.time)
return (_DtCmsIsLess);
if (key->time > entry->key.time)
return (_DtCmsIsGreater);
/* tick's are _DtCmsIsEqual */
if (key->id < entry->key.id)
return (_DtCmsIsLess);
if (key->id > entry->key.id)
return (_DtCmsIsGreater);
return (_DtCmsIsEqual);
}
extern _DtCmsComparisonResult
_DtCmsCompareRptEntry(cms_key *key, caddr_t data)
{
cms_entry *entry = (cms_entry *)data;
if (key->id < entry->key.id)
return (_DtCmsIsLess);
if (key->id > entry->key.id)
return (_DtCmsIsGreater);
return (_DtCmsIsEqual);
}
extern caddr_t
_DtCmsGetEntryKey(caddr_t data)
{
return ((caddr_t) &(((cms_entry *)data)->key));
}
extern CSA_return_code
_DtCmsSetLastUpdate(cms_entry *entry)
{
char datestr[20];
cms_attribute_value val;
_csa_tick_to_iso8601(time(0), datestr);
val.type = CSA_VALUE_DATE_TIME;
val.item.date_time_value = datestr;
/* CSA_ENTRY_ATTR_LAST_UPDATE_I */
return (_DtCmUpdateStringAttrVal(&val,
&entry->attrs[CSA_ENTRY_ATTR_LAST_UPDATE_I].value));
}
extern void
_DtCmsConvertToOnetime(cms_entry *entry, RepeatEvent *re)
{
time_t ctick, lasttick, diff = 0;
RepeatEventState *res;
lasttick = LastTick(entry->key.time, re);
for (ctick = ClosestTick(entry->key.time, entry->key.time, re, &res);
ctick <= lasttick;
ctick = NextTick(ctick, entry->key.time, re, res))
{
if (ctick <= 0 || !_DtCmsInExceptionList(entry, ctick))
break;
}
if (ctick != entry->key.time) {
if (entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
_csa_iso8601_to_tick(entry->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->item.\
date_time_value, &diff);
diff = diff - entry->key.time;
}
entry->key.time = ctick;
_csa_tick_to_iso8601(ctick, entry->attrs\
[CSA_ENTRY_ATTR_START_DATE_I].value->item.\
date_time_value);
if (entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value)
_csa_tick_to_iso8601(ctick+diff, entry->attrs\
[CSA_ENTRY_ATTR_END_DATE_I].value->item.\
date_time_value);
}
if (entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value)
entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value->item.\
sint32_value = CSA_X_DT_REPEAT_ONETIME;
else
_DtCm_set_sint32_attrval(CSA_X_DT_REPEAT_ONETIME,
&entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value);
_DtCmUpdateDateTimeListAttrVal(NULL, &entry->attrs\
[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value);
_DtCmUpdateSint32AttrVal(NULL, &entry->attrs\
[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].value);
_DtCmUpdateStringAttrVal(NULL, &entry->attrs\
[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value);
_DtCmUpdateSint32AttrVal(NULL, &entry->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value);
_DtCmUpdateSint32AttrVal(NULL, &entry->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value);
_DtCmUpdateSint32AttrVal(NULL, &entry->attrs\
[CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I].value);
_DtCmUpdateStringAttrVal(NULL, &entry->attrs\
[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].value);
}
extern int
_DtCmsGetDuration(cms_entry *eptr)
{
time_t stime, etime;
if (eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
_csa_iso8601_to_tick(eptr->attrs[CSA_ENTRY_ATTR_END_DATE_I].\
value->item.date_time_value, &etime);
_csa_iso8601_to_tick(eptr->attrs[CSA_ENTRY_ATTR_START_DATE_I].\
value->item.date_time_value, &stime);
return (etime - stime);
} else
return (0);
}
extern CSA_return_code
_DtCmsCheckInitialAttributes(cms_entry *entry)
{
CSA_return_code stat;
cms_attribute *attrs;
char datestr[80];
if (entry == NULL)
return (CSA_E_INVALID_PARAMETER);
attrs = entry->attrs;
/* fill in server generated value */
/* CSA_ENTRY_ATTR_DATE_CREATED_I */
_csa_tick_to_iso8601(time(0), datestr);
if ((stat = _DtCm_set_string_attrval(datestr,
&attrs[CSA_ENTRY_ATTR_DATE_CREATED_I].value, CSA_VALUE_DATE_TIME))
!= CSA_SUCCESS)
return (stat);
/* CSA_ENTRY_ATTR_LAST_UPDATE_I */
if ((stat = _DtCm_set_string_attrval(datestr,
&attrs[CSA_ENTRY_ATTR_LAST_UPDATE_I].value, CSA_VALUE_DATE_TIME))
!= CSA_SUCCESS)
return (stat);
/* fill in default values when not specified */
if (attrs[CSA_ENTRY_ATTR_SUMMARY_I].value == NULL &&
(stat = _DtCm_set_string_attrval("",
&attrs[CSA_ENTRY_ATTR_SUMMARY_I].value, CSA_VALUE_STRING))
!= CSA_SUCCESS)
return (stat);
if (attrs[CSA_X_DT_ENTRY_ATTR_SHOWTIME_I].value == NULL &&
(stat = _DtCm_set_sint32_attrval(1,
&attrs[CSA_X_DT_ENTRY_ATTR_SHOWTIME_I].value)) != CSA_SUCCESS)
return (stat);
if (attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value == NULL &&
(stat = _DtCm_set_uint32_attrval(CSA_CLASS_PUBLIC,
&attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value)) != CSA_SUCCESS)
return (stat);
if (attrs[CSA_ENTRY_ATTR_STATUS_I].value == NULL &&
(stat = _DtCm_set_uint32_attrval(CSA_X_DT_STATUS_ACTIVE,
&attrs[CSA_ENTRY_ATTR_STATUS_I].value)) != CSA_SUCCESS)
return (stat);
if (attrs[CSA_ENTRY_ATTR_SUBTYPE_I].value == NULL &&
attrs[CSA_ENTRY_ATTR_TYPE_I].value->item.uint32_value ==
CSA_TYPE_EVENT &&
(stat = _DtCm_set_string_attrval(CSA_SUBTYPE_APPOINTMENT,
&attrs[CSA_ENTRY_ATTR_SUBTYPE_I].value, CSA_VALUE_STRING))
!= CSA_SUCCESS)
return (stat);
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsCheckStartEndTime(cms_entry *entry)
{
time_t endtime;
if (entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].value) {
_csa_iso8601_to_tick(entry->attrs[CSA_ENTRY_ATTR_END_DATE_I].\
value->item.date_time_value, &endtime);
if (endtime < entry->key.time)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
else
return (CSA_SUCCESS);
}
return (CSA_SUCCESS);
}
extern void
_DtCmsCleanupExceptionDates(cms_entry *entry, long ftick)
{
time_t tick;
CSA_date_time_list dt, prev, head;
if (entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value == NULL ||
entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value == NULL)
return;
head = entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value;
for (dt = head, prev = NULL; dt != NULL; prev = dt, dt = dt->next) {
_csa_iso8601_to_tick(dt->date_time, &tick);
if (ftick <= tick) {
if (prev) {
prev->next = NULL;
_DtCm_free_date_time_list(head);
}
break;
}
}
if (dt == NULL) {
free(entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value);
entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value = NULL;
} else
entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value->item.\
date_time_list_value = dt;
}
extern int
_DtCmsNumberExceptionDates(cms_entry *entry)
{
cms_attribute_value *vptr;
CSA_date_time_list dt;
int count;
if ((vptr = entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I].value)
== NULL)
return (0);
count = 0;
for (dt = vptr->item.date_time_list_value; dt != NULL; dt = dt->next)
count++;
return (count);
}
extern CSA_return_code
_DtCmsUpdateDurationInRule(cms_entry *entry, uint remain)
{
char *newrule, *ptr;
char buf[BUFSIZ];
cms_attribute_value *vptr;
vptr = entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value;
if ((newrule = malloc(strlen(vptr->item.string_value) + 20)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
sprintf(buf, "#%d", remain);
if (ptr = strchr(vptr->item.string_value, '#')) {
*ptr = NULL;
strcpy(newrule, vptr->item.string_value);
strcat(newrule, buf);
if (ptr = strchr(ptr + 1, ' '))
strcat(newrule, ptr);
} else {
if (ptr = strchr(vptr->item.string_value, ' ')) {
*ptr = NULL;
sprintf(newrule, "%s %s %s", vptr->item.string_value,
buf, ptr+1);
} else
sprintf(newrule, "%s %s", vptr->item.string_value, buf);
}
free (vptr->item.string_value);
entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value->item.string_value
= newrule;
entry->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].value->\
item.uint32_value = remain;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCmsAddEndDateToRule(cms_attribute *attr, RepeatEvent *re, long time)
{
char *newrule, *ptr;
char buf[20];
if (_csa_tick_to_iso8601(time, buf))
return (CSA_E_INVALID_DATE_TIME);
if ((newrule = malloc(strlen(attr->value->item.string_value)+20))
== NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (re->re_end_date == 0) {
sprintf(newrule, "%s %s", attr->value->item.string_value, buf);
} else {
/* end date is always at the end of the rule */
strcpy(newrule, attr->value->item.string_value);
ptr = strrchr(newrule, ' ');
sprintf(ptr, " %s", buf);
}
free(attr->value->item.string_value);
attr->value->item.string_value = newrule;
return (CSA_SUCCESS);
}

View File

@@ -0,0 +1,50 @@
/* $XConsortium: v5ops.h /main/4 1995/11/09 12:56:05 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.
*/
#ifndef _V5OPS_H
#define _V5OPS_H
#include "ansi_c.h"
#include "cm.h"
#include "cmscalendar.h"
#include "rerule.h"
#include "repeat.h"
extern _DtCmsComparisonResult _DtCmsCompareEntry P((
cms_key *key,
caddr_t data));
extern _DtCmsComparisonResult _DtCmsCompareRptEntry P((
cms_key *key,
caddr_t data));
extern caddr_t _DtCmsGetEntryKey P((caddr_t data));
extern CSA_return_code _DtCmsSetLastUpdate P((cms_entry *entry));
extern void _DtCmsConvertToOnetime P((cms_entry *entry, RepeatEvent *re));
extern int _DtCmsGetDuration P((cms_entry *eptr));
extern CSA_return_code _DtCmsCheckInitialAttributes P((cms_entry *entry));
extern CSA_return_code _DtCmsCheckStartEndTime P((cms_entry *entry));
extern void _DtCmsCleanupExceptionDates P((cms_entry *newe, long ftick));
extern int _DtCmsNumberExceptionDates P((cms_entry *entry));
extern CSA_return_code _DtCmsUpdateDurationInRule P((
cms_entry *entry,
uint remain));
extern CSA_return_code _DtCmsAddEndDateToRule P((
cms_attribute *attr,
RepeatEvent *re,
long time));
#endif