Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
98
cde/programs/dtcm/server/Imakefile
Normal file
98
cde/programs/dtcm/server/Imakefile
Normal 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()
|
||||
190
cde/programs/dtcm/server/SUNW_SDTCM_CONVERT.msg
Normal file
190
cde/programs/dtcm/server/SUNW_SDTCM_CONVERT.msg
Normal 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"
|
||||
542
cde/programs/dtcm/server/access.c
Normal file
542
cde/programs/dtcm/server/access.c
Normal 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);
|
||||
}
|
||||
|
||||
93
cde/programs/dtcm/server/access.h
Normal file
93
cde/programs/dtcm/server/access.h
Normal 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
|
||||
660
cde/programs/dtcm/server/callback.c
Normal file
660
cde/programs/dtcm/server/callback.c
Normal 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);
|
||||
}
|
||||
|
||||
113
cde/programs/dtcm/server/callback.h
Normal file
113
cde/programs/dtcm/server/callback.h
Normal 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
|
||||
107
cde/programs/dtcm/server/cm_tbl.i
Normal file
107
cde/programs/dtcm/server/cm_tbl.i
Normal 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]);
|
||||
|
||||
295
cde/programs/dtcm/server/cmsattr.c
Normal file
295
cde/programs/dtcm/server/cmsattr.c
Normal 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);
|
||||
}
|
||||
|
||||
57
cde/programs/dtcm/server/cmsattr.h
Normal file
57
cde/programs/dtcm/server/cmsattr.h
Normal 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
|
||||
1200
cde/programs/dtcm/server/cmscalendar.c
Normal file
1200
cde/programs/dtcm/server/cmscalendar.c
Normal file
File diff suppressed because it is too large
Load Diff
150
cde/programs/dtcm/server/cmscalendar.h
Normal file
150
cde/programs/dtcm/server/cmscalendar.h
Normal 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
|
||||
1141
cde/programs/dtcm/server/cmsconvert.c
Normal file
1141
cde/programs/dtcm/server/cmsconvert.c
Normal file
File diff suppressed because it is too large
Load Diff
68
cde/programs/dtcm/server/cmsconvert.h
Normal file
68
cde/programs/dtcm/server/cmsconvert.h
Normal 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
|
||||
181
cde/programs/dtcm/server/cmsentry.c
Normal file
181
cde/programs/dtcm/server/cmsentry.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
32
cde/programs/dtcm/server/cmsentry.h
Normal file
32
cde/programs/dtcm/server/cmsentry.h
Normal 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
|
||||
1381
cde/programs/dtcm/server/cmsfunc.c
Normal file
1381
cde/programs/dtcm/server/cmsfunc.c
Normal file
File diff suppressed because it is too large
Load Diff
96
cde/programs/dtcm/server/cmsmatch.c
Normal file
96
cde/programs/dtcm/server/cmsmatch.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
23
cde/programs/dtcm/server/cmsmatch.h
Normal file
23
cde/programs/dtcm/server/cmsmatch.h
Normal 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
|
||||
39
cde/programs/dtcm/server/data.h
Normal file
39
cde/programs/dtcm/server/data.h
Normal 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
|
||||
405
cde/programs/dtcm/server/delete.c
Normal file
405
cde/programs/dtcm/server/delete.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
cde/programs/dtcm/server/delete.h
Normal file
39
cde/programs/dtcm/server/delete.h
Normal 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
|
||||
263
cde/programs/dtcm/server/garbage.c
Normal file
263
cde/programs/dtcm/server/garbage.c
Normal 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");
|
||||
}
|
||||
|
||||
|
||||
26
cde/programs/dtcm/server/garbage.h
Normal file
26
cde/programs/dtcm/server/garbage.h
Normal 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
|
||||
361
cde/programs/dtcm/server/insert.c
Normal file
361
cde/programs/dtcm/server/insert.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
24
cde/programs/dtcm/server/insert.h
Normal file
24
cde/programs/dtcm/server/insert.h
Normal 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
|
||||
26
cde/programs/dtcm/server/lexer.h
Normal file
26
cde/programs/dtcm/server/lexer.h
Normal 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
|
||||
542
cde/programs/dtcm/server/lexit.c
Normal file
542
cde/programs/dtcm/server/lexit.c
Normal 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
|
||||
325
cde/programs/dtcm/server/list.c
Normal file
325
cde/programs/dtcm/server/list.c
Normal 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);
|
||||
}
|
||||
54
cde/programs/dtcm/server/list.h
Normal file
54
cde/programs/dtcm/server/list.h
Normal 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
|
||||
1297
cde/programs/dtcm/server/log.c
Normal file
1297
cde/programs/dtcm/server/log.c
Normal file
File diff suppressed because it is too large
Load Diff
88
cde/programs/dtcm/server/log.h
Normal file
88
cde/programs/dtcm/server/log.h
Normal 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
|
||||
636
cde/programs/dtcm/server/lookup.c
Normal file
636
cde/programs/dtcm/server/lookup.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
93
cde/programs/dtcm/server/lookup.h
Normal file
93
cde/programs/dtcm/server/lookup.h
Normal 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
|
||||
1155
cde/programs/dtcm/server/parser.y
Normal file
1155
cde/programs/dtcm/server/parser.y
Normal file
File diff suppressed because it is too large
Load Diff
57
cde/programs/dtcm/server/programtable.c
Normal file
57
cde/programs/dtcm/server/programtable.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
1148
cde/programs/dtcm/server/reclotick.c
Normal file
1148
cde/programs/dtcm/server/reclotick.c
Normal file
File diff suppressed because it is too large
Load Diff
310
cde/programs/dtcm/server/recount.c
Normal file
310
cde/programs/dtcm/server/recount.c
Normal 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;
|
||||
}
|
||||
518
cde/programs/dtcm/server/relasttick.c
Normal file
518
cde/programs/dtcm/server/relasttick.c
Normal 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;
|
||||
}
|
||||
971
cde/programs/dtcm/server/reminder.c
Normal file
971
cde/programs/dtcm/server/reminder.c
Normal 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 */
|
||||
}
|
||||
}
|
||||
|
||||
99
cde/programs/dtcm/server/reminder.h
Normal file
99
cde/programs/dtcm/server/reminder.h
Normal 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
|
||||
581
cde/programs/dtcm/server/renexttick.c
Normal file
581
cde/programs/dtcm/server/renexttick.c
Normal 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);
|
||||
}
|
||||
1727
cde/programs/dtcm/server/repeat.c
Normal file
1727
cde/programs/dtcm/server/repeat.c
Normal file
File diff suppressed because it is too large
Load Diff
77
cde/programs/dtcm/server/repeat.h
Normal file
77
cde/programs/dtcm/server/repeat.h
Normal 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
|
||||
590
cde/programs/dtcm/server/reprevtick.c
Normal file
590
cde/programs/dtcm/server/reprevtick.c
Normal 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);
|
||||
}
|
||||
406
cde/programs/dtcm/server/rerule.c
Normal file
406
cde/programs/dtcm/server/rerule.c
Normal 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);
|
||||
}
|
||||
371
cde/programs/dtcm/server/reutil.c
Normal file
371
cde/programs/dtcm/server/reutil.c
Normal 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;
|
||||
}
|
||||
62
cde/programs/dtcm/server/reutil.h
Normal file
62
cde/programs/dtcm/server/reutil.h
Normal 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 */
|
||||
42
cde/programs/dtcm/server/rpcextras.h
Normal file
42
cde/programs/dtcm/server/rpcextras.h
Normal 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
|
||||
425
cde/programs/dtcm/server/rtable2.c
Normal file
425
cde/programs/dtcm/server/rtable2.c
Normal 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]);
|
||||
}
|
||||
|
||||
115
cde/programs/dtcm/server/rtable2_tbl.i
Normal file
115
cde/programs/dtcm/server/rtable2_tbl.i
Normal 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]);
|
||||
|
||||
441
cde/programs/dtcm/server/rtable3.c
Normal file
441
cde/programs/dtcm/server/rtable3.c
Normal 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]);
|
||||
}
|
||||
|
||||
122
cde/programs/dtcm/server/rtable3_tbl.i
Normal file
122
cde/programs/dtcm/server/rtable3_tbl.i
Normal 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]);
|
||||
|
||||
1892
cde/programs/dtcm/server/rtable4.c
Normal file
1892
cde/programs/dtcm/server/rtable4.c
Normal file
File diff suppressed because it is too large
Load Diff
144
cde/programs/dtcm/server/rtable4_tbl.i
Normal file
144
cde/programs/dtcm/server/rtable4_tbl.i
Normal 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]);
|
||||
|
||||
744
cde/programs/dtcm/server/svcmain.c
Normal file
744
cde/programs/dtcm/server/svcmain.c
Normal 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(×tr[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);
|
||||
}
|
||||
|
||||
652
cde/programs/dtcm/server/tree.c
Normal file
652
cde/programs/dtcm/server/tree.c
Normal 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);
|
||||
}
|
||||
61
cde/programs/dtcm/server/tree.h
Normal file
61
cde/programs/dtcm/server/tree.h
Normal 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
|
||||
589
cde/programs/dtcm/server/update.c
Normal file
589
cde/programs/dtcm/server/update.c
Normal 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);
|
||||
}
|
||||
|
||||
42
cde/programs/dtcm/server/update.h
Normal file
42
cde/programs/dtcm/server/update.h
Normal 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
|
||||
84
cde/programs/dtcm/server/utility.c
Normal file
84
cde/programs/dtcm/server/utility.c
Normal 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);
|
||||
}
|
||||
|
||||
22
cde/programs/dtcm/server/utility.h
Normal file
22
cde/programs/dtcm/server/utility.h
Normal 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
|
||||
1462
cde/programs/dtcm/server/v4ops.c
Normal file
1462
cde/programs/dtcm/server/v4ops.c
Normal file
File diff suppressed because it is too large
Load Diff
158
cde/programs/dtcm/server/v4ops.h
Normal file
158
cde/programs/dtcm/server/v4ops.h
Normal 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
|
||||
352
cde/programs/dtcm/server/v5ops.c
Normal file
352
cde/programs/dtcm/server/v5ops.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
50
cde/programs/dtcm/server/v5ops.h
Normal file
50
cde/programs/dtcm/server/v5ops.h
Normal 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
|
||||
Reference in New Issue
Block a user