Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
53
cde/lib/DtSvc/DtCodelibs/Imakefile
Normal file
53
cde/lib/DtSvc/DtCodelibs/Imakefile
Normal file
@@ -0,0 +1,53 @@
|
||||
XCOMM $XConsortium: Imakefile /main/6 1996/08/20 14:48:43 drk $
|
||||
XCOMM (c) Copyright 1996 Digital Equipment Corporation.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Hewlett-Packard Company.
|
||||
XCOMM (c) Copyright 1993-1994,1996 International Business Machines Corp.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Sun Microsystems, Inc.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Novell, Inc.
|
||||
XCOMM (c) Copyright 1996 FUJITSU LIMITED.
|
||||
XCOMM (c) Copyright 1996 Hitachi.
|
||||
|
||||
#define DoNormalLib NormalLibDtSvc
|
||||
#define DoSharedLib SharedLibDtSvc
|
||||
#define DoDebugLib DebugLibDtSvc
|
||||
#define DoProfileLib ProfileLibDtSvc
|
||||
#define LibName DtSvc
|
||||
#define SoRev SODTSVCREV
|
||||
#define LibHeaders NO
|
||||
#define LibCreate NO
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#ifndef DtSvcDefines
|
||||
# define DtSvcDefines -DXK_MISCELLANY -DMULTIBYTE
|
||||
#endif
|
||||
DEFINES = DtSvcDefines
|
||||
INCLUDES = -I. -I../include
|
||||
|
||||
#if defined(RsArchitecture)
|
||||
CXXEXTRA_DEFINES = -qlanglvl=compat
|
||||
#endif
|
||||
|
||||
|
||||
SRCS = buf.C filegen.C mbschr.C \
|
||||
pathcollapse.C shellscan.C strend.C \
|
||||
strhash.C stringio.C strtokx.C \
|
||||
strwcmp.C privbuf.C strcase.C
|
||||
|
||||
/* WARNING!!!!
|
||||
* Any .o's added to this list need to be added to DTCODELIBS_OBJS3
|
||||
* and SHARED_DTCODELIBS_OBJS3 in the DtSvc Imakefile.
|
||||
*/
|
||||
OBJS = buf.o filegen.o mbschr.o \
|
||||
pathcollapse.o shellscan.o strend.o \
|
||||
strhash.o stringio.o strtokx.o \
|
||||
strwcmp.o privbuf.o strcase.o
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SubdirLibraryRule($(OBJS))
|
||||
|
||||
DependTarget()
|
||||
105
cde/lib/DtSvc/DtCodelibs/buf.C
Normal file
105
cde/lib/DtSvc/DtCodelibs/buf.C
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* File: buf.C $TOG: buf.C /main/5 1998/01/21 18:01:14 mgreess $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include "buf.h"
|
||||
|
||||
void
|
||||
_SHXbuf::start_token()
|
||||
{
|
||||
vec[vec.size()] = (char *)buf.size();
|
||||
is_pattern = FALSE;
|
||||
_new_token = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::quote(Quote q)
|
||||
{
|
||||
_quote ^= q;
|
||||
if (_new_token)
|
||||
start_token();
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::append(int const ch, char flag)
|
||||
{
|
||||
flag |= _quote;
|
||||
|
||||
if (ch == '\0' && !_new_token)
|
||||
_new_token = TRUE;
|
||||
else if (_new_token)
|
||||
start_token();
|
||||
|
||||
if (flag == NOQUOTE)
|
||||
if (ch == '*' || ch == '?' || ch == '[')
|
||||
if (glob)
|
||||
is_pattern = TRUE;
|
||||
else
|
||||
flag |= SINGLEQUOTE;
|
||||
|
||||
if (ch <= 0xFF)
|
||||
{
|
||||
// 8-bit char
|
||||
flags[buf.size()] = flag;
|
||||
buf[buf.size()] = (unsigned char)ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
// multibyte char
|
||||
long sz = buf.size();
|
||||
|
||||
for (int i=0; i<MB_CUR_MAX; i++) flags[sz+i] = flag;
|
||||
buf.reset(sz + MB_CUR_MAX);
|
||||
char *cp = &buf.elt(sz);
|
||||
WCHAR(ch, cp);
|
||||
}
|
||||
|
||||
// expand token into filename(s) if appropriate
|
||||
if (ch == '\0' && (is_pattern || completion))
|
||||
if (!(flag & EXPANDQUOTE))
|
||||
filegen();
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::append(char const *cp, char flag)
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
do
|
||||
append((int)CHARAT(cp), flag);
|
||||
while (CHARADV(cp) != '\0');
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::reset(boolean g, boolean comp)
|
||||
{
|
||||
glob = (boolean) !!g;
|
||||
completion = (boolean ) !!comp;
|
||||
is_pattern = FALSE;
|
||||
_new_token = TRUE;
|
||||
_quote = NOQUOTE;
|
||||
buf.reset(0);
|
||||
flags.reset(0);
|
||||
vec.reset(0);
|
||||
}
|
||||
|
||||
// Convert the subscripts that are stored in vec[] into
|
||||
// char pointers. The only legal operation on _SHXbuf after
|
||||
// calling vector is to call reset.
|
||||
char **
|
||||
_SHXbuf::vector()
|
||||
{
|
||||
for (int i = 0; i < vec.size(); i++)
|
||||
vec[i] = &buf[long(vec[i])];
|
||||
|
||||
vec[i] = NULL;
|
||||
|
||||
return vec.getarr();
|
||||
}
|
||||
49
cde/lib/DtSvc/DtCodelibs/buf.h
Normal file
49
cde/lib/DtSvc/DtCodelibs/buf.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* File: buf.h $XConsortium: buf.h /main/3 1995/10/26 16:07:20 rswiston $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <codelibs/boolean.h>
|
||||
#define __PRIVATE_
|
||||
#include <codelibs/privbuf.h>
|
||||
|
||||
#define NOQUOTE 0
|
||||
#define SINGLEQUOTE 1
|
||||
#define DOUBLEQUOTE 2
|
||||
#define EXPANDQUOTE 4
|
||||
|
||||
typedef unsigned char Quote;
|
||||
|
||||
class _SHXcomponents;
|
||||
|
||||
class _SHXbuf
|
||||
{
|
||||
boolean glob;
|
||||
boolean completion;
|
||||
boolean is_pattern;
|
||||
Quote _quote;
|
||||
boolean _new_token;
|
||||
privbuf_charbuf buf;
|
||||
privbuf_charbuf flags;
|
||||
privbuf_strvec vec;
|
||||
void start_token();
|
||||
void filegen();
|
||||
void expand(_SHXcomponents&, char* const, char*, int);
|
||||
public:
|
||||
_SHXbuf() {reset(TRUE, FALSE);}
|
||||
void reset(boolean glob, boolean completion);
|
||||
void append(int const ch, char flag = 0);
|
||||
void append(char const *cp, char flag = 0);
|
||||
int ntokens() {return vec.size();}
|
||||
boolean new_token() {return _new_token;}
|
||||
Quote quote() {return _quote;}
|
||||
void quote(Quote);
|
||||
char **vector();
|
||||
};
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
281
cde/lib/DtSvc/DtCodelibs/filegen.C
Normal file
281
cde/lib/DtSvc/DtCodelibs/filegen.C
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* File: filegen.C $TOG: filegen.C /main/7 1999/10/14 15:05:25 mgreess $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#define X_INCLUDE_DIRENT_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <codelibs/stringx.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include "buf.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
#ifdef XTHREADS
|
||||
extern "C" {
|
||||
extern void XtProcessLock(void);
|
||||
extern void XtProcessUnlock(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct _SHXcomponent
|
||||
{
|
||||
boolean is_pattern;
|
||||
long offset; // subscript in path buffer
|
||||
char *ptr; // pointer into path buffer
|
||||
};
|
||||
|
||||
declare_array(_SHXcomponents, _SHXcomponent, 4)
|
||||
|
||||
// recursive routine to expand the wildcard path represented in stack into
|
||||
// all possible expansions. The expansions are appended to _SHXbuf::vec.
|
||||
// filebuf is a scratch buffer passed in by the caller and is used to build
|
||||
// intermediate paths. end is a pointer to the position in filebuf where
|
||||
// the calling routine left off.
|
||||
void
|
||||
_SHXbuf::expand(_SHXcomponents &stack,
|
||||
char *const filebuf, char *end, int compnum)
|
||||
{
|
||||
*end = '\0';
|
||||
|
||||
if (compnum == stack.size())
|
||||
return;
|
||||
|
||||
_SHXcomponent &comp = stack[compnum];
|
||||
|
||||
// double-slash?
|
||||
if (comp.ptr[0] == '\0')
|
||||
{
|
||||
if (compnum + 1 == stack.size())
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
else
|
||||
{
|
||||
*end++ = '/';
|
||||
expand(stack, filebuf, end, compnum + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// performance optimization: if this path component
|
||||
// doesn't contain a wildcard, avoid doing an opendir()
|
||||
if (!comp.is_pattern)
|
||||
{
|
||||
strcpy(end, comp.ptr);
|
||||
if (compnum + 1 == stack.size())
|
||||
{
|
||||
// last component, just see if the path really points to something
|
||||
if (access(filebuf, F_OK) != -1)
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// intermediate directory just append this component and keep going
|
||||
char *end2 = strend(end);
|
||||
*end2++ = '/';
|
||||
expand(stack, filebuf, end2, compnum + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a wildcard component, open and scan its parent directory
|
||||
// and look for matches.
|
||||
DIR *dir = opendir(filebuf[0] == '\0' ? "." : filebuf);
|
||||
if (dir == NULL)
|
||||
return;
|
||||
|
||||
_Xreaddirparams dir_buf;
|
||||
struct dirent *ent;
|
||||
|
||||
memset((char*) &dir_buf, 0, sizeof(_Xreaddirparams));
|
||||
while ((ent = _XReaddir(dir, dir_buf)) != NULL)
|
||||
{
|
||||
// deleted file?
|
||||
if (ent->d_ino == 0 || ent->d_name[0] == '\0')
|
||||
continue;
|
||||
|
||||
// right name?
|
||||
if (comp.is_pattern)
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
// Must have explicit match for leading '.'
|
||||
if (CHARAT(ent->d_name) == '.' && CHARAT(comp.ptr) != '.')
|
||||
continue;
|
||||
|
||||
if (strwcmp(comp.ptr, ent->d_name) != 0)
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(comp.ptr, ent->d_name) != 0)
|
||||
continue;
|
||||
|
||||
strcpy(end, ent->d_name);
|
||||
if (compnum + 1 == stack.size())
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
else
|
||||
{
|
||||
char *end2 = end + strlen (ent->d_name);
|
||||
*end2++ = '/';
|
||||
expand(stack, filebuf, end2, compnum + 1);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
|
||||
//extern "C" { void qsort(void *, unsigned, int, ...); };
|
||||
|
||||
static char *bufptr;
|
||||
|
||||
static int
|
||||
//compar(int &v1, int &v2)
|
||||
compar(const void *v1, const void *v2)
|
||||
{
|
||||
int result;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
result = strcmp(&bufptr[*(int*)v1], &bufptr[*(int*)v2]);
|
||||
_DtSvcProcessUnlock();
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
_SHXbuf::filegen()
|
||||
{
|
||||
privbuf_charbuf path;
|
||||
_SHXcomponents stack;
|
||||
|
||||
long vecstart = vec.size() - 1;
|
||||
if (vecstart < 0)
|
||||
return;
|
||||
|
||||
long bufstart = long(vec[vecstart]);
|
||||
|
||||
// Parse the file path, breaking it up into individual components.
|
||||
// Each component is marked as being either a wildcard component
|
||||
// or not. The wildcard components will have a '\' placed before
|
||||
// any quoted wildcard characters. The non-wildcard components
|
||||
// will be left unchanged.
|
||||
int bufpos = (int) bufstart;
|
||||
while (bufpos < buf.size())
|
||||
{
|
||||
_SHXcomponent & comp = stack[stack.size()];
|
||||
comp.is_pattern = FALSE;
|
||||
comp.offset = path.size();
|
||||
comp.ptr = NULL;
|
||||
int startpos = bufpos;
|
||||
|
||||
int ch;
|
||||
do
|
||||
{
|
||||
ch = buf[bufpos];
|
||||
switch (ch)
|
||||
{
|
||||
case '/':
|
||||
ch = '\0';
|
||||
break;
|
||||
case '*':
|
||||
case '?':
|
||||
case '[':
|
||||
if (flags[bufpos] == NOQUOTE)
|
||||
comp.is_pattern = TRUE;
|
||||
else
|
||||
path[path.size()] = '\\';
|
||||
break;
|
||||
}
|
||||
|
||||
path[path.size()] = ch;
|
||||
bufpos++;
|
||||
} while (ch != '\0');
|
||||
|
||||
// Add a '*' to the end of the last component if needed
|
||||
// for completion.
|
||||
if (bufpos >= buf.size()) // last component?
|
||||
if (bufpos > bufstart + 1) // non-null string?
|
||||
if (completion && !is_pattern)
|
||||
{
|
||||
path[path.size() - 1] = '*';
|
||||
path[path.size()] = '\0';
|
||||
comp.is_pattern = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// If it wasn't a pattern, remove all of the '\' characters
|
||||
// that were added.
|
||||
if (!comp.is_pattern)
|
||||
{
|
||||
int len = bufpos - startpos - 1;
|
||||
strncpy(&path[comp.offset], &buf[startpos], len);
|
||||
path[comp.offset + len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the character pointer values for all of the components.
|
||||
// We couldn't do this in the first pass because path is a
|
||||
// dynamic array.
|
||||
char *pathbuf = path.getarr();
|
||||
for (int i = 0; i < stack.size(); i++)
|
||||
stack[i].ptr = &pathbuf[stack[i].offset];
|
||||
|
||||
// Remove the token that we just copied from the return vector
|
||||
// so that we can replace it with its expansion.
|
||||
vec.reset(vecstart);
|
||||
|
||||
char filebuf[MAXPATHLEN];
|
||||
expand(stack, filebuf, filebuf, 0);
|
||||
|
||||
if (vec.size() == vecstart) // no matches?
|
||||
{
|
||||
vec[vecstart] = (char *)bufstart; // restore orig. token
|
||||
return;
|
||||
}
|
||||
|
||||
// alphabetize the expansion to make it look pretty like ksh does.
|
||||
_DtSvcProcessLock();
|
||||
bufptr = buf.getarr();
|
||||
qsort(&vec[vecstart], (unsigned int)(vec.size() - vecstart),
|
||||
sizeof (char *), compar);
|
||||
|
||||
// Find the longest match if we are doing completion:
|
||||
if (completion)
|
||||
{
|
||||
// compare all entries to a copy of the first entry
|
||||
strcpy(filebuf, &bufptr[long(vec[0])]);
|
||||
|
||||
for (long i = 1; i < vec.size(); i++)
|
||||
{
|
||||
register char *ref = filebuf;
|
||||
register char *ptr = &bufptr[long(vec[i])];
|
||||
while (*ref == *ptr && *ref != '\0' && *ptr != '\0')
|
||||
ref++, ptr++;
|
||||
|
||||
*ref = '\0'; // shorten the reference copy
|
||||
}
|
||||
|
||||
// Now store the best match as the first token. We will
|
||||
// have to shift the expansion vector down by one to
|
||||
// make room.
|
||||
for (i = vec.size(); i > 0; --i)
|
||||
{
|
||||
register char *val = vec[i - 1];
|
||||
vec[i] = val;
|
||||
}
|
||||
vec[0] = (char *)buf.size();
|
||||
append(filebuf, EXPANDQUOTE);
|
||||
vec.reset(vec.size() - 1); // adjust for the append
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
implement_array(_SHXcomponents, _SHXcomponent, 4)
|
||||
36
cde/lib/DtSvc/DtCodelibs/mbschr.C
Normal file
36
cde/lib/DtSvc/DtCodelibs/mbschr.C
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* $XConsortium: mbschr.C /main/5 1996/06/21 17:36:36 ageorge $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <codelibs/mbstring.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
#if defined(__cplusplus) || defined(__STDC__)
|
||||
char *
|
||||
_mb_schr(const char *str, wchar_t ch)
|
||||
#else
|
||||
char *
|
||||
_mb_schr(str, ch)
|
||||
register unsigned char *str;
|
||||
register wchar_t ch;
|
||||
#endif
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
for (; *str != '\0'; ADVANCE(str))
|
||||
if (CHARAT(str) == ch)
|
||||
return (char *)str;
|
||||
|
||||
return (char *)0;
|
||||
}
|
||||
162
cde/lib/DtSvc/DtCodelibs/pathcollapse.C
Normal file
162
cde/lib/DtSvc/DtCodelibs/pathcollapse.C
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* $XConsortium: pathcollapse.C /main/5 1996/06/21 17:36:32 ageorge $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
|
||||
#include "/usr/include/apollo/shlib.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/pathutils.h>
|
||||
|
||||
#define SEP(P) (CHARAT(P) == '\0' || CHARAT(P) == '/')
|
||||
#define DOT(P) (CHARAT(P) == '.' && SEP((P) + 1))
|
||||
#define DOTDOT(P) (CHARAT(P) == '.' && DOT((P) + 1))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char *
|
||||
pathcollapse(const char *src, char *dst, boolean show_dir)
|
||||
{
|
||||
int ch;
|
||||
const char *srcp;
|
||||
char *dstp, *sep;
|
||||
char *components[MAXPATHLEN / 2 + 1];
|
||||
char **comp = components;
|
||||
int length = src == NULL ? 0 : strlen(src);
|
||||
int dir_comp; /* TRUE if last component was . or .. */
|
||||
#ifdef apollo
|
||||
int double_slash = 0;
|
||||
#endif
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (length == 0 || length > MAXPATHLEN)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dst == NULL)
|
||||
if ((dst = (char *)malloc(length + 1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef apollo
|
||||
/*
|
||||
* On apollo, a leading double-slash must be preserved, so we
|
||||
* copy the first slash and hide it from the rest of the code.
|
||||
*/
|
||||
if (CHARAT(src) == '/' && CHARAT(src + 1) == '/')
|
||||
{
|
||||
*dst++ = '/';
|
||||
src++;
|
||||
double_slash = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
srcp = src;
|
||||
dstp = dst;
|
||||
|
||||
do /* for each component of src */
|
||||
{
|
||||
*comp = dstp;
|
||||
|
||||
/* copy the component and trailing separator to dst */
|
||||
do
|
||||
{
|
||||
ch = (int)CHARAT(srcp);
|
||||
sep = dstp;
|
||||
WCHARADV(ch, dstp);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
ADVANCE(srcp);
|
||||
} while (ch != '/');
|
||||
|
||||
dir_comp = ch == '/'; /* true if trailing '/' */
|
||||
|
||||
/* skip all adjacent '/' characters [the first is preserved] */
|
||||
while (CHARAT(srcp) == '/')
|
||||
ADVANCE(srcp);
|
||||
|
||||
/* remove redundant trailing slash */
|
||||
if (CHARAT(srcp) == '\0')
|
||||
if (sep > dst)
|
||||
*sep = ch = '\0';
|
||||
|
||||
if (DOT(*comp))
|
||||
{
|
||||
dir_comp = 1;
|
||||
dstp = *comp;
|
||||
if (dstp > dst)
|
||||
{
|
||||
sep = dstp - 1;
|
||||
*dstp = '\0';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (DOTDOT(*comp))
|
||||
{
|
||||
dir_comp = 1;
|
||||
if (*comp > dst)
|
||||
{
|
||||
comp--;
|
||||
if (!DOTDOT(*comp))
|
||||
{
|
||||
dstp = *comp;
|
||||
if (dstp > dst)
|
||||
{
|
||||
sep = dstp - 1;
|
||||
*dstp = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CHARAT(dst) == '/')
|
||||
{
|
||||
/* /.. is same as / */
|
||||
dstp = dst + 1;
|
||||
*dstp = '\0';
|
||||
comp++;
|
||||
}
|
||||
else
|
||||
dst[0] = '.';
|
||||
sep = dst + 1;
|
||||
*sep = '\0';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
comp++;
|
||||
} while (ch != '\0');
|
||||
|
||||
if (show_dir)
|
||||
{
|
||||
if (dir_comp && (sep > dst + 1 || dst[0] != '/'))
|
||||
{
|
||||
*sep++ = '/';
|
||||
*sep = '\0';
|
||||
}
|
||||
}
|
||||
else if (sep > dst)
|
||||
*sep = '\0'; /* remove trailing '/' */
|
||||
|
||||
#ifdef apollo
|
||||
if (double_slash)
|
||||
dst--;
|
||||
#endif
|
||||
|
||||
return dst;
|
||||
}
|
||||
43
cde/lib/DtSvc/DtCodelibs/privbuf.C
Normal file
43
cde/lib/DtSvc/DtCodelibs/privbuf.C
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $XConsortium: privbuf.C /main/4 1996/04/21 19:09:31 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#define __PRIVATE_
|
||||
#include <codelibs/privbuf.h>
|
||||
|
||||
implement_array(privbuf_charbuf, char, 128)
|
||||
implement_array(privbuf_strvec, char*, 128)
|
||||
|
||||
void privbuf_release(void **var)
|
||||
{
|
||||
if (var == NULL || *var == NULL)
|
||||
return;
|
||||
char *buf = (char*)*var;
|
||||
privbuf_func *p = (privbuf_func*)(void*)buf;
|
||||
*var = NULL;
|
||||
(*p)((void*)buf);
|
||||
}
|
||||
|
||||
void privbuf_freeprivbuf(void *buf)
|
||||
{
|
||||
privbuf_buffer *b = (privbuf_buffer*)buf;
|
||||
//delete b->buf;
|
||||
//delete b->vec;
|
||||
delete b;
|
||||
}
|
||||
|
||||
privbuf_buffer *privbuf_allocprivbuf()
|
||||
{
|
||||
privbuf_buffer *b = new privbuf_buffer;
|
||||
b->func = privbuf_freeprivbuf;
|
||||
//b->buf = new privbuf_charbuf;
|
||||
//b->vec = new privbuf_strvec;
|
||||
return b;
|
||||
}
|
||||
480
cde/lib/DtSvc/DtCodelibs/shellscan.C
Normal file
480
cde/lib/DtSvc/DtCodelibs/shellscan.C
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* $TOG: shellscan.C /main/9 1999/10/14 15:05:42 mgreess $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
# if defined(apollo) && !defined(___GID_T)
|
||||
// This kludge is needed for the include conflicts mentioned below
|
||||
// Remove when no longer necessary
|
||||
# define _NEED___PID_T
|
||||
# endif
|
||||
|
||||
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
|
||||
#include "/usr/include/apollo/shlib.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define X_INCLUDE_PWD_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
|
||||
#ifdef apollo
|
||||
// This kludge because of include conflicts between stdlib.h and unistd.h
|
||||
// Remove when problem is fixed
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
_DECL_FUNC(__pid_t, getpid, (void))
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
#else /* not apollo */
|
||||
# include <unistd.h>
|
||||
#endif /* not apollo */
|
||||
|
||||
#include "stringio.h"
|
||||
#include "buf.h"
|
||||
#include <codelibs/shellutils.h>
|
||||
|
||||
#include <codelibs/boolean.h>
|
||||
#include <codelibs/stringx.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#ifdef XTHREADS
|
||||
extern "C" {
|
||||
extern void XtProcessLock(void);
|
||||
extern void XtProcessUnlock(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ISIDENT(CH) (isalnum(CH) || (CH) == '_')
|
||||
|
||||
static _SHXbuf *buf = NULL;
|
||||
static const char *getvar(const char *var, char *);
|
||||
|
||||
// Make this a global someday:
|
||||
static const char *(*shellvarfn)(const char *, char *) = getvar;
|
||||
|
||||
// Parse a sequence of the ksh meta-characters ;&|<> and whitespace
|
||||
// into a single ksh token. Return a pointer to the token as a
|
||||
// string. All whitespace characters are mapped to a single space
|
||||
// character. If ch is not a meta-character, return a NULL pointer.
|
||||
static char *
|
||||
parsemeta(int ch, _StringIO &in, char *ifs, unsigned opts, char *meta)
|
||||
{
|
||||
if (ch == '\0')
|
||||
return " "; // whitespace
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (buf->quote() != NOQUOTE) {
|
||||
_DtSvcProcessUnlock();
|
||||
return NULL; // normal character
|
||||
}
|
||||
|
||||
if (!(opts & SHX_NOSPACE) && strchr(ifs, ch) != NULL) {
|
||||
_DtSvcProcessUnlock();
|
||||
return " "; // whitespace
|
||||
}
|
||||
|
||||
if (!(opts & SHX_NOMETA))
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (buf->new_token() && isascii(ch) && isdigit(ch))
|
||||
if (in.next() == '<' || in.next() == '>')
|
||||
{
|
||||
meta[len++] = (char)ch;
|
||||
ch = in.get();
|
||||
}
|
||||
|
||||
switch (meta[len++] = (char)ch, ch)
|
||||
{
|
||||
case ';':
|
||||
case '&':
|
||||
case '(':
|
||||
case ')':
|
||||
meta[len++] = (in.next() == ch) ? in.get() : '\0';
|
||||
meta[len] = '\0';
|
||||
_DtSvcProcessUnlock();
|
||||
return meta;
|
||||
case '|':
|
||||
meta[len++] = (in.next() == '|' || in.next() == '&') ?
|
||||
in.get() : '\0';
|
||||
meta[len] = '\0';
|
||||
_DtSvcProcessUnlock();
|
||||
return meta;
|
||||
case '>':
|
||||
case '<':
|
||||
if (in.next() == ch || in.next() == '&')
|
||||
meta[len++] = (char)in.get();
|
||||
meta[len] = '\0';
|
||||
_DtSvcProcessUnlock();
|
||||
return meta;
|
||||
}
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return NULL; // normal character
|
||||
}
|
||||
|
||||
// Takes the name of a variable, and looks up it's value. Someday,
|
||||
// this will be replaceable by the user.
|
||||
static const char *
|
||||
getvar(const char *name, char *buff)
|
||||
{
|
||||
if (name[0] != '\0' && name[1] == '\0')
|
||||
switch (name[0])
|
||||
{
|
||||
case '$':
|
||||
sprintf(buff, "%d", getpid());
|
||||
return buff;
|
||||
case '#':
|
||||
case '?':
|
||||
return "0";
|
||||
}
|
||||
|
||||
return getenv(name);
|
||||
}
|
||||
|
||||
// Parse an environment variable name from the _StringIO stream,
|
||||
// and push its value into the _StringIO stream stack.
|
||||
static boolean
|
||||
pushvar(_StringIO &in, char *buff)
|
||||
{
|
||||
_StringIO tmp;
|
||||
privbuf_charbuf name;
|
||||
|
||||
tmp = in;
|
||||
int ch = tmp.get(); // get the first character after the $
|
||||
|
||||
if (!isascii(ch))
|
||||
return FALSE;
|
||||
|
||||
if (ch == '{')
|
||||
while ((ch = tmp.get()) != '\0')
|
||||
{
|
||||
// ${foo!bar} form, grab everything inside {} as name
|
||||
if (ch == '\\') // Only \ does quoting inside ${}
|
||||
ch = tmp.get();
|
||||
else if (ch == '}')
|
||||
break;
|
||||
name.end() = ch;
|
||||
}
|
||||
else if (ispunct(ch))
|
||||
switch (ch) // Special non-alnum shell variables
|
||||
{
|
||||
case '#':
|
||||
case '?':
|
||||
case '$':
|
||||
case '!':
|
||||
case '-':
|
||||
case '*':
|
||||
case '@':
|
||||
case '_':
|
||||
name.end() = ch;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
else if (isdigit(ch))
|
||||
name.end() = ch; // single-digit variables
|
||||
else if (ISIDENT(ch))
|
||||
{
|
||||
// normal variable
|
||||
do
|
||||
name.end() = ch;
|
||||
while (isascii(ch = tmp.get()) && ISIDENT(ch));
|
||||
tmp.unget();
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
name.end() = '\0';
|
||||
|
||||
in = tmp;
|
||||
in.push(shellvarfn(name.getarr(), buff));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
pushenv(_StringIO &in, char const *name)
|
||||
{
|
||||
register char *str = getenv(name);
|
||||
if (str == NULL || *str == '\0')
|
||||
return FALSE;
|
||||
else
|
||||
{
|
||||
in.push(str);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
pushtilde(_StringIO &in)
|
||||
{
|
||||
_StringIO tmp;
|
||||
int namelen = 0;
|
||||
privbuf_charbuf name;
|
||||
|
||||
tmp = in;
|
||||
int ch;
|
||||
|
||||
while ((ch = tmp.get()) != '\0' && ch != '/')
|
||||
name[namelen++] = ch;
|
||||
name[namelen] = '\0';
|
||||
tmp.unget();
|
||||
|
||||
char *str = name.getarr();
|
||||
switch (*str)
|
||||
{
|
||||
case '\0':
|
||||
if (!pushenv(tmp, "HOME"))
|
||||
return FALSE;
|
||||
break;
|
||||
case '+':
|
||||
if (!pushenv(tmp, "PWD"))
|
||||
return FALSE;
|
||||
break;
|
||||
case '-':
|
||||
if (!pushenv(tmp, "OLDPWD"))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
_Xgetpwparams pwd_buf;
|
||||
memset((char*) &pwd_buf, 0, sizeof(_Xgetpwparams));
|
||||
struct passwd * pwd_ret = _XGetpwnam(str, pwd_buf);
|
||||
|
||||
if (pwd_ret == NULL)
|
||||
return FALSE;
|
||||
tmp.push(pwd_ret->pw_dir);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
in = tmp;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
pushgrave(_StringIO &in, const char endchar, boolean quotes, privbuf_charbuf &result)
|
||||
{
|
||||
int ch;
|
||||
char quote = NOQUOTE;
|
||||
privbuf_charbuf cmd;
|
||||
|
||||
do
|
||||
{
|
||||
ch = in.get();
|
||||
|
||||
if (quotes)
|
||||
switch (ch)
|
||||
{
|
||||
case '"':
|
||||
quote = DOUBLEQUOTE;
|
||||
continue;
|
||||
case '\'':
|
||||
if (quote == '"')
|
||||
break; // not recognized inside of ""
|
||||
do
|
||||
cmd.end() = ch;
|
||||
while ((ch = in.get()) != '\'' && ch != '\0');
|
||||
cmd.end() = '\'';
|
||||
quote = NOQUOTE;
|
||||
continue;
|
||||
case '\\':
|
||||
cmd.end() = ch;
|
||||
ch = in.get();
|
||||
if (ch != '\0')
|
||||
cmd.end() = ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == endchar)
|
||||
ch = '\0';
|
||||
|
||||
cmd.end() = ch;
|
||||
} while (ch != '\0');
|
||||
|
||||
result.reset();
|
||||
|
||||
FILE *fp = popen(cmd.getarr(), "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
while ((ch = getc(fp)) != EOF)
|
||||
result.end() = ch;
|
||||
pclose(fp);
|
||||
|
||||
// Remove trailing newline, if any
|
||||
long end = result.size() - 1;
|
||||
if (result[end] == '\n')
|
||||
result.reset(end);
|
||||
|
||||
result.end() = '\0';
|
||||
in.push(result.getarr());
|
||||
}
|
||||
|
||||
char const *const *
|
||||
shellscan(char const *str, int *argc, unsigned opts)
|
||||
{
|
||||
if (opts & SHX_COMPLETE)
|
||||
opts |= SHX_NOSPACE | SHX_NOMETA;
|
||||
|
||||
char *ifs = getenv("IFS");
|
||||
|
||||
if (ifs == NULL)
|
||||
ifs = " \t\n";
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (buf == NULL)
|
||||
buf = new _SHXbuf;
|
||||
buf->reset((boolean)!(opts & SHX_NOGLOB), (boolean)(opts & SHX_COMPLETE));
|
||||
|
||||
_StringIO in(str);
|
||||
int ch;
|
||||
char buff[10], meta_buff[4];
|
||||
privbuf_charbuf result;
|
||||
|
||||
do
|
||||
{
|
||||
ch = in.get();
|
||||
|
||||
// Don't recognize special characters if this is a shell
|
||||
// variable or command substitution.
|
||||
if (!in.in_expansion())
|
||||
{
|
||||
// Handle quoting rules, setting the flag array and
|
||||
// quote variable appropriately.
|
||||
if (!(opts & SHX_NOQUOTES))
|
||||
switch (ch)
|
||||
{
|
||||
case '"':
|
||||
buf->quote(DOUBLEQUOTE);
|
||||
continue;
|
||||
case '\'':
|
||||
if (buf->quote() == DOUBLEQUOTE)
|
||||
break; // not recognized inside of ""
|
||||
buf->quote(SINGLEQUOTE);
|
||||
while ((ch = in.get()) != '\'' && ch != '\0')
|
||||
buf->append(ch);
|
||||
buf->quote(SINGLEQUOTE);
|
||||
continue;
|
||||
case '\\':
|
||||
ch = in.get();
|
||||
if (ch == '\n') // ignore \<newline>
|
||||
continue;
|
||||
if (ch == '\0')
|
||||
{
|
||||
#if defined(__aix) /* Our Macro doesn't like '\\' (ignores rest of line) */
|
||||
buf->append('\\',
|
||||
SINGLEQUOTE);
|
||||
#else
|
||||
buf->append('\\', SINGLEQUOTE);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (buf->quote() == NOQUOTE)
|
||||
{
|
||||
buf->append(ch, SINGLEQUOTE);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// inside "", \ only quotes these 4 characters:
|
||||
switch (ch)
|
||||
{
|
||||
case '$':
|
||||
case '\\':
|
||||
case '`':
|
||||
case '"':
|
||||
buf->append(ch, SINGLEQUOTE);
|
||||
continue;
|
||||
default:
|
||||
// treat the \ and the following char normally
|
||||
buf->append('\\');
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(opts & SHX_NOCMD))
|
||||
switch (ch)
|
||||
{
|
||||
case '`':
|
||||
pushgrave(in, '`', (boolean)!(opts & SHX_NOQUOTES), result);
|
||||
continue;
|
||||
case '$':
|
||||
if (in.next() != '(')
|
||||
break;
|
||||
in.get(); // skip the '('
|
||||
pushgrave(in, ')', (boolean)!(opts & SHX_NOQUOTES), result);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '~' && buf->new_token() && buf->quote() == NOQUOTE)
|
||||
if (!(opts & SHX_NOTILDE))
|
||||
{
|
||||
if (pushtilde(in))
|
||||
continue;
|
||||
buf->append('~');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '$' && !(opts & SHX_NOVARS))
|
||||
{
|
||||
if (pushvar(in, buff))
|
||||
continue;
|
||||
buf->append('$');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If the next item is an unquoted whitespace character or
|
||||
// metacharacter token, terminate the current token. The NUL
|
||||
// character is considered to be whitespace.
|
||||
{
|
||||
int curr_opts = opts;
|
||||
|
||||
if (in.in_expansion())
|
||||
curr_opts |= SHX_NOMETA;
|
||||
|
||||
char *meta = parsemeta(ch, in, ifs, curr_opts, meta_buff);
|
||||
|
||||
if (meta != NULL) // is it a meta-character?
|
||||
{
|
||||
// Terminate current token, if any
|
||||
if (!buf->new_token())
|
||||
buf->append('\0');
|
||||
if (*meta == ' ') // whitespace
|
||||
{
|
||||
// ignore contiguous whitespace chars
|
||||
if (buf->new_token())
|
||||
continue;
|
||||
}
|
||||
else // append the metachar token
|
||||
buf->append(meta);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
buf->append(ch);
|
||||
} while (ch != '\0');
|
||||
|
||||
if (argc != NULL)
|
||||
*argc = buf->ntokens();
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return ( (char const *const *) buf->vector() );
|
||||
/* !!! error 1325: `)' missing at end of input */
|
||||
}
|
||||
46
cde/lib/DtSvc/DtCodelibs/strcase.C
Normal file
46
cde/lib/DtSvc/DtCodelibs/strcase.C
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $XConsortium: strcase.C /main/4 1996/04/21 19:09:37 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
char *strupper(char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (str != NULL)
|
||||
{
|
||||
for (register char *s = str; *s != '\0'; s++)
|
||||
if ((len = mblen(s, MB_CUR_MAX)) > 1)
|
||||
s += len;
|
||||
else
|
||||
*s = toupper((unsigned char)*s);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char *strlower(char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (str != NULL)
|
||||
{
|
||||
for (register char *s = str; *s != '\0'; s++)
|
||||
if ((len = mblen(s, MB_CUR_MAX)) > 1)
|
||||
s += len;
|
||||
else
|
||||
*s = tolower((unsigned char)*s);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
24
cde/lib/DtSvc/DtCodelibs/strend.C
Normal file
24
cde/lib/DtSvc/DtCodelibs/strend.C
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* $XConsortium: strend.C /main/4 1996/04/21 19:09:40 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
char *
|
||||
strend(register const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*str != '\0')
|
||||
str++;
|
||||
|
||||
return (char *)str;
|
||||
}
|
||||
112
cde/lib/DtSvc/DtCodelibs/strhash.C
Normal file
112
cde/lib/DtSvc/DtCodelibs/strhash.C
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* $XConsortium: strhash.C /main/5 1996/06/21 17:36:23 ageorge $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
|
||||
/**************************************************
|
||||
// This is quick but does a pretty crummy job
|
||||
unsigned strhash(register const unsigned char *key)
|
||||
{
|
||||
register unsigned hash = 0;
|
||||
while (*key != '\0')
|
||||
hash = (hash << 3) + *key++;
|
||||
return hash;
|
||||
}
|
||||
**************************************************/
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define BITS(type) (CHAR_BIT * (int)sizeof(type))
|
||||
|
||||
// This is from the "dragon" Compilers book.
|
||||
// It is much better than the above but somewhat slower.
|
||||
//
|
||||
unsigned strhash(register const char *p)
|
||||
{
|
||||
register unsigned h = 0;
|
||||
register unsigned g;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (p != NULL)
|
||||
while (*p != '\0')
|
||||
{
|
||||
h = (h << 4) + (unsigned)CHARADV(p);
|
||||
if (g = h & ((unsigned)0xF << BITS(unsigned) - 4))
|
||||
{
|
||||
h ^= g >> BITS(unsigned) - 4;
|
||||
h ^= g;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
// Same as above but case insensitive. Returns the same value as the
|
||||
// above function if there are no upper case letters in the string.
|
||||
//
|
||||
unsigned strhashi(register const char *p)
|
||||
{
|
||||
register unsigned h = 0;
|
||||
register unsigned g;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (p != NULL)
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (mblen(p, MB_CUR_MAX) > 1)
|
||||
h = (h << 4) + (unsigned)CHARADV(p);
|
||||
else
|
||||
{
|
||||
h = (h << 4) + (unsigned)tolower(*p++);
|
||||
}
|
||||
|
||||
if (g = h & ((unsigned)0xF << BITS(unsigned) - 4))
|
||||
{
|
||||
h ^= g >> BITS(unsigned) - 4;
|
||||
h ^= g;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
// This is about twice as slow as the above but
|
||||
// does a slightly better hash.
|
||||
// by TJ Merritt
|
||||
|
||||
unsigned int
|
||||
hashfunc(buf, len)
|
||||
register unsigned char *buf;
|
||||
register int len;
|
||||
{
|
||||
register unsigned int in;
|
||||
register unsigned int xor;
|
||||
register unsigned int t;
|
||||
|
||||
xor = len << 8;
|
||||
in = 0;
|
||||
|
||||
while (len-- > 0)
|
||||
{
|
||||
in <<= 8;
|
||||
in += *buf++;
|
||||
xor ^= in;
|
||||
t = ((xor & 0x3) << 29) | (xor >> 3);
|
||||
xor ^= t;
|
||||
}
|
||||
|
||||
return xor ^ (xor >> 16);
|
||||
}
|
||||
**************************************************/
|
||||
38
cde/lib/DtSvc/DtCodelibs/stringio.C
Normal file
38
cde/lib/DtSvc/DtCodelibs/stringio.C
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* File: stringio.C $XConsortium: stringio.C /main/5 1996/06/21 17:36:19 ageorge $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include "stringio.h"
|
||||
|
||||
int
|
||||
_StringIO::doit(register int commit)
|
||||
{
|
||||
register wchar_t ch;
|
||||
register int cu = curr;
|
||||
register char *ccp;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
for (; cu >= 0; cu--)
|
||||
{
|
||||
ccp = ptr[cu];
|
||||
ch = ccp ? CHARAT(ccp) : '\0';
|
||||
if (ch != '\0')
|
||||
break;
|
||||
}
|
||||
if (commit)
|
||||
{
|
||||
old_curr = curr;
|
||||
if ((curr = cu) >= 0)
|
||||
{
|
||||
old_ccp = (const char *)ccp;
|
||||
ADVANCE(ccp);
|
||||
ptr[curr] = ccp;
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
75
cde/lib/DtSvc/DtCodelibs/stringio.h
Normal file
75
cde/lib/DtSvc/DtCodelibs/stringio.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* File: stringio.h $XConsortium: stringio.h /main/3 1995/10/26 16:10:00 rswiston $
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
#include <codelibs/boolean.h>
|
||||
#define __PRIVATE_
|
||||
#include <codelibs/privbuf.h>
|
||||
|
||||
class _StringIO
|
||||
{
|
||||
privbuf_strvec ptr;
|
||||
int curr;
|
||||
int old_curr;
|
||||
char const *old_ccp;
|
||||
int doit(int commit);
|
||||
public:
|
||||
void push(char const *ccp);
|
||||
_StringIO();
|
||||
_StringIO(char const *ccp);
|
||||
void unget();
|
||||
int get();
|
||||
int next();
|
||||
boolean in_expansion();
|
||||
};
|
||||
|
||||
inline
|
||||
_StringIO::_StringIO()
|
||||
{
|
||||
curr = old_curr = -1;
|
||||
old_ccp = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
_StringIO::push(char const *ccp)
|
||||
{
|
||||
ptr[++curr] = (char*)ccp;
|
||||
}
|
||||
|
||||
inline
|
||||
_StringIO::_StringIO(char const *ccp)
|
||||
{
|
||||
curr = old_curr = -1;
|
||||
old_ccp = 0;
|
||||
push(ccp);
|
||||
}
|
||||
|
||||
inline void
|
||||
_StringIO::unget()
|
||||
{
|
||||
if (curr >= 0)
|
||||
ptr[curr] = (char*)old_ccp;
|
||||
curr = old_curr;
|
||||
}
|
||||
|
||||
inline int
|
||||
_StringIO::get()
|
||||
{
|
||||
return doit(1);
|
||||
}
|
||||
|
||||
inline int
|
||||
_StringIO::next()
|
||||
{
|
||||
return doit(0);
|
||||
}
|
||||
|
||||
inline boolean
|
||||
_StringIO::in_expansion()
|
||||
{
|
||||
return ((boolean)(curr > 0));
|
||||
}
|
||||
46
cde/lib/DtSvc/DtCodelibs/strtokx.C
Normal file
46
cde/lib/DtSvc/DtCodelibs/strtokx.C
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $XConsortium: strtokx.C /main/4 1996/04/21 19:09:46 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <codelibs/mbstring.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
char *
|
||||
strtokx(register char *&ptr, register const char *sep)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
|
||||
// find the beginning of the token
|
||||
register char *ret = ptr;
|
||||
while (*ret != '\0' && _mb_schr(sep, *ret) != NULL)
|
||||
ADVANCE(ret);
|
||||
|
||||
// find the end of the token
|
||||
register char *end = ret;
|
||||
while (*end != '\0' && _mb_schr(sep, *end) == NULL)
|
||||
ADVANCE(end);
|
||||
|
||||
ptr = end;
|
||||
|
||||
// If this isn't the last token, advance pointer and terminate
|
||||
// current token.
|
||||
if (*end != '\0')
|
||||
{
|
||||
ADVANCE(ptr);
|
||||
WCHAR('\0', end);
|
||||
}
|
||||
|
||||
if (*ret == '\0')
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
283
cde/lib/DtSvc/DtCodelibs/strwcmp.C
Normal file
283
cde/lib/DtSvc/DtCodelibs/strwcmp.C
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* $TOG: strwcmp.C /main/7 1998/04/17 11:25:04 mgreess $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <codelibs/nl_hack.h>
|
||||
#include <string.h>
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
#define QUOTE 0x40000000
|
||||
|
||||
#ifdef DEBUG
|
||||
static char tabs[] = " ";
|
||||
# define TABS (&tabs[10 - depth])
|
||||
|
||||
static int
|
||||
RETURN(int ret, int depth)
|
||||
{
|
||||
printf("%sreturning %s\n", TABS,
|
||||
(ret ? "SUCCEEDED" : "FAILED"));
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define RETURN(x,y) (x)
|
||||
#endif
|
||||
|
||||
/* FORWARD */
|
||||
static int match(const char *, const char *, int);
|
||||
static const char *next_patt(const char *, int advance = 1);
|
||||
static int match_class(const char *, char);
|
||||
|
||||
/* INLINE */
|
||||
static int
|
||||
next_char(register const char *pattern, const char **cpp = NULL)
|
||||
{
|
||||
register int ret;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
ret = pattern ? (int)CHARAT(pattern) : '\0';
|
||||
if (ret != '\0')
|
||||
{
|
||||
ADVANCE(pattern);
|
||||
/* AIX needs line broken to get around macro bug (Temporary Fix) */
|
||||
if (ret == '\\' &&
|
||||
CHARAT(pattern) != '\0')
|
||||
ret = QUOTE | (int)CHARADV(pattern);
|
||||
}
|
||||
|
||||
if (cpp != NULL)
|
||||
*cpp = pattern;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
strwcmp(const char *pattern, const char *string)
|
||||
/*
|
||||
* String 'pattern' is matched against string 'string'. Zero is
|
||||
* returned if the match is successful. 'pattern' may contain the
|
||||
* shell metas * and ? and the semantics are the same. ? and * may
|
||||
* be escaped with \
|
||||
*/
|
||||
{
|
||||
return !match(pattern, string, 0);
|
||||
}
|
||||
|
||||
// stwpat returns a pointer to the first meta-character if the string
|
||||
// is a pattern, else NULL
|
||||
char *
|
||||
strwpat(register const char *pattern)
|
||||
{
|
||||
register int ch;
|
||||
register char *prev_pattern = (char *)pattern;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
while ((ch = next_char(pattern, &pattern)) != '\0')
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case '*':
|
||||
return prev_pattern;
|
||||
case '?':
|
||||
return prev_pattern;
|
||||
case '[': {
|
||||
register const char *eop = next_patt(prev_pattern, 0);
|
||||
if (CHARAT(eop) == ']')
|
||||
return prev_pattern;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prev_pattern = (char *)pattern;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* match will check to see if pattern can successfully be applied to
|
||||
* the beginning of string.
|
||||
*/
|
||||
static int
|
||||
match(register const char *pattern, register const char *string, int depth)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("%smatch(\"%s\", \"%s\")\n", TABS, pattern, string);
|
||||
#endif
|
||||
int ch;
|
||||
const char *cp;
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
while ((ch = next_char(pattern, &cp)) != '\0')
|
||||
{
|
||||
const char *laststr = string;
|
||||
register int testchar = (int)CHARADV(string);
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '*': {
|
||||
pattern = cp; /* skip over '*' */
|
||||
string = laststr; /* reverse - testchar not used */
|
||||
|
||||
const char *s = string;
|
||||
do
|
||||
if (match(pattern, s, depth + 1))
|
||||
return RETURN(1, depth);
|
||||
while (CHARADV(s) != '\0');
|
||||
return RETURN(0, depth);
|
||||
}
|
||||
case '?':
|
||||
break;
|
||||
case '[': {
|
||||
int mt = match_class(pattern, testchar);
|
||||
if (mt == 0)
|
||||
return RETURN(0, depth);
|
||||
else if (mt == 2 && ch != testchar)
|
||||
return RETURN(0, depth);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if ((ch & ~QUOTE) != testchar)
|
||||
return RETURN(0, depth);
|
||||
break;
|
||||
}
|
||||
|
||||
if (testchar == '\0')
|
||||
string = laststr; // reverse string
|
||||
|
||||
pattern = next_patt(pattern);
|
||||
}
|
||||
|
||||
return RETURN(CHARAT(string) == '\0', depth);
|
||||
}
|
||||
|
||||
static int
|
||||
match_class(register const char *clss, register char testchar)
|
||||
/*
|
||||
* pattern is a pointer to the leading [ of
|
||||
* a shell-type class. testchar is the character to match against
|
||||
* the class.
|
||||
*/
|
||||
{
|
||||
int match = 1; /* false if first char is '!' */
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
/* find end of class, ie an un-escaped ']' */
|
||||
register const char *eop = next_patt(clss, 0);
|
||||
ADVANCE(clss);
|
||||
|
||||
if (CHARAT(eop) != ']')
|
||||
return 2;
|
||||
|
||||
if (CHARAT(clss) == '!')
|
||||
{
|
||||
match = 0;
|
||||
ADVANCE(clss);
|
||||
}
|
||||
|
||||
while (clss < eop)
|
||||
{
|
||||
register int ch = next_char(clss, &clss);
|
||||
char const *clss_end = clss;
|
||||
int sep = next_char(clss_end, &clss_end);
|
||||
int ch2 = next_char(clss_end, &clss_end);
|
||||
|
||||
/* check if next three chars are a range */
|
||||
if (sep == '-' && ch2 != ']')
|
||||
{
|
||||
/* check range - we have to use strcoll to do it right */
|
||||
char c1[MB_LEN_MAX+1], c2[MB_LEN_MAX+1], tc[MB_LEN_MAX+1];
|
||||
memset(c1, 0, sizeof(c1));
|
||||
memset(c2, 0, sizeof(c2));
|
||||
memset(tc, 0, sizeof(tc));
|
||||
ch &= ~QUOTE;
|
||||
WCHAR(ch, c1);
|
||||
ch2 &= ~QUOTE;
|
||||
WCHAR(ch2, c2);
|
||||
WCHAR(testchar, tc);
|
||||
|
||||
/* if (ch <= testchar && testchar <= ch2) // Original code */
|
||||
|
||||
/* Second implementation:
|
||||
* if (nl_strncmp(c1, tc, 1) <= 0 && nl_strncmp(tc, c2, 1) <= 0)
|
||||
* return match;
|
||||
*/
|
||||
|
||||
/* Third, portable implementation: */
|
||||
if (strcoll(c1, tc) <= 0 && strcoll(tc, c2) <= 0)
|
||||
return match;
|
||||
clss = clss_end;
|
||||
}
|
||||
else /* they are not a range, check simple
|
||||
match */
|
||||
{
|
||||
if ((ch & ~QUOTE) == testchar)
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
return !match;
|
||||
}
|
||||
|
||||
static const char *
|
||||
next_patt(register const char *pattern, int advance)
|
||||
{
|
||||
wchar_t __nlh_char[1];
|
||||
|
||||
if (CHARAT(pattern) == '[')
|
||||
{
|
||||
int ch;
|
||||
const char *pp = pattern;
|
||||
ADVANCE(pp);
|
||||
|
||||
if (CHARAT(pp) == '^')
|
||||
ADVANCE(pp);
|
||||
|
||||
if (CHARAT(pp) == ']')
|
||||
ADVANCE(pp);
|
||||
|
||||
char const *np;
|
||||
for (; (ch = next_char(pp, &np)) != '\0'; pp = np)
|
||||
if (ch == ']')
|
||||
return (advance ? np : pp);
|
||||
}
|
||||
|
||||
next_char(pattern, &pattern);
|
||||
return pattern;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define MAIN main
|
||||
MAIN()
|
||||
{
|
||||
char pattern[50], string[50];
|
||||
|
||||
while (1)
|
||||
{
|
||||
putchar('\n');
|
||||
printf("pattern: ");
|
||||
if (fgets(pattern, sizeof(pattern)-1, stdin) == NULL)
|
||||
break;
|
||||
printf("string: ");
|
||||
if (fgets(string, sizeof(pattern)-1, stdin) == NULL)
|
||||
break;
|
||||
printf("MATCH is %s\n",
|
||||
((strwcmp(pattern, string) == 0) ? "SUCCEEDED" : "FAILED"));
|
||||
putchar('\n');
|
||||
printf("MATCHI is %s\n",
|
||||
((strwcmpi(pattern, string) == 0) ? "SUCCEEDED" : "FAILED"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
57
cde/lib/DtSvc/DtEncap/Imakefile
Normal file
57
cde/lib/DtSvc/DtEncap/Imakefile
Normal file
@@ -0,0 +1,57 @@
|
||||
XCOMM $XConsortium: Imakefile /main/7 1996/08/22 09:10:00 rswiston $
|
||||
XCOMM (c) Copyright 1996 Digital Equipment Corporation.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Hewlett-Packard Company.
|
||||
XCOMM (c) Copyright 1993-1994,1996 International Business Machines Corp.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Sun Microsystems, Inc.
|
||||
XCOMM (c) Copyright 1993-1994,1996 Novell, Inc.
|
||||
XCOMM (c) Copyright 1996 FUJITSU LIMITED.
|
||||
XCOMM (c) Copyright 1996 Hitachi.
|
||||
|
||||
#define DoNormalLib NormalLibDtSvc
|
||||
#define DoSharedLib SharedLibDtSvc
|
||||
#define DoDebugLib DebugLibDtSvc
|
||||
#define DoProfileLib ProfileLibDtSvc
|
||||
#define LibName DtSvc
|
||||
#define SoRev SODTSVCREV
|
||||
#define LibHeaders NO
|
||||
#define LibCreate NO
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#ifndef DtSvcDefines
|
||||
# define DtSvcDefines -DXK_MISCELLANY -DMULTIBYTE
|
||||
#endif
|
||||
DEFINES = DtSvcDefines \
|
||||
-DCDE_CONFIGURATION_TOP=\"$(CDE_CONFIGURATION_TOP)\" \
|
||||
-DCDE_INSTALLATION_TOP=\"$(CDE_INSTALLATION_TOP)\" \
|
||||
-DCDE_LOGFILES_TOP=\"$(CDE_LOGFILES_TOP)/tmp\"
|
||||
|
||||
INCLUDES = -I. -I../include -I../DtUtil2
|
||||
|
||||
|
||||
SRCS = MemoryMgr.c SbEvent.c Symbolic.c bmsglob.c \
|
||||
connect.c local.c nls.c noio.c \
|
||||
pathwexp.c pipe.c pty.c remote.c \
|
||||
sbstdinc.c scoop.c spc-env.c spc-error.c \
|
||||
spc-exec.c spc-net.c spc-obj.c spc-proto.c \
|
||||
spc-sm.c spc-termio.c spc-util.c spc-xt.c \
|
||||
spc.c stringbuf.c usersig.c
|
||||
|
||||
/* WARNING!!!!
|
||||
* Any .o's added to this list need to be added to DTENCAP_OBJS4
|
||||
* and SHARED_DTENCAP_OBJS4 in the DtSvc Imakefile.
|
||||
*/
|
||||
OBJS = MemoryMgr.o SbEvent.o Symbolic.o bmsglob.o \
|
||||
connect.o local.o nls.o noio.o \
|
||||
pathwexp.o pipe.o pty.o remote.o \
|
||||
sbstdinc.o scoop.o spc-env.o spc-error.o \
|
||||
spc-exec.o spc-net.o spc-obj.o spc-proto.o \
|
||||
spc-sm.o spc-termio.o spc-util.o spc-xt.o \
|
||||
spc.o stringbuf.o usersig.o
|
||||
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SubdirLibraryRule($(OBJS))
|
||||
|
||||
DependTarget()
|
||||
54
cde/lib/DtSvc/DtEncap/MemoryMgr.c
Normal file
54
cde/lib/DtSvc/DtEncap/MemoryMgr.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* File: MemoryMgr.c $XConsortium: MemoryMgr.c /main/3 1995/10/26 15:34:54 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
|
||||
#include "/usr/include/apollo/shlib.h"
|
||||
#endif
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <bms/bms.h>
|
||||
#include <bms/XeUserMsg.h>
|
||||
#include <bms/MemoryMgr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define CPLUSPLUS_MALLOC_TYPE (malloc_t)
|
||||
#else
|
||||
#define CPLUSPLUS_MALLOC_TYPE
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
void * XeMalloc( size_t size )
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString ptr;
|
||||
|
||||
if (!size) return 0;
|
||||
if (ptr = malloc(size)) {
|
||||
*ptr = (XeChar)NULL; /* Force first byte to NULL for bozos who */
|
||||
/* think malloc zeros memory! */
|
||||
return ptr;
|
||||
}
|
||||
|
||||
_DtSimpleError(XeProgName, XeError, XeString_NULL,
|
||||
"><DtEncap: cannot malloc memory");
|
||||
exit(1);
|
||||
return (void*)NULL;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
void XeFree( void * ptr )
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
if (ptr)
|
||||
free((char *)ptr);
|
||||
}
|
||||
63
cde/lib/DtSvc/DtEncap/SbEvent.c
Normal file
63
cde/lib/DtSvc/DtEncap/SbEvent.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* File: SbEvent.c $XConsortium: SbEvent.c /main/3 1995/10/26 15:35:08 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1990, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#define __need_fd_set
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <errno.h>
|
||||
|
||||
typedef char Boolean;
|
||||
#include <bms/XeUserMsg.h>
|
||||
|
||||
#ifdef _AIX
|
||||
/*
|
||||
* The AIX compiler gives an internal error if it includes
|
||||
* <bms/SbEvent.h>. The required typedefs were removed from
|
||||
* this header and placed within this file.
|
||||
*/
|
||||
typedef void (*SbInputCallbackProc) ();
|
||||
typedef unsigned long SbInputId;
|
||||
#else
|
||||
#include <bms/SbEvent.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h> /* for fd_set, FD_SET macros, et. al. */
|
||||
|
||||
SbInputId (*SbAddInput_hookfn) (
|
||||
int fd,
|
||||
SbInputCallbackProc proc,
|
||||
void* data) = NULL;
|
||||
|
||||
SbInputId (*SbAddException_hookfn) (
|
||||
int fd,
|
||||
SbInputCallbackProc proc,
|
||||
void* data) = NULL;
|
||||
|
||||
void (*SbRemoveInput_hookfn) (
|
||||
SbInputId id) = NULL;
|
||||
|
||||
void (*SbRemoveException_hookfn) (
|
||||
SbInputId id) = NULL;
|
||||
|
||||
void (*SbMainLoopUntil_hookfn) (
|
||||
Boolean *flag) = NULL;
|
||||
|
||||
void (*SbBreakMainLoop_hookfn) (
|
||||
void) = NULL;
|
||||
|
||||
/* spcd calls this guy */
|
||||
|
||||
void XeCall_SbMainLoopUntil(Boolean *flag)
|
||||
{
|
||||
(*SbMainLoopUntil_hookfn)(flag);
|
||||
}
|
||||
|
||||
464
cde/lib/DtSvc/DtEncap/Symbolic.c
Normal file
464
cde/lib/DtSvc/DtEncap/Symbolic.c
Normal file
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* File: Symbolic.c $XConsortium: Symbolic.c /main/5 1996/09/27 19:00:23 drk $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#ifdef __osf__
|
||||
#define SBSTDINC_H_NO_REDEFINE
|
||||
#endif
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <bms/bms.h>
|
||||
#include <bms/XeUserMsg.h>
|
||||
#include <bms/MemoryMgr.h>
|
||||
#include <bms/Symbolic.h>
|
||||
|
||||
#include <codelibs/stringx.h> /* strhash */
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/* HASHING */
|
||||
|
||||
/* This is the default symbol table to use */
|
||||
/* --------------------------------------- */
|
||||
#define XE_END_OF_HASH_TABLE (XeSymtabList) -1
|
||||
|
||||
static XeSymTable D_sym_table = NULL;
|
||||
|
||||
typedef struct _unknown_entry_data {
|
||||
XeString name;
|
||||
} *unknown_entry_data;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Symbol (hash) Table */
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static unsigned int
|
||||
keyhash(XeSymTable t, void *key)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
unsigned int hash;
|
||||
|
||||
if (t->hash_fn)
|
||||
{
|
||||
hash = t->hash_fn( key, t->hashsize );
|
||||
if (hash >= t->hashsize)
|
||||
_DtSimpleError(XeProgName, XeInternalError, NULL,
|
||||
(XeString) "Symbolic.c: Hash value from user hash function out of range",
|
||||
NULL);
|
||||
/* We don't come back from the error routine */
|
||||
}
|
||||
else
|
||||
{
|
||||
hash = strhash( (const char *) key );
|
||||
hash = hash & (t->hashsize - 1);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static unsigned int
|
||||
trap_bad_hash_fn(void * UNUSED_PARM(ptr), unsigned int UNUSED_PARM(size))
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
_DtSimpleError(XeProgName, XeInternalError, NULL,
|
||||
(XeString) "Symbolic.c: Hash table at must be power of 2",
|
||||
NULL);
|
||||
/* We don't come back from the error routine */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeSymTable
|
||||
Xe_new_symtab(unsigned int hashsize)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
|
||||
/* Note, hashsize must be power of 2 if using default hash function */
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
XeSymTable t = (XeSymTable) XeMalloc( sizeof (struct _XeSymTable) );
|
||||
t->hashsize = hashsize;
|
||||
|
||||
t->list = (XeSymtabList *)XeMalloc( sizeof( XeSymtabList ) * hashsize );
|
||||
|
||||
for (i = 0; i < hashsize; i++)
|
||||
t->list[i] = (XeSymtabList)NULL;
|
||||
|
||||
t->curr_list = XE_END_OF_HASH_TABLE;
|
||||
t->curr_hash = 0;
|
||||
|
||||
Xe_set_sym_fns(t,
|
||||
(XeSymFn_cmp)NULL,
|
||||
(XeSymFn_init)NULL,
|
||||
(XeSymFn_clean)NULL,
|
||||
(XeSymFn_hash)NULL);
|
||||
|
||||
/* If not a power of two, user better have a hash function */
|
||||
/* that handles that. Install hash function trap so that if */
|
||||
/* he does not install one, we catch it. */
|
||||
/* --------------------------------------------------------- */
|
||||
if (hashsize & (hashsize - 1))
|
||||
t->hash_fn = trap_bad_hash_fn;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeSymTable
|
||||
Xe_default_symtab(void)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
#define D_HASHSIZE 256
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (D_sym_table) {
|
||||
_DtSvcProcessUnlock();
|
||||
return D_sym_table;
|
||||
}
|
||||
|
||||
D_sym_table = Xe_new_symtab(D_HASHSIZE);
|
||||
_DtSvcProcessUnlock();
|
||||
return(D_sym_table);
|
||||
}
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static XeSymtabList
|
||||
NukeOneItem(XeSymTable t, XeSymtabList l)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeSymtabList next;
|
||||
|
||||
/* For standard XeSymbols: */
|
||||
/* 1) Free the name */
|
||||
/* 2) Call free function if configured */
|
||||
/* 3) Free the XeSymbol entry */
|
||||
/* ---------------------------------------- */
|
||||
if (l->data_is_XeSymbol)
|
||||
{
|
||||
XeFree( ((XeSymbol)l->data)->name );
|
||||
if (t->clean_fn)
|
||||
t->clean_fn( ((XeSymbol)l->data)->value );
|
||||
XeFree( l->data );
|
||||
}
|
||||
/* For "anysym" symbols: */
|
||||
/* 1) Call free function if configured */
|
||||
/* 2) If we malloced the data, free it */
|
||||
/* ---------------------------------------- */
|
||||
else
|
||||
{
|
||||
if (t->clean_fn)
|
||||
t->clean_fn( l->data );
|
||||
|
||||
if (l->data_is_malloc_mem)
|
||||
XeFree(l->data);
|
||||
}
|
||||
|
||||
next = l->rest;
|
||||
XeFree(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeSymTable
|
||||
Xe_set_sym_fns(XeSymTable t,
|
||||
XeSymFn_cmp cmp_fn,
|
||||
XeSymFn_init init_fn,
|
||||
XeSymFn_clean clean_fn,
|
||||
XeSymFn_hash hash_fn)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
if (!t) t = Xe_default_symtab();
|
||||
|
||||
t->cmp_fn = cmp_fn;
|
||||
t->init_fn = init_fn;
|
||||
t->clean_fn = clean_fn;
|
||||
t->hash_fn = hash_fn;
|
||||
return(t);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static XeSymbol
|
||||
make_sym(XeString name)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeSymbol sym = Xe_make_struct(_XeSymbol);
|
||||
|
||||
sym->name = strdup( name );
|
||||
sym->value = (void*)NULL;
|
||||
return sym;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static void *
|
||||
intern_something(XeSymTable t,
|
||||
void * data,
|
||||
unsigned int size,
|
||||
Boolean is_XeSymbol,
|
||||
Boolean lookup_only,
|
||||
int *bucket)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
unsigned int hash;
|
||||
XeSymtabList l;
|
||||
XeSymtabList l0;
|
||||
Boolean match;
|
||||
void * hash_key;
|
||||
|
||||
/* If no cmp function assume first item of "data" is a string pointer */
|
||||
/* ------------------------------------------------------------------ */
|
||||
if (is_XeSymbol)
|
||||
hash_key = data;
|
||||
else
|
||||
hash_key = (t->hash_fn) ? data : ((unknown_entry_data) data)->name;
|
||||
|
||||
hash = keyhash( t, hash_key );
|
||||
l = t->list[hash];
|
||||
|
||||
if (bucket)
|
||||
*bucket = hash;
|
||||
|
||||
for (l0 = NULL; l; l0 = l, l = l->rest)
|
||||
{
|
||||
void * cmp_key;
|
||||
void * cmp_key2;
|
||||
|
||||
if (is_XeSymbol)
|
||||
cmp_key = data;
|
||||
else
|
||||
cmp_key = (t->cmp_fn) ? data : ((unknown_entry_data) data)->name;
|
||||
|
||||
if (l->data_is_XeSymbol)
|
||||
cmp_key2 = ((XeSymbol) l->data)->name;
|
||||
else
|
||||
cmp_key2 = (t->cmp_fn) ? l->data : ((unknown_entry_data) l->data)->name;
|
||||
|
||||
/* Use the "compare" function to see if we have a match on our key */
|
||||
/* --------------------------------------------------------------- */
|
||||
if (t->cmp_fn)
|
||||
match = (t->cmp_fn( cmp_key, cmp_key2 ) == 0);
|
||||
else
|
||||
match = (strcmp((const char *) cmp_key, (const char *)cmp_key2 ) == 0);
|
||||
|
||||
if (match)
|
||||
return l->data;
|
||||
}
|
||||
|
||||
/* If just doing a lookup, don't add a new symbol */
|
||||
/* ---------------------------------------------- */
|
||||
if (lookup_only) return (void *) NULL;
|
||||
|
||||
/* There was no match. We need to create an entry in the hash table. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
l = (XeSymtabList) XeMalloc( sizeof(struct _XeSymtabList) );
|
||||
l->rest = (XeSymtabList)NULL;
|
||||
l->data_is_XeSymbol = is_XeSymbol;
|
||||
l->data_is_malloc_mem = FALSE;
|
||||
|
||||
|
||||
if (l0)
|
||||
l0->rest = l;
|
||||
else
|
||||
t->list[hash] = l;
|
||||
|
||||
/* If we have a standard symbol, make the XeSymbol entry. */
|
||||
/* -------------------------------------------------------- */
|
||||
if (is_XeSymbol)
|
||||
{
|
||||
XeSymbol sym = make_sym((XeString)data);
|
||||
l->data = (void*) sym;
|
||||
if (t->init_fn)
|
||||
sym->value = t->init_fn( l->data, size /* will be 0 */ );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 1) If "size" != 0, */
|
||||
/* - malloc "size" bytes, */
|
||||
/* - copy "data" into malloced space, */
|
||||
/* - Save pointer to malloc space as user's data pointer */
|
||||
/* Else */
|
||||
/* - Save "data" as pointer to user's data */
|
||||
/* 2) If a "init_fn" is configured, */
|
||||
/* - call init_fn( user's data pointer, "size" ) */
|
||||
/* - set user's data pointer to return value of init_fn */
|
||||
/* ONLY if "size" was zero. */
|
||||
/* */
|
||||
/* If size is non zero AND there is a user's malloc function, */
|
||||
/* beware that the return value from the malloc function is not*/
|
||||
/* save anywhere by these routines. If size was zero, the */
|
||||
/* return value of the user's function is kept. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
if (size)
|
||||
{
|
||||
l->data = XeMalloc( size );
|
||||
memcpy(l->data, data, size);
|
||||
l->data_is_malloc_mem = TRUE;
|
||||
}
|
||||
else
|
||||
l->data = data;
|
||||
|
||||
if (t->init_fn)
|
||||
{
|
||||
void * new_data = t->init_fn( l->data, size );
|
||||
|
||||
if (!size)
|
||||
l->data = new_data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* appended to the end of the hash chain (if any). */
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
t->curr_list = l;
|
||||
t->curr_hash = hash;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Added data %p in list[%d] @ %p\n", l->data, hash, l);
|
||||
#endif
|
||||
|
||||
return l->data;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeSymbol
|
||||
Xe_intern(XeSymTable t, ConstXeString const name)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (!name) return (XeSymbol)NULL;
|
||||
|
||||
if (!t) t = Xe_default_symtab();
|
||||
|
||||
return (XeSymbol)intern_something(t, (void *)name, 0, TRUE, FALSE, (int*)NULL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeSymbol
|
||||
Xe_lookup(XeSymTable t, ConstXeString const name)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (!name) return (XeSymbol)NULL;
|
||||
|
||||
if (!t) t = Xe_default_symtab();
|
||||
|
||||
return (XeSymbol)intern_something(t, (void *)name, 0, TRUE, TRUE, (int*)NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* LISTS */
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeList
|
||||
Xe_make_list(void * data, XeList rest)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeList temp = Xe_make_struct(_XeList);
|
||||
|
||||
temp->data = data;
|
||||
temp->rest = rest;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* QUEUES */
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeQueue
|
||||
Xe_init_queue(XeQueue q, void * nullval)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
q->head = 0;
|
||||
q->null = nullval;
|
||||
return q;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeQueue
|
||||
Xe_make_queue(void * nullval)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
return Xe_init_queue(Xe_make_struct(_XeQueue), nullval);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
void *
|
||||
Xe_pop_queue(XeQueue q)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeList head = q->head;
|
||||
|
||||
if (head) {
|
||||
void * val = head->data;
|
||||
|
||||
q->head = head->rest;
|
||||
XeFree(head);
|
||||
return val;
|
||||
} else
|
||||
return q->null;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
void *
|
||||
Xe_delete_queue_element(XeQueue q, void * val)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeList last = 0, head = q->head;
|
||||
|
||||
while (head)
|
||||
if (head->data == val) {
|
||||
if (last)
|
||||
last->rest = head->rest;
|
||||
else
|
||||
q->head = head->rest;
|
||||
if (q->tail == head)
|
||||
q->tail = last;
|
||||
XeFree(head);
|
||||
return val;
|
||||
} else
|
||||
last = head, head = head->rest;
|
||||
return q->null;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
void
|
||||
Xe_push_queue(XeQueue q, void * val)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeList new_ptr = Xe_make_list(val, 0);
|
||||
|
||||
if (q->head)
|
||||
q->tail->rest = new_ptr;
|
||||
else
|
||||
q->head = new_ptr;
|
||||
q->tail = new_ptr;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
void
|
||||
Xe_release_queue(XeQueue q)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (q) {
|
||||
while (q->head)
|
||||
Xe_pop_queue(q);
|
||||
XeFree(q);
|
||||
}
|
||||
}
|
||||
47
cde/lib/DtSvc/DtEncap/bmsglob.c
Normal file
47
cde/lib/DtSvc/DtEncap/bmsglob.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* File: bmsglob.c $XConsortium: bmsglob.c /main/4 1996/06/21 17:35:08 ageorge $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1990, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#ifdef __osf__
|
||||
/* #define SBSTDINC_H_NO_INCLUDE */
|
||||
#define SBSTDINC_H_NO_REDEFINE
|
||||
#endif
|
||||
|
||||
#include <bms/sbport.h>
|
||||
#include <bms/bms.h>
|
||||
|
||||
char *XeToolClass = NULL;
|
||||
|
||||
/* --------- */
|
||||
/* context.c */
|
||||
/* --------- */
|
||||
XeString XeProgName = (XeString) "<unknown program name>";
|
||||
|
||||
/*-------------- */
|
||||
/* SPC/spc-obj.c */
|
||||
/*-------------- */
|
||||
int SPC_Initialized=FALSE;
|
||||
|
||||
/*-------------- */
|
||||
/* SPC/spc-error.c */
|
||||
/*-------------- */
|
||||
int XeSPCErrorNumber = 0;
|
||||
FILE *spc_logF = (FILE*)NULL;
|
||||
|
||||
/*-------------- */
|
||||
/* SPC/spc-env.c */
|
||||
/*-------------- */
|
||||
XeString spc_user_environment_file=XeString_NULL;
|
||||
|
||||
/*-------------- */
|
||||
/* SPC/spc-proto.c */
|
||||
/*-------------- */
|
||||
FILE *SPC_Print_Protocol = (FILE*)NULL;
|
||||
429
cde/lib/DtSvc/DtEncap/connect.c
Normal file
429
cde/lib/DtSvc/DtEncap/connect.c
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* File: connect.c $TOG: connect.c /main/8 1998/04/09 17:44:33 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <sys/socket.h> /**** needed by gethostbyname et al *****/
|
||||
#define X_INCLUDE_NETDB_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
|
||||
#include <bms/bms.h>
|
||||
#include <bms/connect.h>
|
||||
#include <bms/MemoryMgr.h> /* Xe_make_struct, make_str ... */
|
||||
#include <bms/XeUserMsg.h>
|
||||
#include <bms/pathwexp.h> /* Xe_shellexp */
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#include <codelibs/pathutils.h>
|
||||
|
||||
/*
|
||||
* local variables
|
||||
*/
|
||||
static XeString context_host = NULL;
|
||||
|
||||
static XeString FindDomainHost (XeString host_spec);
|
||||
static void UnParseFileString (XeString host, XeString path);
|
||||
static int GetDomainName (XeString buffer, unsigned int bufsize);
|
||||
|
||||
#define strequal(xxx_str1, xxx_str2) (!strcmp(xxx_str1, xxx_str2))
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeString
|
||||
XeCreateContextString(XeString host,
|
||||
XeString directory,
|
||||
XeString file)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString context_string;
|
||||
|
||||
host = XeFindShortHost(host);
|
||||
|
||||
if ((strequal(directory, (XeString)"")) || (directory == NULL)){
|
||||
if ((strequal(file, (XeString)"")) || (file == NULL)){
|
||||
return((XeString) NULL);
|
||||
} else {
|
||||
context_string = XeMalloc (strlen(host) + strlen(file) + 2);
|
||||
sprintf (context_string, "%s:%s", host, file);
|
||||
}
|
||||
} else {
|
||||
if ((strequal(file, (XeString)"")) || (file == NULL)){
|
||||
context_string = XeMalloc(strlen(host) + strlen(directory) + 2);
|
||||
sprintf (context_string, "%s:%s", host, directory);
|
||||
}
|
||||
else {
|
||||
context_string = XeMalloc(strlen(host) + strlen(directory) +
|
||||
strlen(file) + 3);
|
||||
sprintf (context_string, "%s:%s/%s", host, directory, file);
|
||||
}
|
||||
}
|
||||
Xe_release_str(host);
|
||||
return(context_string);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeString
|
||||
XeFindShortHost(XeString host_spec)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString host, ptr, ptr2;
|
||||
XeChar localhost[MAXHOSTNAMELEN];
|
||||
|
||||
if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
|
||||
_DtSvcProcessLock();
|
||||
if (!context_host){
|
||||
context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
|
||||
Xegetcwd(context_host, MAXHOSTNAMELEN);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
host_spec = context_host;
|
||||
}
|
||||
host_spec = Xe_shellexp(host_spec);
|
||||
ptr = strstr(host_spec, (XeString)".");
|
||||
if (!ptr) /* short name already */
|
||||
host = strdup(host_spec);
|
||||
else {
|
||||
GetDomainName(localhost, MAXHOSTNAMELEN);
|
||||
ptr2 = strstr(localhost, (XeString)".");
|
||||
if (ptr2 && strequal(ptr, ptr2)) { /* domains same, can eliminate */
|
||||
host = Xe_make_ntype(ptr-host_spec+1, XeChar);
|
||||
strncpy(host, host_spec, ptr-host_spec); /* copy only up to "." */
|
||||
host[ptr-host_spec] = NULL; /* NULL terminate copy */
|
||||
}
|
||||
else
|
||||
host = strdup(host_spec);
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
/* temporary without domain comparisons */
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeString
|
||||
XeFindHost(XeString host_spec)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
|
||||
_DtSvcProcessLock();
|
||||
if (!context_host){
|
||||
context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
|
||||
Xegetcwd(context_host, MAXHOSTNAMELEN);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
host_spec = context_host;
|
||||
}
|
||||
host_spec = Xe_shellexp(host_spec);
|
||||
return strdup(host_spec);
|
||||
}
|
||||
|
||||
|
||||
/* this should be XeFindHost but is called other name for 1.0 operation
|
||||
using only simple names if in short domain. See defect HZNlp05737 */
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static XeString
|
||||
FindDomainHost(XeString host_spec)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString host;
|
||||
XeString ptr;
|
||||
XeChar localhost[MAXHOSTNAMELEN];
|
||||
|
||||
if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
|
||||
_DtSvcProcessLock();
|
||||
if (!context_host){
|
||||
context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
|
||||
Xegetcwd(context_host, MAXHOSTNAMELEN);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
host_spec = context_host;
|
||||
}
|
||||
else if (strequal(host_spec, (XeString)"*")) {
|
||||
host_spec = strdup((XeString)"*");
|
||||
return host_spec;
|
||||
}
|
||||
host_spec = Xe_shellexp(host_spec);
|
||||
ptr = strstr(host_spec, (XeString)".");
|
||||
if (ptr)
|
||||
host = strdup(host_spec);
|
||||
else {
|
||||
GetDomainName(localhost, MAXHOSTNAMELEN);
|
||||
ptr = strstr(localhost, (XeString)"."); /* points to domain name if one exists */
|
||||
if (ptr) {
|
||||
host = Xe_make_ntype(strlen(host_spec)+strlen(ptr)+1, XeChar);
|
||||
strcpy(host, host_spec);
|
||||
strcat(host, ptr);
|
||||
}
|
||||
else
|
||||
host = strdup(host_spec);
|
||||
}
|
||||
return(host);
|
||||
}
|
||||
|
||||
/****** XeParseFileString and UnParseFileString work together to munge and
|
||||
unmunge a path into a host path pair. UnParseFileString DOES NOT WORK
|
||||
FOR ARBITRARY STRINGS. It is not a general functions (it is a hack).
|
||||
Do not use It as a general function.
|
||||
******/
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static void
|
||||
UnParseFileString(XeString host, XeString path)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (host) { /* there was a host in the original string */
|
||||
*--path = (XeChar) ':';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeParseFileString(XeString line,
|
||||
XeString *host_addr,
|
||||
XeString *path_addr)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString current_position = line;
|
||||
|
||||
if ((XeChar)'/' == *line) {
|
||||
*host_addr = XeString_NULL;
|
||||
*path_addr = line;
|
||||
return(0);
|
||||
}
|
||||
|
||||
while (*current_position && ((XeChar) ':' != *current_position)) {
|
||||
int len;
|
||||
if ((len = mblen(current_position, MB_CUR_MAX)) > 1)
|
||||
current_position += len;
|
||||
else
|
||||
current_position++;
|
||||
}
|
||||
if (*current_position) { /* host was specified */
|
||||
*current_position++ = XeChar_NULL; /* ":" goes to NULL */
|
||||
*host_addr = line;
|
||||
*path_addr = current_position;
|
||||
} else {
|
||||
*host_addr = XeString_NULL;
|
||||
*path_addr = line;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/***** Xegethostname is a replacement for gethostname which always returns the
|
||||
canonical (domain) hostname
|
||||
******/
|
||||
|
||||
static XeString domainname = XeString_NULL;
|
||||
|
||||
/* this should be Xegethostname but is called other name for 1.0 operation
|
||||
using only simple names if in short domain. See defect HZNlp05737 */
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static int
|
||||
GetDomainName(XeString buffer, unsigned int bufsize)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString tmpbuf = Xe_make_buffer(bufsize);
|
||||
XeString ptr;
|
||||
struct hostent *host_ret;
|
||||
_Xgethostbynameparams host_buf;
|
||||
static Boolean firstPass = TRUE;
|
||||
int status;
|
||||
|
||||
/* try to get domain name from hostname */
|
||||
if (status = gethostname(tmpbuf, bufsize)) {
|
||||
XeFree(tmpbuf);
|
||||
return status; /* failed gethostname */
|
||||
}
|
||||
ptr = strstr(tmpbuf, (XeString)".");
|
||||
_DtSvcProcessLock();
|
||||
if (domainname && ptr && strcmp(domainname, ptr)) /* domains are different */
|
||||
_DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><Domain configured in hostname and domain server are different: '%s', '%s'", domainname, ptr);
|
||||
if (!domainname && ptr)
|
||||
domainname = strdup(ptr);
|
||||
if (ptr) { /* "." in hostname */
|
||||
strncpy(buffer, tmpbuf, bufsize);
|
||||
XeFree(tmpbuf);
|
||||
_DtSvcProcessUnlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* look up domain name in domain server */
|
||||
if (!domainname && (firstPass)) {
|
||||
firstPass = FALSE;
|
||||
host_ret = _XGethostbyname(tmpbuf, host_buf);
|
||||
if (host_ret == NULL) {
|
||||
_DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><%s not found in hosts database", tmpbuf);
|
||||
_DtSvcProcessUnlock();
|
||||
return -1;
|
||||
}
|
||||
if (ptr = strstr(host_ret->h_name, (XeString)".")) /* if dot in canonical name */
|
||||
domainname = strdup(ptr);
|
||||
}
|
||||
|
||||
/* construct full domain name for return */
|
||||
strncpy(buffer, tmpbuf, bufsize);
|
||||
if (domainname)
|
||||
strncat(buffer, domainname, bufsize - strlen(tmpbuf));
|
||||
XeFree(tmpbuf);
|
||||
_DtSvcProcessUnlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
int
|
||||
Xegetshorthostname(XeString buffer, unsigned int bufsize)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString ptr;
|
||||
int status;
|
||||
|
||||
if (status = gethostname(buffer, bufsize))
|
||||
return status; /* failed gethostname */
|
||||
if (ptr = strstr(buffer, (XeString)"."))
|
||||
*ptr = NULL; /* delete domain name if there is one */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
int
|
||||
Xegethostname(XeString buffer, unsigned int bufsize)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
return Xegetshorthostname(buffer, bufsize);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
Boolean
|
||||
XeIsLocalHostP(XeString hostname)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeChar localhost[MAXHOSTNAMELEN];
|
||||
XeString found_host = FindDomainHost(hostname);
|
||||
int status;
|
||||
|
||||
GetDomainName(localhost, MAXHOSTNAMELEN);
|
||||
status = strcmp(localhost, found_host)==0;
|
||||
XeFree(found_host);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
Boolean
|
||||
XeIsSameHostP(XeString host1, XeString host2)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString long_host1 = FindDomainHost(host1);
|
||||
XeString long_host2 = FindDomainHost(host2);
|
||||
int status = strcmp(long_host1, long_host2) == 0;
|
||||
if (!host1 || !host1[0] || !strcmp(host1,(XeString)"-")
|
||||
|| !host2 || !host2[0] || !strcmp(host2,(XeString)"-"))
|
||||
status = strcmp(host1, host2) == 0;
|
||||
|
||||
XeFree(long_host1);
|
||||
XeFree(long_host2);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* note the following functions use char not Xechar because they are
|
||||
plug replacements for the Unix functions */
|
||||
|
||||
static char *last_env_string = NULL; /* save env so it can be freed later */
|
||||
|
||||
/* Note: only use this function for $PWD as it assumes it can free the
|
||||
env variable when a new one is assigned -- this will only be true if
|
||||
the same variable is used for all calls to copying_putenv */
|
||||
static void
|
||||
copying_putenv(char *env)
|
||||
{
|
||||
char *env_copy = XeCopyStringM(env);
|
||||
putenv(env_copy);
|
||||
_DtSvcProcessLock();
|
||||
if (last_env_string)
|
||||
XeFree(last_env_string);
|
||||
last_env_string = env_copy;
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
char *
|
||||
Xegetcwd(char *buf, int size)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
Boolean pwd_ok = FALSE;
|
||||
char *env, *current_dir;
|
||||
|
||||
if (current_dir = getenv("PWD")) { /* use PWD instead of slow call */
|
||||
int s1, s2;
|
||||
struct stat sb1, sb2;
|
||||
|
||||
/* The code used to copy size-1 bytes. This is a waste most of */
|
||||
/* the time. All we need to copy is strlen($PWD) bytes unless */
|
||||
/* there are more bytes that fit into the array passed in. */
|
||||
|
||||
int len=strlen(current_dir);
|
||||
if (len > size-1)
|
||||
len = size-1;
|
||||
|
||||
strncpy(buf, current_dir, len);
|
||||
buf[len] = NULL;
|
||||
|
||||
/* Make sure $PWD is the same as "." before we trust it. */
|
||||
/* All this is still much faster the getcwd() esp. on UX discless. */
|
||||
s1 = stat(buf, &sb1);
|
||||
s2 = stat(".", &sb2);
|
||||
|
||||
/* If device and inode are the same, we have a match */
|
||||
pwd_ok = ((s1 == 0 && s2 == 0) &&
|
||||
(sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino) );
|
||||
}
|
||||
|
||||
if (!pwd_ok) {
|
||||
current_dir = getcwd(buf, size);
|
||||
env = XeMalloc(MAXPATHLEN+10);
|
||||
sprintf(env, "PWD=%s", buf);
|
||||
copying_putenv(env); /* set PWD if necessary for later cache use */
|
||||
if (env) XeFree(env);
|
||||
}
|
||||
return current_dir;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
int
|
||||
Xechdir (const char *path)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
int status;
|
||||
char *simple_path = NULL;
|
||||
char *env;
|
||||
char buf[MAXPATHLEN+10];
|
||||
if ((status = chdir(path))==0) {
|
||||
env = XeMalloc(MAXPATHLEN+10);
|
||||
|
||||
if (path[0] != '/') { /* relative path */
|
||||
path = getcwd(buf, sizeof buf);
|
||||
sprintf(env, "PWD=%s", path);
|
||||
}
|
||||
else {
|
||||
char *canon_path = pathcollapse(path, NULL, FALSE);
|
||||
/* absolute path */
|
||||
sprintf(env, "PWD=%s", canon_path);
|
||||
/* note XeFree() not appropriate if Xemalloc not used */
|
||||
free(canon_path);
|
||||
}
|
||||
|
||||
copying_putenv(env); /* update PWD if directory changed */
|
||||
if (env) XeFree(env);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
232
cde/lib/DtSvc/DtEncap/local.c
Normal file
232
cde/lib/DtSvc/DtEncap/local.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* File: local.c $TOG: local.c /main/5 1999/10/14 15:05:57 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#define __need_timeval /* Needed for "struct timeval" from <time.h>. */
|
||||
#define __need_fd_set
|
||||
|
||||
#include <bms/sbport.h>
|
||||
#ifdef __osf__
|
||||
#include <sys/time.h> /* For declaration of select(). */
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <SPC/spc-proto.h>
|
||||
|
||||
/*
|
||||
**
|
||||
** Note that the close routines call the parent method AFTER the
|
||||
** work done for the child method. This is because the parent method
|
||||
** will do all the deallocation.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int close_local_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *wirelist;
|
||||
int result;
|
||||
|
||||
for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next){
|
||||
spc_close(wirelist->fd[READ_SIDE]);
|
||||
spc_close(wirelist->fd[WRITE_SIDE]);
|
||||
SPC_XtRemoveInput(&wirelist->read_toolkit_id, SPC_Input);
|
||||
SPC_XtRemoveInput(&wirelist->except_toolkit_id, SPC_Exception);
|
||||
}
|
||||
|
||||
call_parent_method(channel, close, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int write_local_channel_object(SPC_Channel_Ptr channel,
|
||||
XeString buffer,
|
||||
int nbytes)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel,
|
||||
write,
|
||||
(channel, buffer, nbytes),
|
||||
result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
result = SPC_Write_Chars(channel->file_descs[STDIN], buffer, nbytes);
|
||||
if(result==ERROR) {
|
||||
SPC_Error(SPC_Writing);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/* the function exec_proc_local_channel_object is defined in spc-exec.c */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int signal_local_channel_object (SPC_Channel_Ptr channel,
|
||||
int sig)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, signal, (channel, sig), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if(sig == SIGKILL || IS_SPCIO_SIGNAL_PGRP(channel->IOMode))
|
||||
result=kill(-(channel->pid), sig);
|
||||
else
|
||||
result=kill(channel->pid, sig);
|
||||
|
||||
if(result==ERROR)
|
||||
return(errno!=ESRCH);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int local_channel_object_wait_for_termination(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, wait_for_termination, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* Do we need to check for remote channel input here? */
|
||||
|
||||
while(IS_ACTIVE(channel)) {
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
/* the SIGCLD signal handler will take care of us here */
|
||||
sigsuspend(&mask);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
remove_logfile_local_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, remove_logfile, (channel), result);
|
||||
|
||||
if(unlink(channel->logfile)==ERROR) {
|
||||
SPC_Error(SPC_Unlink_Logfile);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* This is malloc'ed memory from open_noio_channel_object() and tempnam() */
|
||||
XeFree(channel->logfile);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
extern SPC_Channel_Ptr spc_activation_list;
|
||||
|
||||
/* All this routine does is to look up the channel, and
|
||||
call the generic input handler routine */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void local_channel_object_input_handler(void * client_data,
|
||||
int *source,
|
||||
SPCInputId * UNUSED_PARM(id))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
/* WARNING!!! This routine is NOT XPG3 compliant. The timeval struct */
|
||||
/* is the problem here. */
|
||||
|
||||
SPC_Channel_Ptr channel=(SPC_Channel_Ptr) client_data;
|
||||
int fd=(*source);
|
||||
int connector;
|
||||
int len;
|
||||
fd_set read_fd_vect, except_fd_vect;
|
||||
SPC_Channel_Ptr tmp, this_ptr;
|
||||
struct timeval timeout; /* Not part of XPG3 !!! */
|
||||
|
||||
/* This ^&@$#% select is here to get around an X toolkit bug */
|
||||
|
||||
FD_ZERO(&read_fd_vect);
|
||||
FD_ZERO(&except_fd_vect);
|
||||
|
||||
FD_SET(fd, &read_fd_vect);
|
||||
FD_SET(fd, &except_fd_vect);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
#if defined(SVR4) || defined(__osf__) || defined(__hpux)
|
||||
select(max_fds, (fd_set*)&read_fd_vect, NULL, (fd_set*)&except_fd_vect, &timeout);
|
||||
#else
|
||||
/* UX has select defined with int*, not fd_set* parms */
|
||||
select(max_fds, (int*)&read_fd_vect, NULL, (int*)&except_fd_vect, &timeout);
|
||||
#endif
|
||||
if(! (FD_ISSET(fd, &read_fd_vect) || FD_ISSET(fd, &except_fd_vect))) {
|
||||
return /* (FALSE) */;
|
||||
}
|
||||
|
||||
/* The following is to get around an apparent Xt bug where sometimes
|
||||
the client data pointer passed to me is not the one I was expecting.
|
||||
*/
|
||||
|
||||
tmp = spc_activation_list;
|
||||
this_ptr = NULL;
|
||||
while(tmp) {
|
||||
if((fd == Stdin(tmp)) || (fd == Stderr(tmp)))
|
||||
this_ptr = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if(this_ptr == NULL)
|
||||
this_ptr = channel;
|
||||
if(this_ptr != channel)
|
||||
channel = this_ptr;
|
||||
|
||||
if((connector=SPC_fd_to_connector(channel, fd)) == ERROR) {
|
||||
SPC_Error(SPC_Bad_Fd);
|
||||
return /* (SPC_ERROR) */;
|
||||
}
|
||||
len = SPC_Input_Handler(channel, connector);
|
||||
return /* (len) */;
|
||||
}
|
||||
|
||||
int local_channel_object_send_eof(SPC_Channel_Ptr channel)
|
||||
{
|
||||
Wire *wire = channel->wires[STDIN];
|
||||
|
||||
spc_close(wire->fd[READ_SIDE]);
|
||||
spc_close(wire->fd[WRITE_SIDE]);
|
||||
SPC_XtRemoveInput(&wire->read_toolkit_id, SPC_Input);
|
||||
SPC_XtRemoveInput(&wire->except_toolkit_id, SPC_Exception);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
39
cde/lib/DtSvc/DtEncap/nls.c
Normal file
39
cde/lib/DtSvc/DtEncap/nls.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* File: nls.c $XConsortium: nls.c /main/3 1995/10/26 15:36:38 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <bms/bms.h>
|
||||
|
||||
#ifndef CDE_LOGFILES_TOP
|
||||
#define CDE_LOGFILES_TOP "/var/dt/tmp"
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeString
|
||||
XeSBTempPath(XeString suffix)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString dir = (XeString) CDE_LOGFILES_TOP;
|
||||
XeString path;
|
||||
|
||||
if (!suffix || !*suffix)
|
||||
return strdup(dir);
|
||||
|
||||
path = (XeString)XeMalloc(strlen(dir) + strlen(suffix) + 2 );
|
||||
|
||||
strcpy(path, dir);
|
||||
strcat(path, "/");
|
||||
strcat(path, suffix);
|
||||
|
||||
return path;
|
||||
}
|
||||
382
cde/lib/DtSvc/DtEncap/noio.c
Normal file
382
cde/lib/DtSvc/DtEncap/noio.c
Normal file
@@ -0,0 +1,382 @@
|
||||
/* $XConsortium: noio.c /main/8 1996/11/21 19:53:13 drk $
|
||||
*
|
||||
* File: noio.c
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <bms/MemoryMgr.h>
|
||||
#define X_INCLUDE_PWD_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/* Global variables */
|
||||
|
||||
/*
|
||||
* The name of the directory used for authentication and
|
||||
* for temporary logfiles.
|
||||
*/
|
||||
XeString SPCD_Authentication_Dir = NULL;
|
||||
|
||||
/*
|
||||
* This array contains the names of the logfiles the SPC daemon
|
||||
* creates. Before the daemon exits, if any logfiles exist, they
|
||||
* will be removed.
|
||||
*/
|
||||
char **SPC_logfile_list = NULL;
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void noio_channel_class_init(object_clasp t)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
noio_channel_clasp c =(noio_channel_clasp) t;
|
||||
|
||||
c->new_obj = alloc_channel_object;
|
||||
|
||||
c->open = open_noio_channel_object;
|
||||
c->close = close_local_channel_object;
|
||||
c->read = read_noio_channel_object;
|
||||
c->write = write_noio_channel_object;
|
||||
c->reset = reset_noio_channel_object;
|
||||
c->pre_fork = pre_fork_noio_channel_object;
|
||||
c->post_fork = post_fork_noio_channel_object;
|
||||
c->exec_proc = exec_proc_local_channel_object;
|
||||
c->signal = signal_local_channel_object;
|
||||
c->wait_for_termination = local_channel_object_wait_for_termination;
|
||||
c->attach = attach_noio_channel_object;
|
||||
c->input = noio_channel_object_input_handler;
|
||||
c->remove_logfile = remove_logfile_local_channel_object;
|
||||
|
||||
/* New B.00 methods */
|
||||
|
||||
c->send_eof = send_eof_noio_channel_object;
|
||||
c->set_termio = set_termio_noio_channel_object;
|
||||
}
|
||||
|
||||
static struct noio_channel_class noio_channel_class_struct = {
|
||||
(channel_clasp) &channel_class, /* base class pointer */
|
||||
"noio_channel", /* class name */
|
||||
noio_channel_class_init, /* class initialize function */
|
||||
sizeof(SPC_Channel), /* size */
|
||||
0
|
||||
};
|
||||
|
||||
noio_channel_clasp noio_channel_class = &noio_channel_class_struct;
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
*/
|
||||
|
||||
static int is_dir_usable (
|
||||
char *dir);
|
||||
static char * get_tmp_dir (
|
||||
void);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* is_dir_usable - given a directory name, return 1 if:
|
||||
*
|
||||
* #1 the directory exists (determined by stat() succeeding)
|
||||
*
|
||||
* #2 the directory is readable
|
||||
*
|
||||
* #3 the directory is writeable
|
||||
*
|
||||
* otherwise, return 0.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* char *dir - the directory to check
|
||||
*
|
||||
* Return Value:
|
||||
*
|
||||
* 1 if 'dir' is usable and 0 if it is not
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int is_dir_usable (
|
||||
char *dir)
|
||||
{
|
||||
struct stat stat_buffer;
|
||||
|
||||
if ((stat (dir, &stat_buffer)) != 0)
|
||||
return (0);
|
||||
|
||||
if ((S_ISDIR(stat_buffer.st_mode)) && (access (dir, W_OK | R_OK) == 0))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* get_tmp_dir - determine the name of a directory to use
|
||||
* for temporary logfiles. The first dirctory in the
|
||||
* following list that passes the usability test in
|
||||
* 'is_dir_usable' will be returned:
|
||||
*
|
||||
* ~/.dt/tmp
|
||||
*
|
||||
* ~/.dt
|
||||
*
|
||||
* ~/
|
||||
*
|
||||
* Parameters: NONE
|
||||
*
|
||||
* Return Value:
|
||||
*
|
||||
* char * - the name of the temporary directory to use
|
||||
* or NULL if no usable directory is found.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* o The caller is responsible for free'ing the returned
|
||||
* string (if it is not NULL)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static char * get_tmp_dir (
|
||||
void)
|
||||
{
|
||||
char *dir;
|
||||
_Xgetpwparams pwd_buf;
|
||||
struct passwd * pwd_ret;
|
||||
|
||||
if ((pwd_ret = _XGetpwuid(getuid(), pwd_buf)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
dir = malloc (strlen (pwd_ret->pw_dir) +
|
||||
strlen (SPCD_ENV_HOME_DIRECTORY) + 8);
|
||||
|
||||
if (!dir)
|
||||
return (NULL);
|
||||
|
||||
(void) sprintf (dir, "%s/%s/tmp", pwd_ret->pw_dir, SPCD_ENV_HOME_DIRECTORY);
|
||||
if (is_dir_usable (dir))
|
||||
return (dir);
|
||||
|
||||
(void) sprintf (dir, "%s/%s", pwd_ret->pw_dir, SPCD_ENV_HOME_DIRECTORY);
|
||||
if (is_dir_usable (dir))
|
||||
return (dir);
|
||||
|
||||
(void) sprintf (dir, "%s", pwd_ret->pw_dir);
|
||||
if (is_dir_usable (dir))
|
||||
return (dir);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Method definitions for noio channel objects
|
||||
***
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine handles initialization for noio channels
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr open_noio_channel_object(SPC_Channel_Ptr channel,
|
||||
int iomode,
|
||||
XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int i=0;
|
||||
SPC_Channel_Ptr result;
|
||||
XeString temp_dir_name = NULL;
|
||||
|
||||
call_parent_method(channel, open, (channel, iomode, hostname), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if(IS_SPCIO_USE_LOGFILE(iomode)) {
|
||||
|
||||
_DtSvcProcessLock();
|
||||
/* Storage from tempnam() freed in remove_logfile_local_channel_object */
|
||||
if (SPCD_Authentication_Dir != NULL)
|
||||
channel->logfile=tempnam(SPCD_Authentication_Dir,"SPC");
|
||||
else {
|
||||
temp_dir_name = get_tmp_dir ();
|
||||
channel->logfile=tempnam(temp_dir_name,"SPC");
|
||||
if (temp_dir_name != NULL)
|
||||
free(temp_dir_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the name of the logfile so it can removed by the
|
||||
* daemon before it exits.
|
||||
*/
|
||||
if (SPC_logfile_list == NULL)
|
||||
/*
|
||||
* Create the first block plus the NULL terminator.
|
||||
*/
|
||||
SPC_logfile_list = (char **) malloc (2 * sizeof (char *));
|
||||
else {
|
||||
/*
|
||||
* Need to add this file to the end of the list.
|
||||
*/
|
||||
for (i = 0; SPC_logfile_list[i] != NULL; i++);
|
||||
SPC_logfile_list = (char **) realloc (SPC_logfile_list,
|
||||
(i+2) * sizeof (char *));
|
||||
}
|
||||
if (channel->logfile != NULL)
|
||||
SPC_logfile_list[i] = strdup (channel->logfile);
|
||||
else
|
||||
SPC_logfile_list[i] = (char *) NULL;
|
||||
SPC_logfile_list[i+1] = (char *) NULL;
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
if(!channel->logfile) {
|
||||
SPC_Error(SPC_Out_Of_Memory);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return(channel);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int read_noio_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(connector), /* STDOUT or STDERR */
|
||||
XeString UNUSED_PARM(buffer),
|
||||
int UNUSED_PARM(nbytes))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int write_noio_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
XeString UNUSED_PARM(buffer),
|
||||
int UNUSED_PARM(nbytes))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int pre_fork_noio_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, pre_fork, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int post_fork_noio_channel_object(SPC_Channel_Ptr channel,
|
||||
int parentp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result, fd;
|
||||
|
||||
call_parent_method(channel, post_fork, (channel, parentp), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
|
||||
if (parentp) { /* Master process */
|
||||
}
|
||||
else { /* Slave process */
|
||||
|
||||
/* set up STDIN, STDOUT & STDERR to go to /dev/null,
|
||||
or to the appropriate logfile */
|
||||
|
||||
fd=(-1);
|
||||
|
||||
spc_dup2(fd, STDIN);
|
||||
|
||||
/* Open logfile if necessary */
|
||||
|
||||
if(IS_SPCIO_USE_LOGFILE(channel->IOMode))
|
||||
if((fd=open(channel->logfile, O_WRONLY | O_CREAT, 0666)) == ERROR) {
|
||||
SPC_Error(SPC_Cannot_Open_Log, channel->logfile);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
spc_dup2(fd, STDOUT);
|
||||
spc_dup2(fd, STDERR);
|
||||
|
||||
/* close all other file descriptors */
|
||||
|
||||
SPC_Close_Unused();
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int reset_noio_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int iomode=channel->IOMode;
|
||||
|
||||
call_parent_method(channel, reset, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int attach_noio_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(foo))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* It is an error to try to attach to a noio channel... */
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void noio_channel_object_input_handler(void *UNUSED_PARM(client_data),
|
||||
int *UNUSED_PARM(source),
|
||||
SPCInputId *UNUSED_PARM(id))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return /* (SPC_ERROR) */;
|
||||
}
|
||||
|
||||
int send_eof_noio_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel))
|
||||
{
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
int set_termio_noio_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(connection),
|
||||
int UNUSED_PARM(side),
|
||||
struct termios * UNUSED_PARM(termio))
|
||||
{
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
31
cde/lib/DtSvc/DtEncap/pathwexp.c
Normal file
31
cde/lib/DtSvc/DtEncap/pathwexp.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* File: pathwexp.c $XConsortium: pathwexp.c /main/3 1995/10/26 15:37:07 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h>
|
||||
#include <bms/pathwexp.h>
|
||||
|
||||
#include <codelibs/shellutils.h>
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeString Xe_shellexp(XeString path)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
int num;
|
||||
XeString *res = (XeString *) shellscan(path, &num,
|
||||
SHX_NOGLOB | SHX_NOSPACE | SHX_NOMETA | SHX_NOGRAVE);
|
||||
|
||||
if (num == 0)
|
||||
return NULL;
|
||||
else
|
||||
return res[0];
|
||||
}
|
||||
|
||||
322
cde/lib/DtSvc/DtEncap/pipe.c
Normal file
322
cde/lib/DtSvc/DtEncap/pipe.c
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* File: pipe.c $XConsortium: pipe.c /main/4 1996/04/21 19:10:09 drk $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <errno.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void pipe_channel_class_init(object_clasp t)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
pipe_channel_clasp c = (pipe_channel_clasp) t;
|
||||
|
||||
c->new_obj = alloc_channel_object;
|
||||
|
||||
c->open = open_pipe_channel_object;
|
||||
c->close = close_local_channel_object;
|
||||
c->read = read_pipe_channel_object;
|
||||
c->write = write_local_channel_object;
|
||||
c->reset = reset_pipe_channel_object;
|
||||
c->pre_fork = pre_fork_pipe_channel_object;
|
||||
c->post_fork = post_fork_pipe_channel_object;
|
||||
c->exec_proc = exec_proc_local_channel_object;
|
||||
c->signal = signal_local_channel_object;
|
||||
c->wait_for_termination = local_channel_object_wait_for_termination;
|
||||
c->attach = attach_pipe_channel_object;
|
||||
c->add_input = add_input_pipe_channel_object;
|
||||
c->input = local_channel_object_input_handler;
|
||||
c->remove_logfile = remove_logfile_local_channel_object;
|
||||
|
||||
/* New B.00 methods */
|
||||
|
||||
c->send_eof = local_channel_object_send_eof;
|
||||
c->set_termio = set_termio_noio_channel_object;
|
||||
}
|
||||
|
||||
static struct pipe_channel_class pipe_channel_class_struct = {
|
||||
(channel_clasp) &channel_class, /* base class pointer */
|
||||
"pipe_channel", /* class name */
|
||||
pipe_channel_class_init, /* class initialize function */
|
||||
sizeof(SPC_Channel), /* size */
|
||||
0
|
||||
};
|
||||
|
||||
pipe_channel_clasp pipe_channel_class = &pipe_channel_class_struct;
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
Wire *getpipe(Wire *prevwire)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *wire_ptr=get_new_wire();
|
||||
|
||||
if(!wire_ptr)
|
||||
return(SPC_ERROR);
|
||||
|
||||
wire_ptr->next=prevwire;
|
||||
/* Get file descriptors for pipe */
|
||||
if (pipe(wire_ptr->fd) < OK) {
|
||||
SPC_Error(SPC_No_Pipe);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
return(wire_ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Method definitions for pipe channel objects
|
||||
***
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine handles initialization for pipe channels
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr open_pipe_channel_object(SPC_Channel_Ptr channel,
|
||||
int iomode,
|
||||
XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
Wire *tmpwire=NULL;
|
||||
SPC_Channel_Ptr result;
|
||||
|
||||
call_parent_method(channel, open, (channel, iomode, hostname), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if (IS_SPCIO_STDIN(iomode)) {
|
||||
tmpwire=channel->wires[STDIN]=getpipe(NULL);
|
||||
if(!tmpwire)
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if (IS_SPCIO_STDOUT(iomode)) {
|
||||
tmpwire=channel->wires[STDOUT]=getpipe(tmpwire);
|
||||
if(!tmpwire)
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(IS_SPCIO_STDERR(iomode)) {
|
||||
if (!tmpwire ||
|
||||
IS_SPCIO_SEPARATE(iomode)) {
|
||||
tmpwire=channel->wires[STDERR]=getpipe(tmpwire);
|
||||
if(!tmpwire)
|
||||
return(SPC_ERROR);
|
||||
} else {
|
||||
channel->wires[STDERR]=channel->wires[STDOUT];
|
||||
}
|
||||
}
|
||||
|
||||
channel->file_descs[STDIN] =(channel->wires[STDIN]) ->fd[WRITE_SIDE];
|
||||
channel->file_descs[STDOUT]=(channel->wires[STDOUT])->fd[READ_SIDE];
|
||||
channel->file_descs[STDERR]=(channel->wires[STDERR])->fd[READ_SIDE];
|
||||
|
||||
channel->wire_list=tmpwire;
|
||||
|
||||
return(channel);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int read_pipe_channel_object(SPC_Channel_Ptr channel,
|
||||
int connector, /* STDOUT or STDERR */
|
||||
XeString buffer,
|
||||
int nbytes)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel,
|
||||
read,
|
||||
(channel, connector, buffer, nbytes),
|
||||
result);
|
||||
|
||||
if(result==Undefined)
|
||||
return(Undefined);
|
||||
|
||||
do {
|
||||
result = read(channel->file_descs[connector], buffer, nbytes);
|
||||
} while (result<0 && errno == EINTR);
|
||||
|
||||
if(result == 0) {
|
||||
|
||||
SPC_XtRemoveInput(&channel->wires[connector]->read_toolkit_id, SPC_Input);
|
||||
SPC_Change_State(channel, connector, 0, -1);
|
||||
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int pre_fork_pipe_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, pre_fork, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int post_fork_pipe_channel_object(SPC_Channel_Ptr channel,
|
||||
int parentp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, post_fork, (channel, parentp), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
|
||||
if (parentp) { /* Master process */
|
||||
|
||||
spc_close(channel->wires[STDIN]->fd[READ_SIDE]);
|
||||
spc_close(channel->wires[STDOUT]->fd[WRITE_SIDE]);
|
||||
spc_close(channel->wires[STDERR]->fd[WRITE_SIDE]);
|
||||
|
||||
channel->wires[STDIN]->fd[READ_SIDE] = (-1);
|
||||
channel->wires[STDOUT]->fd[WRITE_SIDE] = (-1);
|
||||
channel->wires[STDERR]->fd[WRITE_SIDE] = (-1);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
else { /* Slave process */
|
||||
|
||||
/* Close the "other" side of the pipes */
|
||||
|
||||
spc_close(channel->wires[STDIN]->fd[WRITE_SIDE]);
|
||||
spc_close(channel->wires[STDOUT]->fd[READ_SIDE]);
|
||||
spc_close(channel->wires[STDERR]->fd[READ_SIDE]);
|
||||
|
||||
/* Dup the file descriptors to fd's 3, 4, 5.
|
||||
spc_dup2 is used to make sure these guys are hooked to something
|
||||
(/dev/null if necessary). We do this step here just in case any
|
||||
of the source file descriptors are 0, 1, or 2. */
|
||||
|
||||
spc_dup2(channel->wires[STDIN]->fd[READ_SIDE], 3);
|
||||
spc_dup2(channel->wires[STDOUT]->fd[WRITE_SIDE], 4);
|
||||
spc_dup2(channel->wires[STDERR]->fd[WRITE_SIDE], 5);
|
||||
|
||||
/* Go to STDIN, STDOUT, STDERR */
|
||||
|
||||
spc_dup2(3, STDIN);
|
||||
spc_dup2(4, STDOUT);
|
||||
spc_dup2(5, STDERR);
|
||||
|
||||
/* Close any other open file descriptors in the child */
|
||||
SPC_Close_Unused();
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int reset_pipe_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int iomode=channel->IOMode;
|
||||
Wire *wirelist;
|
||||
|
||||
call_parent_method(channel, reset, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* Close the file descriptors */
|
||||
|
||||
for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next) {
|
||||
SPC_XtRemoveInput(&wirelist->read_toolkit_id, SPC_Input);
|
||||
close(wirelist->fd[READ_SIDE]);
|
||||
close(wirelist->fd[WRITE_SIDE]);
|
||||
wirelist->flags &= ~SPCIO_DATA;
|
||||
}
|
||||
|
||||
/* Allocate new file descriptors */
|
||||
|
||||
for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next) {
|
||||
if(pipe(wirelist->fd) < 0) {
|
||||
SPC_Error(SPC_No_Pipe);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* set the file_descs array to the new file descriptors & set up
|
||||
the new read mask */
|
||||
|
||||
channel->file_descs[STDIN] = (channel->wires[STDIN])->fd[WRITE_SIDE];
|
||||
channel->file_descs[STDOUT] = (channel->wires[STDOUT])->fd[READ_SIDE];
|
||||
channel->file_descs[STDERR] = (channel->wires[STDERR])->fd[READ_SIDE];
|
||||
|
||||
XeSPCAddInput(channel, NULL, NULL);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int attach_pipe_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(foo))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* It is an error to try to attach to a pipe channel... */
|
||||
SPC_Error(SPC_Bad_Operation);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int add_input_pipe_channel_object(SPC_Channel_Ptr channel,
|
||||
SbInputHandlerProc handler,
|
||||
void *data)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result, fd;
|
||||
Wire *wirelist, *stdinwire;
|
||||
|
||||
call_parent_method(channel, add_input, (channel, handler, data), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
stdinwire=channel->wires[STDIN];
|
||||
|
||||
for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next) {
|
||||
|
||||
if(wirelist == stdinwire)
|
||||
continue;
|
||||
|
||||
if(wirelist->read_toolkit_id != -1)
|
||||
continue;
|
||||
|
||||
fd=wirelist->fd[READ_SIDE];
|
||||
SPC_XtAddInput(channel,
|
||||
&wirelist->read_toolkit_id,
|
||||
fd,
|
||||
channel->class_ptr->input,
|
||||
SPC_Input);
|
||||
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
1107
cde/lib/DtSvc/DtEncap/pty.c
Normal file
1107
cde/lib/DtSvc/DtEncap/pty.c
Normal file
File diff suppressed because it is too large
Load Diff
488
cde/lib/DtSvc/DtEncap/remote.c
Normal file
488
cde/lib/DtSvc/DtEncap/remote.c
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* File: remote.c $XConsortium: remote.c /main/5 1996/06/21 17:34:53 ageorge $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h>
|
||||
#include <bms/usersig.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <SPC/spc-proto.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void remote_channel_class_init(object_clasp t)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
channel_clasp c=(channel_clasp) t;
|
||||
|
||||
c->new_obj = alloc_channel_object;
|
||||
|
||||
c->open = open_remote_channel_object;
|
||||
c->close = close_remote_channel_object;
|
||||
c->read = read_remote_channel_object;
|
||||
c->write = write_remote_channel_object;
|
||||
c->reset = reset_remote_channel_object;
|
||||
/* pre_fork & post_fork have no method */
|
||||
c->exec_proc = exec_proc_remote_channel_object;
|
||||
c->signal = signal_remote_channel_object;
|
||||
/* wait_for_termination has no method */
|
||||
c->attach = attach_remote_channel_object;
|
||||
c->add_input = add_input_remote_channel_object;
|
||||
c->input = SPC_Conditional_Packet_Handler;
|
||||
c->remove_logfile = remove_logfile_remote_channel_object;
|
||||
|
||||
/* New B.00 methods */
|
||||
|
||||
c->send_eof = send_eof_remote_channel_object;
|
||||
c->set_termio = set_termio_remote_channel_object;
|
||||
|
||||
}
|
||||
|
||||
static struct remote_channel_class remote_channel_class_struct = {
|
||||
(channel_clasp) &channel_class, /* base class pointer */
|
||||
"remote_channel", /* class name */
|
||||
remote_channel_class_init,/* class initialize function */
|
||||
sizeof(SPC_Channel), /* size */
|
||||
0
|
||||
};
|
||||
|
||||
remote_channel_clasp remote_channel_class = &remote_channel_class_struct;
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
Wire *get_new_remote_wire(Wire *prevwire)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *mywire=get_new_wire();
|
||||
|
||||
if(mywire==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
mywire->next=prevwire;
|
||||
return(mywire);
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Method definitions for remote channel objects
|
||||
***
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr open_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
int iomode,
|
||||
XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Channel_Ptr result;
|
||||
int seqno, retval;
|
||||
Wire *tmpwire=NULL;
|
||||
int sid;
|
||||
|
||||
call_parent_method(channel, open, (channel, iomode, hostname), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
channel->cid=0;
|
||||
channel->queued_remote_data=Xe_make_queue(NULL);
|
||||
iomode=channel->IOMode;
|
||||
|
||||
if(IS_SPCIO_STDIN(iomode)) {
|
||||
tmpwire=get_new_remote_wire(tmpwire);
|
||||
channel->wires[STDIN]=tmpwire;
|
||||
}
|
||||
if(IS_SPCIO_STDOUT(iomode)) {
|
||||
tmpwire=get_new_remote_wire(tmpwire);
|
||||
channel->wires[STDOUT]=tmpwire;
|
||||
}
|
||||
if(IS_SPCIO_STDERR(iomode)) {
|
||||
if(!tmpwire || /* ERRORONLY */
|
||||
IS_SPCIO_SEPARATE(iomode))
|
||||
tmpwire=get_new_remote_wire(tmpwire);
|
||||
channel->wires[STDERR]=tmpwire;
|
||||
}
|
||||
|
||||
channel->wire_list=tmpwire;
|
||||
|
||||
if(!(channel->connection=SPC_Open_Connection(hostname)))
|
||||
return(SPC_ERROR);
|
||||
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
CHANNEL_OPEN, iomode);
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
channel->cid=retval;
|
||||
sid=channel->connection->sid;
|
||||
channel->file_descs[STDIN]=sid;
|
||||
channel->file_descs[STDOUT]=sid;
|
||||
channel->file_descs[STDERR]=sid;
|
||||
|
||||
if ((SPC_client_version_number >= SPC_PROTOCOL_VERSION_CDE_BASE) &&
|
||||
(SPC_who_am_i == SPC_I_AM_A_CLIENT)) {
|
||||
channel->wires[STDIN]->master_name = NULL;
|
||||
channel->wires[STDIN]->slave_name = NULL;
|
||||
channel->wires[STDOUT]->master_name = NULL;
|
||||
channel->wires[STDOUT]->slave_name = NULL;
|
||||
channel->wires[STDERR]->master_name = NULL;
|
||||
channel->wires[STDERR]->slave_name = NULL;
|
||||
}
|
||||
else
|
||||
SPC_Query_Devices(channel);
|
||||
|
||||
SPC_Query_Logfile(channel);
|
||||
|
||||
return(channel);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Note that the close routines call the parent method AFTER the
|
||||
** work done for the child method. This is because the parent method
|
||||
** will do all the deallocation.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int close_remote_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int result;
|
||||
int seqno, retval;
|
||||
|
||||
channel->IOMode |= SPCIO_DELAY_CLOSE;
|
||||
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
CHANNEL_CLOSE);
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
|
||||
call_parent_method(channel, close, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int reset_remote_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int result;
|
||||
int seqno, retval;
|
||||
XeQueue tmpqueue;
|
||||
protocol_request_ptr prot;
|
||||
|
||||
call_parent_method(channel, reset, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
CHANNEL_RESET);
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* At this point, we know that the remote server has sent us all
|
||||
necessary data (since RESET expects a reply). So, we are safe to
|
||||
flush any queued data on this channel. */
|
||||
|
||||
{
|
||||
if (tmpqueue=channel->queued_remote_data)
|
||||
{
|
||||
Xe_for_queue(protocol_request_ptr, prot, tmpqueue) {
|
||||
Xe_delete_queue_element(channel->queued_remote_data, prot);
|
||||
SPC_Free_Protocol_Ptr(prot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int exec_proc_remote_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int retval, seqno;
|
||||
int tmp_errorno;
|
||||
|
||||
call_parent_method(channel, exec_proc, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
call_parent_method(channel, pre_fork, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if((channel->connection->protocol_version > 2) ||
|
||||
IS_SPCIO_FORCE_CONTEXT(channel->IOMode))
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
APP_B00_SPAWN,
|
||||
channel->path, channel->context_dir,
|
||||
channel->argv, channel->envp);
|
||||
else
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
APPLICATION_SPAWN,
|
||||
channel->path, channel->context_dir,
|
||||
channel->argv, channel->envp);
|
||||
|
||||
_DtSvcProcessLock();
|
||||
tmp_errorno = XeSPCErrorNumber;
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
if (tmp_errorno != 0)
|
||||
XeSPCErrorNumber = tmp_errorno;
|
||||
_DtSvcProcessUnlock();
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
channel->pid=retval;
|
||||
|
||||
call_parent_method(channel, post_fork, (channel, retval), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int write_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
XeString buffer,
|
||||
int len)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int seqno, retval;
|
||||
int lentogo=len, lentowrite;
|
||||
|
||||
call_parent_method(channel, write, (channel, buffer, len), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
do {
|
||||
|
||||
lentowrite=min(lentogo, SPC_BUFSIZ);
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
APPLICATION_DATA, buffer, lentowrite);
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
lentogo -= lentowrite;
|
||||
buffer += lentowrite;
|
||||
|
||||
} while(lentogo>0);
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int read_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
int connection,
|
||||
XeString buffer,
|
||||
int len)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, read, (channel, connection, buffer, len), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if(!IS_SPCIO_DATA(channel->wires[connection]->flags))
|
||||
return(0);
|
||||
|
||||
result=SPC_Read_Remote_Data(channel, connection, buffer, len);
|
||||
if(result == 0)
|
||||
/* Got EOF. Yank the data line */
|
||||
SPC_Change_State(channel, connection, 0, -1);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int signal_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
int sig)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int seqno, retval;
|
||||
|
||||
call_parent_method(channel, signal, (channel, sig), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if (channel->connection->protocol_version >= 2) {
|
||||
XeString signame = XeSignalToName( sig );
|
||||
|
||||
if (!signame)
|
||||
{
|
||||
SPC_Error(SPC_Bad_Signal_Value, sig);
|
||||
return (SPC_ERROR);
|
||||
}
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
APPLICATION_SIGNAL, signame);
|
||||
}
|
||||
else
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
APPLICATION_SIGNAL, sig);
|
||||
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int attach_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
int pid)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int seqno, retval;
|
||||
|
||||
call_parent_method(channel, attach, (channel, pid), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
CHANNEL_ATTACH, pid);
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
SPC_Flush_Queued_Data(channel);
|
||||
|
||||
if(!mempf0(channel, pre_fork))
|
||||
return(SPC_ERROR);
|
||||
channel->pid = pid;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
remove_logfile_remote_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
int seqno, retval;
|
||||
|
||||
call_parent_method(channel, remove_logfile, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
seqno=SPC_Write_Protocol_Request(channel->connection, channel, DELETE_LOGFILE);
|
||||
retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int add_input_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
SbInputHandlerProc handler,
|
||||
void *data)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
SPC_Connection_Ptr conn=channel->connection;
|
||||
|
||||
call_parent_method(channel, add_input, (channel, handler, data), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if(conn->termination_id != -1)
|
||||
/* We already have a handler, don't need another one */
|
||||
return(TRUE);
|
||||
|
||||
SPC_XtAddInput(channel,
|
||||
&conn->termination_id,
|
||||
conn->sid,
|
||||
channel->class_ptr->input,
|
||||
SPC_Input);
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Debug_Mode(SPC_Channel_Ptr channel,
|
||||
XeString file)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int retval, seqno;
|
||||
|
||||
if(!channel->connection)
|
||||
return(SPC_ERROR);
|
||||
|
||||
retval=SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
SERVER_DEBUG, file);
|
||||
seqno=SPC_Waitfor_Reply(channel->connection, channel, retval);
|
||||
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
return(seqno);
|
||||
|
||||
}
|
||||
|
||||
int send_eof_remote_channel_object(SPC_Channel_Ptr channel)
|
||||
{
|
||||
int retval, seqno;
|
||||
|
||||
if(!channel->connection)
|
||||
return(SPC_ERROR);
|
||||
|
||||
retval =
|
||||
SPC_Write_Protocol_Request(channel->connection, channel, CHANNEL_SEND_EOF);
|
||||
seqno = SPC_Waitfor_Reply(channel->connection, channel, retval);
|
||||
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(seqno);
|
||||
|
||||
}
|
||||
|
||||
int set_termio_remote_channel_object(SPC_Channel_Ptr channel,
|
||||
int connector,
|
||||
int side,
|
||||
struct termios *termios)
|
||||
{
|
||||
int retval, seqno;
|
||||
|
||||
if(!channel->connection)
|
||||
return(SPC_ERROR);
|
||||
|
||||
retval =
|
||||
SPC_Write_Protocol_Request(channel->connection, channel,
|
||||
CHANNEL_TERMIOS,
|
||||
connector, side, termios);
|
||||
seqno = SPC_Waitfor_Reply(channel->connection, channel, retval);
|
||||
|
||||
if(retval==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(seqno);
|
||||
|
||||
}
|
||||
149
cde/lib/DtSvc/DtEncap/sbstdinc.c
Normal file
149
cde/lib/DtSvc/DtEncap/sbstdinc.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* File: sbstdinc.c $TOG: sbstdinc.c /main/5 1999/10/14 15:06:26 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#define SBSTDINC_H_NO_REDEFINE
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
static XeChar XESTRING_SAFE_NULL[1] = {(XeChar)0};
|
||||
|
||||
/************************************************************************/
|
||||
/* Routines from <string.h> */
|
||||
/************************************************************************/
|
||||
|
||||
XeString Xestrcat(XeString s1, ConstXeString s2)
|
||||
{
|
||||
if (!s1) return XeString_NULL;
|
||||
if (!s2) return s1;
|
||||
|
||||
return (XeString) strcat(s1, s2);
|
||||
}
|
||||
|
||||
XeString Xestrncat(XeString s1, ConstXeString s2, size_t n)
|
||||
{
|
||||
if (!s1) return XeString_NULL;
|
||||
if (!s2) return s1;
|
||||
|
||||
return (XeString) strncat(s1, s2, n);
|
||||
}
|
||||
|
||||
int Xestrcmp(ConstXeString s1, ConstXeString s2)
|
||||
{
|
||||
if (s1 == s2) return 0;
|
||||
{
|
||||
const XeChar * p1 = (s1) ? s1 : XESTRING_SAFE_NULL;
|
||||
const XeChar * p2 = (s2) ? s2 : XESTRING_SAFE_NULL;
|
||||
|
||||
return strcmp(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
int Xestrncmp(ConstXeString s1, ConstXeString s2, size_t n)
|
||||
{
|
||||
if (s1 == s2) return 0;
|
||||
{
|
||||
ConstXeString p1 = (s1) ? s1 : XESTRING_SAFE_NULL;
|
||||
ConstXeString p2 = (s2) ? s2 : XESTRING_SAFE_NULL;
|
||||
return strncmp( (char *) p1, (char *) p2, n);
|
||||
}
|
||||
}
|
||||
|
||||
XeString Xestrcpy(XeString s1, ConstXeString s2)
|
||||
{
|
||||
if (!s1) return s1;
|
||||
if (!s2) {
|
||||
*s1 = (XeChar)0;
|
||||
return s1;
|
||||
}
|
||||
|
||||
return (XeString) strcpy(s1, s2);
|
||||
}
|
||||
|
||||
XeString Xestrncpy(XeString s1, ConstXeString s2, size_t n)
|
||||
{
|
||||
if (!s1) return s1;
|
||||
if (!s2 && n) {
|
||||
*s1 = (XeChar)0;
|
||||
return s1;
|
||||
}
|
||||
|
||||
return (XeString) strncpy(s1, s2, n);
|
||||
}
|
||||
|
||||
int Xestrcoll(ConstXeString s1, ConstXeString s2)
|
||||
{
|
||||
if (s1 == s2) return 0;
|
||||
{
|
||||
XeString p1 = (s1) ? (XeString) s1 : XESTRING_SAFE_NULL;
|
||||
XeString p2 = (s2) ? (XeString) s2 : XESTRING_SAFE_NULL;
|
||||
return strcoll(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Xestrxfrm(XeString s1, ConstXeString s2, size_t n)
|
||||
{
|
||||
return strxfrm(s1, s2, n);
|
||||
}
|
||||
|
||||
XeString Xestrchr(ConstXeString s, int c)
|
||||
{
|
||||
if (!s) return XeString_NULL;
|
||||
|
||||
return (XeString) strchr(s, c);
|
||||
}
|
||||
|
||||
XeString Xestrrchr(ConstXeString s, int c)
|
||||
{
|
||||
if (!s) return XeString_NULL;
|
||||
|
||||
return (XeString) strrchr(s, c);
|
||||
}
|
||||
|
||||
XeString Xestrpbrk(ConstXeString s1, ConstXeString s2)
|
||||
{
|
||||
if (!s1) return XeString_NULL;
|
||||
if (!s2) return XeString_NULL;
|
||||
|
||||
return (XeString) strpbrk(s1, s2);
|
||||
}
|
||||
|
||||
XeString Xestrstr(ConstXeString s1, ConstXeString s2)
|
||||
{
|
||||
if (!s1) return XeString_NULL;
|
||||
if (!s2) return XeString_NULL;
|
||||
|
||||
return (XeString) strstr(s1, s2);
|
||||
}
|
||||
|
||||
XeString Xestrtok(XeString s1, ConstXeString s2)
|
||||
{
|
||||
/* s1 is null except after the first call */
|
||||
if (!s2) return XeString_NULL;
|
||||
|
||||
return (XeString) strtok(s1, s2);
|
||||
}
|
||||
|
||||
size_t Xestrlen(ConstXeString const s)
|
||||
{
|
||||
if (!s) return (size_t)0;
|
||||
|
||||
return strlen((char *) s);
|
||||
}
|
||||
|
||||
XeString Xestrdup(ConstXeString s)
|
||||
{
|
||||
if (!s) return XeString_NULL;
|
||||
|
||||
return (XeString) strdup(s);
|
||||
}
|
||||
182
cde/lib/DtSvc/DtEncap/scoop.c
Normal file
182
cde/lib/DtSvc/DtEncap/scoop.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* File: scoop.c $XConsortium: scoop.c /main/3 1995/10/26 15:38:19 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
|
||||
#include "/usr/include/apollo/shlib.h"
|
||||
#endif
|
||||
|
||||
#include <bms/sbport.h> /* This must be the first file included */
|
||||
#include <bms/scoop.h>
|
||||
|
||||
static void system_class_init (object_clasp to_do, object_clasp on_behalf_of);
|
||||
static void system_object_init (object_clasp c, object *p);
|
||||
static void root_class_init (object_clasp c);
|
||||
static void root_object_init (object *p);
|
||||
static object *root_clone (object *this_ptr, object *clone);
|
||||
static object *root_new (object_clasp c);
|
||||
static void root_free (object *p);
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
void object_destroy (object *p)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
memf (p->, free_obj, (p)) ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
object *object_create (object_clasp c)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
object *p ;
|
||||
|
||||
if (! c->init) { system_class_init (c, c) ; }
|
||||
p = (*(c->new_obj))(c) ;
|
||||
if (p)
|
||||
object_init (c, p) ;
|
||||
return p ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
void object_init (object_clasp c, object *p)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (! c->init) { system_class_init (c, c) ; }
|
||||
p->class_ptr = c ;
|
||||
system_object_init (c, p) ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static void system_class_init (object_clasp to_do, object_clasp on_behalf_of)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
object_clasp base ;
|
||||
|
||||
if ( on_behalf_of && to_do && ! on_behalf_of->init )
|
||||
{ }
|
||||
else
|
||||
return ;
|
||||
|
||||
if (to_do == on_behalf_of && to_do != root_class)
|
||||
{ on_behalf_of->base = *((object_clasp *) (on_behalf_of->base)) ;
|
||||
} ;
|
||||
base = to_do->base ;
|
||||
system_class_init (base, base) ;
|
||||
system_class_init (base, on_behalf_of) ;
|
||||
|
||||
if (to_do == on_behalf_of)
|
||||
{ to_do->object_init = root_object_init ;
|
||||
to_do->new_obj = root_new ;
|
||||
to_do->free_obj = root_free ;
|
||||
} ;
|
||||
|
||||
#ifdef GLSDEBUG
|
||||
printf ("-> '%s' class for '%s'\n",
|
||||
to_do->name, on_behalf_of->name) ;
|
||||
#endif /* GLSDEBUG */
|
||||
|
||||
(*(to_do->class_init))(on_behalf_of);
|
||||
if (to_do == on_behalf_of) on_behalf_of->init = TRUE ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static void system_object_init (object_clasp c, object *p)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (!c) return ;
|
||||
|
||||
#ifdef GLSDEBUG
|
||||
printf (" '%s' object for '%s'\n", c->name, p->class_ptr->name) ;
|
||||
#endif /* GLSDEBUG */
|
||||
|
||||
system_object_init (c->base, p) ;
|
||||
|
||||
#ifdef GLSDEBUG
|
||||
printf ("-> '%s' object for '%s'\n", c->name, p->class_ptr->name) ;
|
||||
#endif /* GLSDEBUG */
|
||||
|
||||
(*(c->object_init))(p) ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static void root_class_init (object_clasp c)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
c->clone = root_clone ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static void root_object_init (object * UNUSED_PARM(p))
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
The clone (second) argument to the clone method may be either NULL or an
|
||||
object pointer. If NULL, a space of the size necessary for an object of
|
||||
the same class as the primary object (this) will be allocated. If the
|
||||
input argument is not null, it is assumed that the caller has verified
|
||||
there is sufficient space for a copy of the original object.
|
||||
If the clone procedure does allocate the space for the clone, it only
|
||||
allocates the space. It does not do object initialization.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static object *root_clone (object *this_ptr, object *clone)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
register XeString orig = (XeString) this_ptr ;
|
||||
register XeString copy ;
|
||||
|
||||
register object_clasp o_class = this_ptr->class_ptr ;
|
||||
register OSizeType size = o_class->object_size ;
|
||||
|
||||
if ( ! clone )
|
||||
clone = (*(o_class->new_obj))(o_class) ;
|
||||
if (clone) {
|
||||
copy = (XeString) clone ;
|
||||
while (size--)
|
||||
*copy++ = *orig++ ;
|
||||
}
|
||||
return clone ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static object *root_new (object_clasp c)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{ object *p = (object *)malloc((unsigned) c->object_size) ;
|
||||
|
||||
/* Don't use XeMalloc here, we want to be able to grab our Edit */
|
||||
/* widget without the rest of the world being pulled in. */
|
||||
if (!p)
|
||||
{
|
||||
fprintf(stderr, "scoop: malloc in root_new failed, out of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return p ;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
static void root_free (object *p)
|
||||
/*--------------------------------------------------------------------------+*/
|
||||
{
|
||||
if (p) free ((char *)p) ;
|
||||
}
|
||||
|
||||
struct root_class root_class_struct = {
|
||||
(object_clasp) NULL, /* root has no base class */
|
||||
"root", /* class name */
|
||||
root_class_init,
|
||||
sizeof (object),
|
||||
0,
|
||||
} ;
|
||||
|
||||
object_clasp root_class = & root_class_struct ;
|
||||
407
cde/lib/DtSvc/DtEncap/spc-env.c
Normal file
407
cde/lib/DtSvc/DtEncap/spc-env.c
Normal file
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* File: spc-env.c $TOG: spc-env.c /main/9 1998/04/10 08:27:04 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
|
||||
#include <bms/MemoryMgr.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
#include <XlationSvc.h>
|
||||
#include <LocaleXlate.h>
|
||||
|
||||
/* External declarations */
|
||||
|
||||
extern XeString official_hostname; /* from spc-net.c */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString SPC_Getenv(XeString var,
|
||||
XeString *envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int len;
|
||||
XeString *envidx;
|
||||
XeString idx;
|
||||
|
||||
/* First, check that we have real values */
|
||||
|
||||
if(!var || !envp || !*envp)
|
||||
return(XeString_NULL);
|
||||
|
||||
/* Look for '=' */
|
||||
|
||||
idx=strchr(var, Equal);
|
||||
|
||||
if(idx==0)
|
||||
/* No '='. Just use the entire var string */
|
||||
len=strlen(var);
|
||||
else
|
||||
/* found '='. Diddle pointers to get index of var */
|
||||
len=(strchr(var, Equal))-var;
|
||||
|
||||
for(envidx=envp; *envidx; envidx++) {
|
||||
if(!strncmp(*envidx, var, len))
|
||||
/* Found a match. Return value part */
|
||||
return(*envidx+len+1);
|
||||
}
|
||||
|
||||
return(XeString_NULL);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** The purpose of SPC_Putenv is to maintain the environment pointers
|
||||
** associated with a given channel. It differs from the normal putenv
|
||||
** routine in the following ways:
|
||||
** 1. It copies its arguments (and frees any arguments which get a "hit")
|
||||
** 2. It takes an environment pointer which will be used to store the
|
||||
** new value. This new pointer may change (via realloc).
|
||||
**
|
||||
** Note: This routine makes a number of assumptions:
|
||||
** 1. The envp pointer was allocated via malloc.
|
||||
** 2. That it is okay to ignore error conditions. In particular,
|
||||
** it will ignore incorrect pointers (which is okay, as this
|
||||
** guy is an internal routine which means that these pointers
|
||||
** have been already checked), and it will ignore syntax errors
|
||||
** in the passed value. The latter ignore may be slightly
|
||||
** problematical, but it happens.
|
||||
** 3. That memory allocation errors cause the program to bomb.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString *SPC_Putenv(XeString val,
|
||||
XeString *envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
int len, newsize;
|
||||
XeString *envptr;
|
||||
char *pch;
|
||||
int remove_command = 0;
|
||||
#ifdef NLS16
|
||||
int is_multibyte = 0;
|
||||
#endif /* NLS16 */
|
||||
|
||||
#ifdef NLS16
|
||||
if (MB_CUR_MAX > 1)
|
||||
is_multibyte = 1;
|
||||
else
|
||||
is_multibyte = 0;
|
||||
#endif /* NLS16 */
|
||||
|
||||
/* Again, check for real values */
|
||||
|
||||
if(!val || !envp) {
|
||||
return(envp);
|
||||
}
|
||||
|
||||
/* Look for '=' */
|
||||
|
||||
len=(strchr(val, (XeChar)'='))-val;
|
||||
if(len<0) {
|
||||
/*
|
||||
* This string doesn't contain an '='. This may be OK if
|
||||
* the string contains a 'remove environment variable' keyword.
|
||||
* If this keyword is found, treat it like a variable and
|
||||
* the SPC daemon will find it and remove it from the
|
||||
* environment before it exec's a subprocess.
|
||||
*
|
||||
* If the string contains some white space before the variable
|
||||
* or keyword, skip the white space.
|
||||
*/
|
||||
pch = val;
|
||||
while (
|
||||
#ifdef NLS16
|
||||
(!is_multibyte || (mblen (pch, MB_CUR_MAX) == 1)) &&
|
||||
#endif
|
||||
isspace ((u_char)*pch))
|
||||
pch++;
|
||||
if (*pch == '\000')
|
||||
return (envp);
|
||||
if (strncmp (pch, SPC_REMOVE_VAR, strlen (SPC_REMOVE_VAR)))
|
||||
return(envp);
|
||||
remove_command = 1;
|
||||
val = pch;
|
||||
len = strlen (SPC_REMOVE_VAR);
|
||||
}
|
||||
|
||||
for(envptr=envp; *envptr; envptr++) {
|
||||
if(!strncmp(*envptr, val, len) && !remove_command) {
|
||||
/* Found a match. Replace this value with the one passed */
|
||||
free(*envptr);
|
||||
*envptr=SPC_copy_string(val);
|
||||
return(envp);
|
||||
}
|
||||
}
|
||||
|
||||
/* No match. We need to expand this env pointer, and stash the
|
||||
new value at the end */
|
||||
|
||||
len=envptr-envp;
|
||||
|
||||
/* calculate new size needed:
|
||||
len=ptr to null element
|
||||
newsize=len+2 (one for NULL, one for new element)
|
||||
*/
|
||||
|
||||
newsize=(len+2)*sizeof(XeString *);
|
||||
|
||||
/* Expand envp. This is a potentially expensive operation, if the
|
||||
realloc routine is not smart. */
|
||||
|
||||
if(!(envp=(XeString *)realloc((char *)envp, newsize))) {
|
||||
SPC_Error(SPC_Out_Of_Memory);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Okay. We got the new memory. Stash the new variable into it &
|
||||
return the new envp.*/
|
||||
|
||||
envp[len]=SPC_copy_string(val);
|
||||
envp[len+1]=XeChar_NULL;
|
||||
|
||||
return(envp);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString *SPC_Add_Env_File(XeString filename,
|
||||
XeString *envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
FILE *f;
|
||||
int n;
|
||||
XeChar fbuffer[BUFSIZ];
|
||||
|
||||
if(!filename)
|
||||
return(envp);
|
||||
|
||||
/* Open stream */
|
||||
|
||||
if(!(f=fopen(filename, "r")))
|
||||
return(envp);
|
||||
|
||||
while(fgets(fbuffer, BUFSIZ, f)) {
|
||||
n=strlen(fbuffer);
|
||||
if(fbuffer[n-1]==Newline)
|
||||
fbuffer[--n]=Pad; /* get rid of the extra newline */
|
||||
|
||||
/* Should we skip this line? */
|
||||
|
||||
if(n==XeChar_NULL || fbuffer[0]==Pad || fbuffer[0]==Pound) continue;
|
||||
|
||||
envp=SPC_Putenv(fbuffer, envp);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return(envp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString *SPC_Create_Default_Envp(XeString *old_envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
XeString *envp;
|
||||
XeChar *display;
|
||||
XeString envVar;
|
||||
XeString sys_env_path = NULL;
|
||||
|
||||
if(old_envp)
|
||||
envp=old_envp;
|
||||
else {
|
||||
envp=(XeString *)XeMalloc(sizeof(XeString) * DEFAULT_ENVP_SIZE);
|
||||
envp[0]=XeChar_NULL;
|
||||
}
|
||||
|
||||
if(!(envVar=getenv("DISPLAY")))
|
||||
{
|
||||
display = (XeChar *)malloc(
|
||||
(strlen(official_hostname) + 11) * sizeof(XeChar));
|
||||
if (display != (XeChar *)NULL)
|
||||
sprintf(display, "DISPLAY=%s:0", official_hostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
display = (XeChar *)malloc((strlen(envVar) + 9) * sizeof(XeChar));
|
||||
if (display != (XeChar *)NULL)
|
||||
sprintf(display, "DISPLAY=%s", envVar);
|
||||
}
|
||||
|
||||
if (display != (XeChar *)NULL)
|
||||
{
|
||||
envp=SPC_Putenv(display, envp);
|
||||
free(display);
|
||||
}
|
||||
|
||||
/*
|
||||
* Should we pick a default value for LANG (e.g. "C")?
|
||||
* For now we ignore it if it is not already set.
|
||||
*/
|
||||
if ((envVar = getenv("LANG")) != (XeString)NULL)
|
||||
{
|
||||
XeChar *langBuf;
|
||||
|
||||
if ((langBuf = (XeChar *)malloc((strlen(envVar) + 6) * sizeof(XeChar)))
|
||||
!= (XeChar *)NULL)
|
||||
{
|
||||
sprintf(langBuf, "LANG=%s", envVar);
|
||||
envp = SPC_Putenv(langBuf, envp);
|
||||
|
||||
free(langBuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* First add the installed environment file.
|
||||
*/
|
||||
sys_env_path = (XeString) malloc (strlen(SPCD_ENV_INSTALL_DIRECTORY) +
|
||||
strlen(SPCD_ENV_FILE) + 3);
|
||||
(void) sprintf (sys_env_path, "%s/%s",
|
||||
SPCD_ENV_INSTALL_DIRECTORY,
|
||||
SPCD_ENV_FILE);
|
||||
envp=SPC_Add_Env_File(sys_env_path, envp);
|
||||
|
||||
/*
|
||||
* Next add the configured environment file.
|
||||
*/
|
||||
sys_env_path = (XeString) realloc (sys_env_path,
|
||||
strlen(SPCD_ENV_CONFIG_DIRECTORY) +
|
||||
strlen(SPCD_ENV_FILE) + 3);
|
||||
(void) sprintf (sys_env_path, "%s/%s",
|
||||
SPCD_ENV_CONFIG_DIRECTORY,
|
||||
SPCD_ENV_FILE);
|
||||
envp=SPC_Add_Env_File(sys_env_path, envp);
|
||||
|
||||
/*
|
||||
* Now add the user environment file
|
||||
*/
|
||||
_DtSvcProcessLock();
|
||||
envp=SPC_Add_Env_File(spc_user_environment_file, envp);
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
free(sys_env_path);
|
||||
|
||||
return(envp);
|
||||
}
|
||||
|
||||
/* Final cleanup of environment pointer */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString *SPC_Fixup_Environment(XeString *envp,
|
||||
SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(!envp)
|
||||
return(envp);
|
||||
|
||||
if (IS_REMOTE(channel))
|
||||
{
|
||||
XeString disp, myLang;
|
||||
|
||||
disp=SPC_Getenv((XeString)"DISPLAY", envp);
|
||||
|
||||
/* I don't particularly like hard coding these values here.
|
||||
I have been bitten before by doing so, and probably will again... */
|
||||
if (!strncmp(disp, (XeString)"unix", 4) ||
|
||||
!strncmp(disp, (XeString)"local", 5) ||
|
||||
!strncmp(disp, (XeString)":", 1))
|
||||
{
|
||||
XeChar *dispBuf = NULL;
|
||||
XeString screenptr;
|
||||
XeChar null=XeChar_NULL;
|
||||
|
||||
dispBuf =
|
||||
(XeChar*) malloc(MAXHOSTNAMELEN + sizeof((XeString)"DISPLAY=:0.0") + 1);
|
||||
if (dispBuf)
|
||||
{
|
||||
screenptr=strchr(disp, Colon);
|
||||
sprintf(dispBuf, "DISPLAY=%s%s",
|
||||
official_hostname,
|
||||
screenptr ? screenptr : &null);
|
||||
|
||||
envp=SPC_Putenv(dispBuf, envp);
|
||||
free(dispBuf);
|
||||
}
|
||||
}
|
||||
|
||||
myLang = SPC_Getenv((XeString)"LANG", envp);
|
||||
if (myLang)
|
||||
{
|
||||
_DtXlateDb db = NULL;
|
||||
char platform[_DtPLATFORM_MAX_LEN];
|
||||
int execVer;
|
||||
int compVer;
|
||||
char *stdLang;
|
||||
XeChar *langBuf;
|
||||
|
||||
if (_DtLcxOpenAllDbs(&db) == 0)
|
||||
{
|
||||
if ((_DtXlateGetXlateEnv(db, platform, &execVer, &compVer) == 0) &&
|
||||
(_DtLcxXlateOpToStd(db, platform, compVer, DtLCX_OPER_SETLOCALE,
|
||||
myLang, &stdLang, NULL, NULL, NULL) == 0))
|
||||
{
|
||||
if ((langBuf = (XeChar *)malloc((strlen(stdLang) + 6) *
|
||||
sizeof(XeChar)))
|
||||
!= (XeChar *)NULL)
|
||||
{
|
||||
sprintf(langBuf, "LANG=%s", stdLang);
|
||||
envp = SPC_Putenv(langBuf, envp);
|
||||
free(langBuf);
|
||||
}
|
||||
|
||||
free(stdLang);
|
||||
}
|
||||
|
||||
_DtLcxCloseDb(&db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(envp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString *SPC_Merge_Envp(XeString *dest_envp,
|
||||
XeString *source_envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(!dest_envp || !source_envp)
|
||||
return(dest_envp);
|
||||
for(; *source_envp; source_envp++)
|
||||
dest_envp=SPC_Putenv(*source_envp, dest_envp);
|
||||
|
||||
return(dest_envp);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void SPC_Free_Envp(XeString *envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString *envptr=envp;
|
||||
|
||||
if(!envptr)
|
||||
return;
|
||||
|
||||
while (*envptr)
|
||||
free(*envptr++);
|
||||
|
||||
free((char *)envp);
|
||||
}
|
||||
762
cde/lib/DtSvc/DtEncap/spc-error.c
Normal file
762
cde/lib/DtSvc/DtEncap/spc-error.c
Normal file
@@ -0,0 +1,762 @@
|
||||
/*
|
||||
* $TOG: spc-error.c /main/10 1998/04/10 08:27:30 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <bms/MemoryMgr.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#define X_INCLUDE_TIME_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Log file information (routines near bottom of file)
|
||||
*/
|
||||
|
||||
#define TEMPLATE_EXTENSION (XeString)".XXXXXX" /* For mktemp(3c) */
|
||||
|
||||
XeChar spc_logfile[MAXPATHLEN+1];
|
||||
XeChar spc_logging = FALSE;
|
||||
/* FILE *spc_logF = NULL; -- to bmsglob.c */
|
||||
|
||||
int spc_logfd = NULL;
|
||||
|
||||
/* This is the SPC error number variable */
|
||||
/* ------------------------------------- */
|
||||
/* int XeSPCErrorNumber = NULL; --- now in bmsglob.c */
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static XeString
|
||||
err_mnemonic(unsigned int errn, char *buff)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Since there is currently no standard way to get an err number */
|
||||
/* mnenonic from the system, we do it the hard way. We can't even */
|
||||
/* use a table as the actual numeric values may differ on machines. */
|
||||
/* Another potential problem is if one of these gets passed across */
|
||||
/* a network connection from a different type of machine that has */
|
||||
/* values that differ than the machine this routine runs on, we */
|
||||
/* could have problems. I don't think anycode does that now. */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
XeString s;
|
||||
|
||||
switch (errn) {
|
||||
|
||||
/* These are all in POSIX 1003.1 and/or X/Open XPG3 */
|
||||
/* ---------------------------------------------------- */
|
||||
case EPERM : s = (XeString)"EPERM"; break;
|
||||
case ENOENT : s = (XeString)"ENOENT"; break;
|
||||
case ESRCH : s = (XeString)"ESRCH"; break;
|
||||
case EINTR : s = (XeString)"EINTR"; break;
|
||||
case EIO : s = (XeString)"EIO"; break;
|
||||
case ENXIO : s = (XeString)"ENXIO"; break;
|
||||
case E2BIG : s = (XeString)"E2BIG"; break;
|
||||
case ENOEXEC : s = (XeString)"ENOEXEC"; break;
|
||||
case EBADF : s = (XeString)"EBADF"; break;
|
||||
case ECHILD : s = (XeString)"ECHILD"; break;
|
||||
case EAGAIN : s = (XeString)"EAGAIN"; break;
|
||||
case ENOMEM : s = (XeString)"ENOMEM"; break;
|
||||
case EACCES : s = (XeString)"EACCES"; break;
|
||||
case EFAULT : s = (XeString)"EFAULT"; break;
|
||||
case ENOTBLK : s = (XeString)"ENOTBLK"; break;
|
||||
case EBUSY : s = (XeString)"EBUSY"; break;
|
||||
case EEXIST : s = (XeString)"EEXIST"; break;
|
||||
case EXDEV : s = (XeString)"EXDEV"; break;
|
||||
case ENODEV : s = (XeString)"ENODEV"; break;
|
||||
case ENOTDIR : s = (XeString)"ENOTDIR"; break;
|
||||
case EISDIR : s = (XeString)"EISDIR"; break;
|
||||
case EINVAL : s = (XeString)"EINVAL"; break;
|
||||
case ENFILE : s = (XeString)"ENFILE"; break;
|
||||
case EMFILE : s = (XeString)"EMFILE"; break;
|
||||
case ENOTTY : s = (XeString)"ENOTTY"; break;
|
||||
case ETXTBSY : s = (XeString)"ETXTBSY"; break;
|
||||
case EFBIG : s = (XeString)"EFBIG"; break;
|
||||
case ENOSPC : s = (XeString)"ENOSPC"; break;
|
||||
case ESPIPE : s = (XeString)"ESPIPE"; break;
|
||||
case EROFS : s = (XeString)"EROFS"; break;
|
||||
case EMLINK : s = (XeString)"EMLINK"; break;
|
||||
case EPIPE : s = (XeString)"EPIPE"; break;
|
||||
case ENOMSG : s = (XeString)"ENOMSG"; break;
|
||||
case EIDRM : s = (XeString)"EIDRM"; break;
|
||||
case EDEADLK : s = (XeString)"EDEADLK"; break;
|
||||
case ENOLCK : s = (XeString)"ENOLCK"; break;
|
||||
#ifndef __aix
|
||||
case ENOTEMPTY : s = (XeString)"ENOTEMPTY"; break;
|
||||
#endif
|
||||
case ENAMETOOLONG : s = (XeString)"ENAMETOOLONG"; break;
|
||||
case ENOSYS : s = (XeString)"ENOSYS"; break;
|
||||
|
||||
/* You could include machine specific stuff here ... */
|
||||
/* ---------------------------------------------------- */
|
||||
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
default : s = XeString_NULL; break;
|
||||
}
|
||||
|
||||
|
||||
if (s)
|
||||
sprintf(buff, "%s (%d)",s,errn);
|
||||
else
|
||||
sprintf(buff, "(%d)",errn);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString SPC_copy_string(XeString str)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int len;
|
||||
XeString tmp_str;
|
||||
|
||||
if(!str)
|
||||
return(XeString_NULL);
|
||||
|
||||
len=strlen(str);
|
||||
|
||||
tmp_str=(XeString)XeMalloc(len+1);
|
||||
strcpy(tmp_str, str);
|
||||
return(tmp_str);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void SPC_Error (int error, ...)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
va_list ap;
|
||||
SPCError *err;
|
||||
XeChar *buffer;
|
||||
XeString arg1;
|
||||
long arg2;
|
||||
XeChar buff[40];
|
||||
|
||||
err=SPC_Lookup_Error(error);
|
||||
|
||||
if(!err)
|
||||
return;
|
||||
|
||||
if(err->text) {
|
||||
free(err->text);
|
||||
err->text = NULL;
|
||||
}
|
||||
|
||||
va_start(ap, error); /** Start varargs **/
|
||||
arg1=va_arg(ap, XeString);
|
||||
|
||||
if (arg1)
|
||||
{
|
||||
/* The argument on the stack may be holding an int or a char pointer. */
|
||||
/* Always popping off a long into the value of arg2 works fine */
|
||||
/* because the subsequent call to sprintf does the proper conversion via */
|
||||
/* "err->format". */
|
||||
arg2=va_arg(ap, long);
|
||||
}
|
||||
else
|
||||
{
|
||||
arg1 = XeString_Empty;
|
||||
arg2 = 0;
|
||||
}
|
||||
|
||||
buffer = (XeChar*) malloc(sizeof(XeChar) * SPC_BUFSIZ);
|
||||
if (buffer)
|
||||
{
|
||||
sprintf(buffer, err->format, arg1, arg2);
|
||||
err->text=SPC_copy_string(buffer);
|
||||
free(buffer);
|
||||
}
|
||||
va_end(ap); /** End varargs **/
|
||||
|
||||
_DtSvcProcessLock();
|
||||
XeSPCErrorNumber=error;
|
||||
if (SPC_who_am_i == SPC_I_AM_A_DAEMON){
|
||||
|
||||
SPC_Format_Log((XeString)"DTSPCD error (%d): %s",
|
||||
XeSPCErrorNumber, err->text);
|
||||
if (err->use_errno){
|
||||
XeString errname;
|
||||
XeString errmsg;
|
||||
unsigned int errn = errno;
|
||||
|
||||
errname = err_mnemonic(errn, buff);
|
||||
|
||||
if (!(errmsg = strerror(errn)))
|
||||
errmsg = (XeString) "unknown";
|
||||
|
||||
SPC_Format_Log((XeString)" [%s] %s", errname, errmsg);
|
||||
}
|
||||
if(err->severity == XeFatalError || err->severity == XeInternalError) {
|
||||
SPC_Format_Log((XeString)"Exiting server ...");
|
||||
SPC_Close_Log();
|
||||
_DtSvcProcessUnlock();
|
||||
exit (3);
|
||||
}
|
||||
}
|
||||
else
|
||||
_DtSimpleError(XeProgName, XeError, XeString_NULL, err->text);
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Log file routines
|
||||
*
|
||||
* Note: Current restriction of only one log file open at a time.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Make_Log_Filename(XeString name,
|
||||
int unique) /* When TRUE, make name unique */
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Make a log filename based on the passed name (and perhaps process id) */
|
||||
XeString cp;
|
||||
XeString log_file_path = NULL;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
/* first build the log file path */
|
||||
if (!name || !*name) {
|
||||
log_file_path = XeSBTempPath((XeString)"DTSPCD_log");
|
||||
strcpy(spc_logfile, log_file_path);
|
||||
}
|
||||
else {
|
||||
if (strlen(name) > MAXPATHLEN)
|
||||
_DtSimpleError(XeProgName, XeInternalError, XeString_NULL,
|
||||
(XeString)"String too long in DTSPCD_Make_Log_Filename()");
|
||||
|
||||
strcpy(spc_logfile, name);
|
||||
}
|
||||
|
||||
if (unique) {
|
||||
/* Add the extension. No strlen checking is done */
|
||||
strcat(spc_logfile, TEMPLATE_EXTENSION);
|
||||
|
||||
cp = (XeString) mktemp(spc_logfile);
|
||||
if (!cp || !*cp) {
|
||||
/* Sorry, but this is the best we can do */
|
||||
strcpy(spc_logfile, (log_file_path) ? log_file_path : name);
|
||||
}
|
||||
}
|
||||
|
||||
/* free the strings allocated for the path */
|
||||
if (log_file_path) XeFree(log_file_path);
|
||||
_DtSvcProcessUnlock();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Open_Log(XeString filename,
|
||||
int unique) /* When TRUE, make filename unique */
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Open the SPC log file */
|
||||
|
||||
/* Use the filename if one was passed to make a log filename */
|
||||
SPC_Make_Log_Filename(filename, unique);
|
||||
|
||||
/* Open the logfile */
|
||||
_DtSvcProcessLock();
|
||||
spc_logF = fopen(spc_logfile, "a+");
|
||||
if (!spc_logF) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
spc_logging = TRUE;
|
||||
|
||||
SPC_Format_Log((XeString)"*** DTSPCD logging started, file: `%s'", spc_logfile);
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Close_Log(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Close the current log file */
|
||||
|
||||
SPC_Format_Log((XeString)"*** DTSPCD logging stopped");
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (spc_logF) {
|
||||
fclose(spc_logF);
|
||||
}
|
||||
spc_logfd = NULL;
|
||||
spc_logF = NULL;
|
||||
spc_logging = FALSE;
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Write_Log(XeString str)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Write the passed message to the log file */
|
||||
time_t t;
|
||||
_Xctimeparams ctime_buf;
|
||||
char *result;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (spc_logging && spc_logF) {
|
||||
t = time(NULL);
|
||||
result = _XCtime(&t, ctime_buf);
|
||||
fprintf(spc_logF, "%s: %s", str, result);
|
||||
fflush(spc_logF);
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int SPC_Format_Log (XeString format, ...)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Format the passed message to the log file */
|
||||
va_list args;
|
||||
time_t t;
|
||||
_Xctimeparams ctime_buf;
|
||||
char *result;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (spc_logging && spc_logF) {
|
||||
/* First the message */
|
||||
va_start(args, format);
|
||||
vfprintf(spc_logF, format, args);
|
||||
va_end(args);
|
||||
|
||||
/* Now a time stamp */
|
||||
t = time(NULL);
|
||||
result = _XCtime(&t, ctime_buf);
|
||||
fprintf(spc_logF, ": %s", result);
|
||||
fflush(spc_logF);
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** This next routine used to be such a nice little guy... Once upon a
|
||||
** time I had all the error messages in a very
|
||||
** compact representation. It was a vector of SPCError structures.
|
||||
** When I wanted to go from the integer representation of an error to
|
||||
** its textual form, I simply did a table lookup. Unfortunately,
|
||||
** that method did not work at all well with the NLS scheme cooked up
|
||||
** by the Excalibur team. This scheme was nice for programs which
|
||||
** just had the strings in the text. It basically searched the
|
||||
** source program for a string with a funny symbol and replaced it
|
||||
** with a function call. Well, to make a long story short, I decided
|
||||
** to go with that scheme. Thus this function.
|
||||
**
|
||||
*/
|
||||
|
||||
SPCError spc_error_struct;
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPCError *SPC_Lookup_Error(int errornum)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
switch (errornum) {
|
||||
|
||||
case SPC_Out_Of_Memory:
|
||||
spc_error_struct.format = (XeString) "><Unable to allocate memory for internal SPC operation\n Perhaps you need to add more swap space to the system";
|
||||
spc_error_struct.severity = XeFatalError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Argument:
|
||||
spc_error_struct.format = (XeString) "><Bad argument to DTSPCD call";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Active_Channel:
|
||||
spc_error_struct.format = (XeString) "><Channel already active";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Inactive_Channel:
|
||||
spc_error_struct.format = (XeString) "><Channel is not active";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Internal_Error:
|
||||
spc_error_struct.format = (XeString) "><Internal SPC Error";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Cannot_Fork:
|
||||
spc_error_struct.format = (XeString) "><Cannot fork";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Cannot_Exec:
|
||||
spc_error_struct.format = (XeString) "><Cannot exec file %s.\nPerhaps your PATH variable is incorrect.\nUse the following errno value to further diagnose the problem.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_No_Pipe:
|
||||
spc_error_struct.format = (XeString) "><Cannot get pipe";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_No_Pty:
|
||||
spc_error_struct.format = (XeString) "><Unable to allocate pty for a DTSPCD channel.\nTry cleaning up some currently running processes to release their ptys,\nor reconfigure your kernel to increase the pty limit.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Connector:
|
||||
spc_error_struct.format = (XeString) "><Bad connector";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Reading:
|
||||
spc_error_struct.format = (XeString) "><Unexpected error reading data on connection to host %s.\nUse the following errno value to correct the problem.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Writing:
|
||||
spc_error_struct.format = (XeString) "><Unexpected error writing data on channel";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Service:
|
||||
spc_error_struct.format = (XeString) "><Unknown internet service %s/%s.\nMake an entry in your /etc/services file";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Unknown_Host:
|
||||
spc_error_struct.format = (XeString) "><Unable to find a host entry for %s.\nTry adding an entry in /etc/hosts for it.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Socket:
|
||||
spc_error_struct.format = (XeString) "><Socket failed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Connect:
|
||||
spc_error_struct.format = (XeString) "><Connect call failed to remote host %s\nPerhaps the desktop is not installed on the remote host,\nor the remote inetd program needs to be restarted (via 'inetd -c'),\nor the remote file /etc/inetd.conf does not have an entry for the dtspcd process.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Bind:
|
||||
spc_error_struct.format = (XeString) "><Bind failed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Accept:
|
||||
spc_error_struct.format = (XeString) "><Accept failed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Reuse:
|
||||
spc_error_struct.format = (XeString) "><Reuse socket option failed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Open:
|
||||
spc_error_struct.format = (XeString) "><Cannot open file";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Connection_EOF:
|
||||
if (SPC_who_am_i == SPC_I_AM_A_DAEMON)
|
||||
spc_error_struct.format = (XeString) "><Client has disconneted (received EOF).";
|
||||
else
|
||||
spc_error_struct.format = (XeString) "><The dtspcd process on host '%s' has terminated.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Timeout:
|
||||
spc_error_struct.format = (XeString) "><Internal timeout expired";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Protocol:
|
||||
spc_error_struct.format = (XeString) "><Illegal protocol request";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Unexpected_Reply:
|
||||
spc_error_struct.format = (XeString) "><Protocol error: unexpected reply";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_No_Channel:
|
||||
spc_error_struct.format = (XeString) "><Cannot initialize channel";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Illegal_Iomode:
|
||||
spc_error_struct.format = (XeString) "><Inconsistent iomode value specified";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_No_Signal_Handler:
|
||||
spc_error_struct.format = (XeString) "><Cannot set SIGCLD handler";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Operation:
|
||||
spc_error_struct.format = (XeString) "><Illegal operation";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Fd:
|
||||
spc_error_struct.format = (XeString) "><Bad file descriptor";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Ioctl:
|
||||
spc_error_struct.format = (XeString) "><ioctl call failed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Select:
|
||||
spc_error_struct.format = (XeString) "><select call failed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bind_Timeout:
|
||||
spc_error_struct.format = (XeString) "><Timeout on bind";
|
||||
spc_error_struct.severity = XeWarning;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Arg_Too_Long:
|
||||
spc_error_struct.format = (XeString) "><Argument %.50s... to DTSPCD system call is too long, max. length is %d";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Write_Prot:
|
||||
spc_error_struct.format = (XeString) "><Error writing protocol request to host %s.\nPerhaps the remote server has crashed.\nUse the following errno value to diagnose the problem.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Username:
|
||||
spc_error_struct.format = (XeString) "><Incorrect user name";
|
||||
spc_error_struct.severity = XeFatalError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Password:
|
||||
spc_error_struct.format = (XeString) "><Incorrect password";
|
||||
spc_error_struct.severity = XeFatalError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Client_Not_Valid:
|
||||
spc_error_struct.format = (XeString) "><Client not valid";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Cannot_Open_Slave:
|
||||
spc_error_struct.format = (XeString) "><Unable to open slave pty %s.\nUse the following errno value to correct the problem";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Protocol_Abort:
|
||||
spc_error_struct.format = (XeString) "><Received ABORT protocol request on connection to %s.";
|
||||
spc_error_struct.severity = XeFatalError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Env_Too_Big:
|
||||
spc_error_struct.format = (XeString) "><Environment variable %.50s... too big,\nmaximum size is %d\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Unlink_Logfile:
|
||||
spc_error_struct.format = (XeString) "><Cannot unlink logfile";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Closed_Channel:
|
||||
spc_error_struct.format = (XeString) "><Channel already closed";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Authentication:
|
||||
spc_error_struct.format = (XeString) "><Cannot open user authentication file";
|
||||
spc_error_struct.severity = XeFatalError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Cannot_Open_Log:
|
||||
spc_error_struct.format = (XeString) "><Unable to open log file %s\nUse the following errno value to correct the problem";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Connection_Reset:
|
||||
spc_error_struct.format = (XeString) "><Remote data connection to %s reset by peer\nRemote host may not have an entry for the local host in /usr/adm/inetd.sec.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Register_Username:
|
||||
spc_error_struct.format = (XeString) "><Cannot register user --\nImproper password or uid for user '%s' on remote host '%s'.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Register_Netrc:
|
||||
spc_error_struct.format = (XeString) "><Cannot register user --\nUnable to create a pathname to the authentication file '%s' on host '%s'.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Register_Open:
|
||||
spc_error_struct.format = (XeString) "><Cannot register user --\nUnable to open authentication file '%s' on host '%s'.\nUse the following errno value to diagnose the problem.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Register_Handshake:
|
||||
spc_error_struct.format = (XeString) "><Cannot register user --\nPerhaps user '%s' does not have the same uid on host '%s'.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Termios_Mode :
|
||||
spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe item '%s' is not recognized as a valid item for the Mode flags.\nThe item has been ignored.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Termios_Speed :
|
||||
spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe item '%s' is not recognized as a valid item for a speed setting.\nThe item has been ignored.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Termios_CC :
|
||||
spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe item '%s' is not recognized as a valid item for a Control Character name/value pair.\nThe item has been ignored.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Termios_Proto :
|
||||
spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe string does not have the correct number of fields -- %s.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Signal_Name :
|
||||
spc_error_struct.format = (XeString) "><The signal '%s' is not supported on this machine.\nThe DTSPCD signal request has been ignored.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Signal_Value :
|
||||
spc_error_struct.format = (XeString) "><The signal %d is not supported by the XeSignalToName() routine.\nIt can not be sent via DTSPCD to a remote machine.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Signal_Format :
|
||||
spc_error_struct.format = (XeString) "><The APPLICATION_SIGNAL DTSPCD data '%s' is not recognized.\nIt is expected to be a signal name or a signal number.\n";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_tc_Call :
|
||||
spc_error_struct.format = (XeString) "><The terminal control call to '%s' failed.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_cannot_Chdir :
|
||||
spc_error_struct.format = (XeString) "><Cannot cd to directory '%s'.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Bad_Permission :
|
||||
spc_error_struct.format = (XeString) "><Incorrect permission on DTSPCD Authentication file.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = TRUE;
|
||||
break;
|
||||
|
||||
case SPC_Cannot_Create_Netfilename :
|
||||
spc_error_struct.format = (XeString) "><Cannot create a pathname to the current working\ndirectory '%s' from host '%s'.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
case SPC_Protocol_Version_Error:
|
||||
spc_error_struct.format = (XeString) "><SPC protocol version mismatch. The local version is %d, but the version of the SPC Daemon is %d. This operation requires equivalent protocol versions.";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
spc_error_struct.format = (XeString) "><Unknown error code";
|
||||
spc_error_struct.severity = XeError;
|
||||
spc_error_struct.use_errno = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(&spc_error_struct);
|
||||
}
|
||||
|
||||
978
cde/lib/DtSvc/DtEncap/spc-exec.c
Normal file
978
cde/lib/DtSvc/DtEncap/spc-exec.c
Normal file
@@ -0,0 +1,978 @@
|
||||
/*
|
||||
* File: spc-exec.c $TOG: spc-exec.c /main/9 1998/10/26 17:22:38 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <bms/MemoryMgr.h>
|
||||
|
||||
#include <SPC/spc-proto.h>
|
||||
|
||||
#ifdef SVR4
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <Tt/tt_c.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/* Global vars. */
|
||||
|
||||
SPC_Connection_Ptr write_terminator=NULL, read_terminator=NULL;
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
*/
|
||||
static char *get_path_from_context (
|
||||
char *context );
|
||||
static int remove_variable(
|
||||
char *string );
|
||||
static void resolve_variable_reference(
|
||||
char **string );
|
||||
|
||||
/*
|
||||
* This array contains the process id's of the sub-processes
|
||||
* started by the daemon. When a sub-process terminates, its
|
||||
* entry will be set to SPCD_DEAD_PROCESS. This list of pid's
|
||||
* is kept beause when the exit timer expires, if the daemon
|
||||
* has no sub-processes running, it will exit.
|
||||
*/
|
||||
pid_t *SPC_pid_list = NULL;
|
||||
|
||||
/*
|
||||
* This global variable is set by the daemon when the client
|
||||
* connects.
|
||||
*/
|
||||
int SPC_client_version_number = SPC_PROTOCOL_VERSION;
|
||||
|
||||
/*
|
||||
* If this variable is not NULL, it will contain the name of
|
||||
* the mount point environment variable plus its value thus it
|
||||
* ready for 'putenv'.
|
||||
*/
|
||||
char *SPC_mount_point_env_var = NULL;
|
||||
|
||||
/* External definitions */
|
||||
|
||||
extern XeChar spc_logging;
|
||||
extern XeString *environ;
|
||||
|
||||
/*
|
||||
* Routines for handling Sub-Processes
|
||||
*/
|
||||
|
||||
/*
|
||||
**
|
||||
** Initialize synchronous terminators.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Setup_Synchronous_Terminator(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int pipes[2];
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(write_terminator) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if(pipe(pipes)<0) {
|
||||
SPC_Error(SPC_No_Pipe);
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if((write_terminator=SPC_Alloc_Connection())==SPC_ERROR) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
SPC_Add_Connection(write_terminator);
|
||||
|
||||
if((read_terminator=SPC_Alloc_Connection())==SPC_ERROR) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
SPC_Add_Connection(read_terminator);
|
||||
|
||||
write_terminator->sid=pipes[WRITE_SIDE];
|
||||
write_terminator->connected=TRUE;
|
||||
|
||||
read_terminator->sid=pipes[READ_SIDE];
|
||||
read_terminator->connected=TRUE;
|
||||
SPC_XtAddInput(NULL, &read_terminator->termination_id, read_terminator->sid,
|
||||
SPC_Conditional_Packet_Handler, SPC_Terminator);
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Connection_Ptr SPC_Channel_Terminator_Connection(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(IS_REMOTE(channel))
|
||||
return(channel->connection);
|
||||
else
|
||||
return(read_terminator);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void SPC_Close_Unused(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Close any and all unused file descriptors */
|
||||
int fd;
|
||||
|
||||
for (fd = STDERR + 1; fd < max_fds; fd++) spc_close(fd);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_MakeSystemCommand(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
XeString shell;
|
||||
XeString *argv;
|
||||
XeString *tmp_argv;
|
||||
XeChar newargtwo[_POSIX_ARG_MAX];
|
||||
int argtwolen=0, tmplen=0;
|
||||
|
||||
/* Allocate our memory up front */
|
||||
|
||||
argv=Alloc_Argv(4);
|
||||
|
||||
newargtwo[argtwolen]=0;
|
||||
|
||||
/* copy path into newargtwo */
|
||||
|
||||
strncat(newargtwo, channel->path, _POSIX_ARG_MAX-1);
|
||||
strcat(newargtwo, (XeString)" ");
|
||||
argtwolen=strlen(newargtwo);
|
||||
|
||||
/* copy argv into newargtwo */
|
||||
for(tmp_argv=channel->argv; tmp_argv && *tmp_argv; tmp_argv++) {
|
||||
tmplen=strlen(*tmp_argv)+1; /* Room for extra space */
|
||||
if((tmplen+argtwolen)<_POSIX_ARG_MAX-1) {
|
||||
strcat(newargtwo, *tmp_argv);
|
||||
strcat(newargtwo, (XeString)" ");
|
||||
argtwolen += tmplen;
|
||||
} else {
|
||||
XeChar *errbuf;
|
||||
|
||||
errbuf = malloc(sizeof(XeChar) * 100);
|
||||
if (errbuf)
|
||||
{
|
||||
SPC_Free_Envp(argv);
|
||||
sprintf(errbuf,"(%d chars), max. length is %d",tmplen,_POSIX_ARG_MAX);
|
||||
SPC_Error(SPC_Arg_Too_Long, tmp_argv, _POSIX_ARG_MAX);
|
||||
free(errbuf);
|
||||
}
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* get a shell --
|
||||
First use the value of $SB_SHELL (if any),
|
||||
then try $SHELL,
|
||||
then use DEFAULT_SHELL
|
||||
*/
|
||||
|
||||
if(!(shell=getenv((XeString)"SB_SHELL")))
|
||||
if(!(shell=getenv((XeString)"SHELL")))
|
||||
shell = DEFAULT_SHELL;
|
||||
|
||||
/* setup argv properly */
|
||||
|
||||
argv[0]=SPC_copy_string(shell);
|
||||
argv[1]=SPC_copy_string((XeString)"-c");
|
||||
argv[2]=SPC_copy_string(newargtwo);
|
||||
argv[3]=NULL;
|
||||
channel->argv = argv;
|
||||
channel->IOMode |= SPCIO_DEALLOC_ARGV;
|
||||
|
||||
/* Now set this shell as the path */
|
||||
|
||||
channel->path = shell;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines for handling child process termination
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
/* This is the right way according to the Spec 1170 */
|
||||
void SPC_Child_Terminated(int i)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* This catches signals for sub-process termination */
|
||||
int type, cause, status;
|
||||
pid_t wait_pid, pid;
|
||||
SPC_Channel_Ptr channel;
|
||||
protocol_request req, *prot;
|
||||
buffered_data data, *pdata;
|
||||
int length;
|
||||
int indx;
|
||||
int saved_errno = errno;
|
||||
|
||||
prot = (&req);
|
||||
pdata = (&data);
|
||||
|
||||
prot->dataptr=pdata;
|
||||
|
||||
wait_pid = -1;
|
||||
while(pid = waitpid(wait_pid, &status, WNOHANG)) {
|
||||
if((pid == -1 && errno == ECHILD) || pid == 0) {
|
||||
/* no more children. Return */
|
||||
errno = saved_errno;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Okay, we got the process ID of a terminated child. Find the
|
||||
channel associated with this PID. */
|
||||
channel=SPC_Find_PID(pid);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, (XeString)"got SIGCHLD, pid: %d, channel: %p\n", pid, channel);
|
||||
#endif
|
||||
|
||||
if(!channel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
_DtSvcProcessLock();
|
||||
/*
|
||||
* Look for this process in the pid list. If found, mark it
|
||||
* as done.
|
||||
*/
|
||||
if (SPC_pid_list != NULL) {
|
||||
for (indx=0; SPC_pid_list[indx] != NULL; indx++)
|
||||
if (SPC_pid_list[indx] == pid) {
|
||||
SPC_pid_list[indx] = SPCD_DEAD_PROCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/* We have the channel. Mark it as being closed. */
|
||||
|
||||
channel->status = status;
|
||||
|
||||
/* If we this channel is set up for synchronous termination,
|
||||
write the protocol request to record that this guy died.
|
||||
Otherwise, call the termination handler directly. */
|
||||
|
||||
if(IS_SPCIO_SYNC_TERM(channel->IOMode)) {
|
||||
|
||||
/* This code is basically what SPC_Write_Protocol_Request does.
|
||||
It is replicated here because a call to SPC_W_P_R would have
|
||||
to be re-enterant if we called it here, and SPC_W_P_R is not
|
||||
re-enterant at this time. */
|
||||
|
||||
SPC_Reset_Protocol_Ptr(prot, channel, APPLICATION_DIED, 0);
|
||||
pdata->len=WRITE_APPLICATION_DIED(pdata, status);
|
||||
length=WRITE_HEADER(pdata, channel->cid,
|
||||
prot->request_type,
|
||||
pdata->len,
|
||||
0);
|
||||
pdata->data[length]=(XeChar)' ';
|
||||
length=pdata->len+REQUEST_HEADER_LENGTH;
|
||||
if(write(write_terminator->sid, pdata->data, length)==ERROR)
|
||||
SPC_Error(SPC_Internal_Error);
|
||||
pdata->offset=REQUEST_HEADER_LENGTH;
|
||||
print_protocol_request((XeString) (XeString)" <-- INTERNAL APPLICATION_DIED", prot);
|
||||
}
|
||||
else {
|
||||
SPC_Change_State(channel, NULL, -1, 0);
|
||||
if(channel->Terminate_Handler) {
|
||||
XeSPCGetProcessStatus(channel, &type, &cause);
|
||||
(* channel->Terminate_Handler)
|
||||
(channel, channel->pid, type, cause, channel->Terminate_Data);
|
||||
}
|
||||
}
|
||||
/* Loop around & get another PID */
|
||||
}
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Check to see if a given path names an executable file. Thus, we
|
||||
*** need to know if the file exists. If it is a directory, we want
|
||||
*** to fail. Otherwise, we want to us the system rules for checking
|
||||
*** on the file, and thus the 'access' call.
|
||||
***
|
||||
*/
|
||||
|
||||
static Boolean executable_predicate(XeString path, XeString dir, XeString file)
|
||||
{
|
||||
|
||||
struct stat file_status;
|
||||
|
||||
dir=dir;
|
||||
file=file;
|
||||
|
||||
if(stat(path, &file_status) != 0)
|
||||
return(FALSE);
|
||||
|
||||
if(S_ISDIR(file_status.st_mode))
|
||||
return(FALSE);
|
||||
|
||||
return(access(path, X_OK | F_OK) == 0);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int exec_proc_local_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
sigset_t newsigmask, oldsigmask;
|
||||
pid_t pid;
|
||||
int result;
|
||||
XeString *envp;
|
||||
XeString dir = XeString_NULL;
|
||||
int retval;
|
||||
int i, reuse_pid = 0;
|
||||
|
||||
call_parent_method(channel, exec_proc, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* Check to see if the channel pathname points to a valid executable.
|
||||
We do this by using the _path_search function. If the channel
|
||||
has a PATH variable set in its local environment, use it,
|
||||
otherwise use the "global" environment. We can accomplish this
|
||||
by using the spc_getenv call in the _path_search call. If the
|
||||
channel doesn't have a PATH variable, then spc_getenv will
|
||||
return NULL, which indicates use of the global environment.
|
||||
*/
|
||||
|
||||
if(!_path_search(SPC_Getenv("PATH", channel->envp),
|
||||
channel->path,
|
||||
executable_predicate)) {
|
||||
SPC_Error(SPC_Cannot_Exec, channel->path);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* If we were passed a host:dir to cd to, make sure it exists. */
|
||||
/* We want to do this before we fork the child. */
|
||||
|
||||
if((channel->context_dir) && (channel->context_dir[0])) {
|
||||
struct stat stat_info;
|
||||
Boolean ok = FALSE;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (SPC_client_version_number < SPC_PROTOCOL_VERSION_CDE_BASE)
|
||||
dir = get_path_from_context(channel->context_dir);
|
||||
else {
|
||||
/*
|
||||
* context_dir is actually a "netfile" so it needs to
|
||||
* be converted to a "real" path.
|
||||
*/
|
||||
dir = (char *) tt_netfile_file (channel->context_dir);
|
||||
if (tt_ptr_error (dir) != TT_OK)
|
||||
dir = NULL;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
if (dir == NULL)
|
||||
/* can't make connection ... */;
|
||||
else if (stat(dir,&stat_info) != 0)
|
||||
/* directory not there */;
|
||||
|
||||
else if ((stat_info.st_mode & S_IFDIR) == 0)
|
||||
/* path is not a directory ... */;
|
||||
else
|
||||
ok = TRUE;
|
||||
|
||||
if (!ok && IS_SPCIO_FORCE_CONTEXT(channel->IOMode)) {
|
||||
if (dir != NULL && (strcmp (dir, channel->context_dir) != 0))
|
||||
SPC_Error(SPC_cannot_Chdir, dir);
|
||||
SPC_Error(SPC_cannot_Chdir, channel->context_dir);
|
||||
XeFree(dir);
|
||||
dir = XeString_NULL;
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if(mempf0(channel, pre_fork)==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* When using HP NLIO (xj0input) we have a problem. Namely, */
|
||||
/* the xj0 processs uses signal() to deal with SIGCLD which */
|
||||
/* is incompatible with sigaction/sigprogmask/etc. Even */
|
||||
/* though xj0 resets the signal handler, since the signal */
|
||||
/* routines are incompatible, our original handler gets lost. */
|
||||
/* Hence, we need to reset it. We do it here everytime we */
|
||||
/* fork a child just to be on the safe side. */
|
||||
|
||||
SPC_ResetTerminator();
|
||||
|
||||
sigemptyset(&newsigmask);
|
||||
sigemptyset(&oldsigmask);
|
||||
sigaddset(&newsigmask, SIGCHLD);
|
||||
|
||||
if (sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask) == ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
pid = channel->pid = fork();
|
||||
|
||||
/*
|
||||
* Must save this pid so that when the daemon's timer goes off,
|
||||
* if there has been no activity and there are no sub-processes
|
||||
* running, the daemon can exit.
|
||||
*/
|
||||
i = 0;
|
||||
_DtSvcProcessLock();
|
||||
if (SPC_pid_list == NULL)
|
||||
/*
|
||||
* Create the first block plus the NULL terminator.
|
||||
*/
|
||||
SPC_pid_list = (pid_t *) malloc (2 * sizeof (pid_t));
|
||||
else {
|
||||
/*
|
||||
* If a dead pid entry exists, reuse it; otherwise, must create
|
||||
* room for the new pid.
|
||||
*/
|
||||
for (i = 0; SPC_pid_list[i] != NULL; i++)
|
||||
if (SPC_pid_list[i] == SPCD_DEAD_PROCESS) {
|
||||
SPC_pid_list[i] = pid;
|
||||
reuse_pid = 1;
|
||||
break;
|
||||
}
|
||||
if (!reuse_pid)
|
||||
SPC_pid_list = (pid_t *) realloc (SPC_pid_list,
|
||||
(i+2) * sizeof (pid_t));
|
||||
}
|
||||
if (!reuse_pid) {
|
||||
SPC_pid_list[i] = pid;
|
||||
SPC_pid_list[i+1] = NULL;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
if (pid) {
|
||||
XeFree(dir);
|
||||
|
||||
/* Did we really fork? */
|
||||
if (pid == ERROR) {
|
||||
SPC_Error(SPC_Cannot_Fork);
|
||||
retval = SPC_ERROR;
|
||||
} else {
|
||||
/* Do any set up for the parent process here */
|
||||
mempf1(channel, post_fork, pid);
|
||||
retval = TRUE;
|
||||
}
|
||||
|
||||
/* Reinstate the old signal mask (unblock SIGCLD). */
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
|
||||
return(retval);
|
||||
}
|
||||
else {
|
||||
/* Child process: connect wires, make environment and exec sub-process */
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
|
||||
|
||||
/* Make sure the child is the process group leader. In the case of
|
||||
ptys, we also want to break the current terminal affiliation.
|
||||
We want to be the process group leader so XeSPCKillProcess (which
|
||||
does a kill(-pid, 9)) will kill all processes associated with us.
|
||||
|
||||
For PTY's, we need to break the terminal affiliation so the next
|
||||
open (which will be a pty) will cause us to become affiliated with
|
||||
the pty. We do this so when the parent process closes the master
|
||||
side of the pty, the slave side processes get SIGHUP. If they
|
||||
ignore SIGHUP, they will never die. So it goes...
|
||||
*/
|
||||
|
||||
if(IS_SPCIO_PTY(channel->IOMode))
|
||||
setsid();
|
||||
else {
|
||||
pid_t tmppid = getpid();
|
||||
if(setpgid(tmppid, tmppid) == -1)
|
||||
fprintf(stderr, (XeString)"setpgid failed, errno: %d\n", errno);
|
||||
}
|
||||
|
||||
/* Connect wires to sub-process standard files */
|
||||
result=mempf1(channel, post_fork, pid);
|
||||
|
||||
if(result!=SPC_ERROR) {
|
||||
int indx = -1;
|
||||
int i;
|
||||
char **ppch;
|
||||
|
||||
/*
|
||||
* Before adding in the list of environment variables
|
||||
* from the environment variable files, must search
|
||||
* the list for LANG definitions. If found, the
|
||||
* last definition must be putenv'ed to assure the
|
||||
* multi-byte parsing code is using the correct locale.
|
||||
*/
|
||||
for (i = 0, ppch = channel->envp; *ppch; *ppch++, i++)
|
||||
if (!strncmp (*ppch, "LANG=", 5))
|
||||
indx = i;
|
||||
|
||||
if (indx != -1)
|
||||
resolve_variable_reference (&channel->envp[indx]);
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (!setlocale (LC_CTYPE, ""))
|
||||
/*
|
||||
* setlocale failed - log a message but execute
|
||||
* the command anyway.
|
||||
*/
|
||||
if (SPC_Print_Protocol != NULL)
|
||||
(void) fprintf(SPC_Print_Protocol,
|
||||
"+++> Failed to 'setlocale'; LANG = %s\n",
|
||||
getenv("LANG"));
|
||||
/* Mix in the stashed environment */
|
||||
|
||||
for(envp=channel->envp; *envp; envp++)
|
||||
resolve_variable_reference(&*envp);
|
||||
|
||||
if (SPC_mount_point_env_var != NULL)
|
||||
/*
|
||||
* The mount point environment variable was
|
||||
* inherited by the daemon or was given to the
|
||||
* daemon via the command line. In either case
|
||||
* this subprocess must inherit the daemon's
|
||||
* value.
|
||||
*/
|
||||
(void) putenv (SPC_mount_point_env_var);
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/* Connect to the context directory */
|
||||
/* We have already validated this guy exists */
|
||||
|
||||
if(dir)
|
||||
Xechdir(dir);
|
||||
}
|
||||
|
||||
XeFree(dir);
|
||||
|
||||
if(result!=SPC_ERROR) {
|
||||
/* Execute */
|
||||
/* Compiler barfs without cast ? */
|
||||
#if defined(__hpux_8_0) || defined(__aix)
|
||||
result=execvp(channel->path, channel->argv);
|
||||
#else
|
||||
result=execvp(channel->path, channel->argv);
|
||||
#endif
|
||||
/* If we return from exec, it failed */
|
||||
SPC_Error(SPC_Cannot_Exec, channel->path);
|
||||
}
|
||||
|
||||
/* We want to get rid of this child image (carefully) */
|
||||
_exit(42);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* get_path_from_context - given a 'context' string in the following form:
|
||||
*
|
||||
* [host:]path
|
||||
*
|
||||
* return the path component.
|
||||
*
|
||||
* NOTE - the caller must free the returned string.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* char *context - the context string to parse
|
||||
*
|
||||
* Return Value:
|
||||
*
|
||||
* A NULL if a pathname cannot be constructed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static char *get_path_from_context (
|
||||
char *context)
|
||||
{
|
||||
char *host = NULL;
|
||||
char *file = NULL;
|
||||
char *netfile = NULL;
|
||||
char *path = NULL;
|
||||
char tmp[MAXPATHLEN];
|
||||
char *pch;
|
||||
|
||||
/*
|
||||
* Break context into its host and file parts.
|
||||
*/
|
||||
if (context == NULL)
|
||||
return (NULL);
|
||||
|
||||
(void) strcpy (tmp, context);
|
||||
file = tmp;
|
||||
|
||||
if ((pch = (char *) strchr (tmp, ':')) != NULL) {
|
||||
host = tmp;
|
||||
file = pch + 1;
|
||||
*pch = '\000';
|
||||
}
|
||||
|
||||
if (!host)
|
||||
return (strdup (file));
|
||||
|
||||
netfile = (char *) tt_host_file_netfile (host, file);
|
||||
if (tt_ptr_error (netfile) != TT_OK) {
|
||||
SPC_Error (SPC_Cannot_Create_Netfilename, context, host);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
path = (char *) tt_netfile_file (netfile);
|
||||
tt_free (netfile);
|
||||
if (tt_ptr_error (path) != TT_OK) {
|
||||
SPC_Error (SPC_Cannot_Create_Netfilename, context, host);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (path);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* remove_variable ()
|
||||
*
|
||||
* This takes a string of the format:
|
||||
*
|
||||
* var_name=some_value | <remove_variable_keyword> var_name
|
||||
*
|
||||
* and if the second form is found, 'var_name' is removed from
|
||||
* the environment.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* char *string see the format above.
|
||||
*
|
||||
* Return Value:
|
||||
*
|
||||
* int 0 if 'string' contains a 'remove variable' command
|
||||
* 1 if string does not contain a 'remove variable' command
|
||||
*
|
||||
* Modified:
|
||||
*
|
||||
* char **environ 'var_name' is removed from the environment
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
static int
|
||||
remove_variable(
|
||||
char *string)
|
||||
{
|
||||
char *pch;
|
||||
char **ppch;
|
||||
char **ppch2;
|
||||
char *tmp_var;
|
||||
int tmp_len;
|
||||
|
||||
/*
|
||||
* If string contains some white space before the variable
|
||||
* or keyword, skip the white space.
|
||||
*/
|
||||
pch = string;
|
||||
while (
|
||||
#ifdef NLS16
|
||||
((mblen (pch, MB_CUR_MAX) == 1)) &&
|
||||
#endif /* NLS16 */
|
||||
isspace ((u_char)*pch))
|
||||
pch++;
|
||||
|
||||
if (*pch == '\000')
|
||||
return (1);
|
||||
if (strncmp (pch, SPC_REMOVE_VAR, strlen (SPC_REMOVE_VAR)))
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Skip the white space after the keyword and move to the
|
||||
* beginning of the variable.
|
||||
*/
|
||||
pch = pch + strlen (SPC_REMOVE_VAR);
|
||||
while (
|
||||
#ifdef NLS16
|
||||
((mblen (pch, MB_CUR_MAX) == 1)) &&
|
||||
#endif /* NLS16 */
|
||||
isspace ((u_char)*pch))
|
||||
pch++;
|
||||
|
||||
if (*pch == '\000')
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* pch should now point to the variable to be removed.
|
||||
*
|
||||
* tmp_var will be equal to the variable with a trailing '='.
|
||||
* This is added so the future comparison will not match
|
||||
* against variables that start with 'tmp_var' but then
|
||||
* have something else.
|
||||
*/
|
||||
tmp_var = malloc ((strlen (pch) + 2) * sizeof (char));
|
||||
(void) sprintf (tmp_var, "%s=", pch);
|
||||
tmp_len = strlen (tmp_var);
|
||||
|
||||
/*
|
||||
* Scan 'environ' for 'tmp_var'
|
||||
*/
|
||||
for (ppch = environ; *ppch; *ppch++) {
|
||||
if (!strncmp (tmp_var, *ppch, tmp_len)) {
|
||||
/*
|
||||
* Found the variable so remove it by moving all
|
||||
* variables after *ppch up.
|
||||
*/
|
||||
for (ppch2 = ppch; *ppch2; *ppch2++) {
|
||||
*ppch++;
|
||||
*ppch2 = *ppch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free ((char *) tmp_var);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* resolve_variable_reference ()
|
||||
*
|
||||
* This function takes a string of the format:
|
||||
*
|
||||
* var_name=some_value
|
||||
*
|
||||
* and if 'some_value' contains a reference to an environment
|
||||
* variable, the reference is replaced with the value of the
|
||||
* variable.
|
||||
*
|
||||
* For example, if 'string' is
|
||||
*
|
||||
* FOO=$VFA_TOP/foo
|
||||
*
|
||||
* and $VFA_TOP is '/some_tree', then 'string' will be changed to:
|
||||
*
|
||||
* FOO=/some_tree/foo
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* o 'putenv' will be invoked with argument 'string', even if 'string'
|
||||
* was not modified.
|
||||
*
|
||||
* o A valid variable name consists of alphanumerics and underscore
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* char **string MODIFIED - the environment variable
|
||||
* definition to be parsed
|
||||
*
|
||||
* Return Value:
|
||||
*
|
||||
* void
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
static void
|
||||
resolve_variable_reference(
|
||||
char **string ) /* MODIFIED */
|
||||
{
|
||||
char *string_end;
|
||||
char *var_start;
|
||||
char *pch;
|
||||
char *value;
|
||||
int n; /* number of bytes in a string */
|
||||
int len;
|
||||
int found_brace;
|
||||
char variable[256];
|
||||
char *buf = NULL;
|
||||
char *pbeg = *string;
|
||||
char *string_start = *string;
|
||||
|
||||
if (!remove_variable (*string))
|
||||
return;
|
||||
|
||||
pch = pbeg;
|
||||
|
||||
buf = malloc(2048);
|
||||
|
||||
while (*pbeg) {
|
||||
|
||||
/*
|
||||
* Look for '$' - the beginning of a variable reference.
|
||||
* If a '$' character is not found, exit the loop
|
||||
*/
|
||||
#ifdef NLS16
|
||||
while (*pch) {
|
||||
|
||||
if (((len = mblen (pch, MB_CUR_MAX)) == 1) && (*pch == '$'))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Move past this char
|
||||
*/
|
||||
if (len > 0)
|
||||
pch += len;
|
||||
else
|
||||
/*
|
||||
* pch is null or it points to an invalid mulit-byte
|
||||
* character.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
#else
|
||||
pch = strchr (pch, '$');
|
||||
#endif /* NLS16 */
|
||||
|
||||
if (pch == NULL || *pch == '\000')
|
||||
/*
|
||||
* The string doesn't contain any (more) variables
|
||||
*/
|
||||
break;
|
||||
|
||||
string_start = *string;
|
||||
|
||||
/*
|
||||
* Found a '$' - the beginning of an environment variable so
|
||||
* skip it and check the next char for '{' and if it is found
|
||||
* skip it and move to the real beginning of an env variable.
|
||||
*/
|
||||
string_end = pch;
|
||||
found_brace = 0;
|
||||
pch++;
|
||||
|
||||
#ifdef NLS16
|
||||
if ((mblen (pch, MB_CUR_MAX) == 1) && (*pch == '{')) {
|
||||
#else
|
||||
if (*pch == '{') {
|
||||
#endif /* NLS16 */
|
||||
pch++; /* input = ${ */
|
||||
found_brace = 1;
|
||||
}
|
||||
if (*pch == '\0') /* input = $\0 or ${\0 */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Find the end of the variable name - it is assumed to
|
||||
* be the first character that is not an alpha-numeric
|
||||
* or '_'.
|
||||
*/
|
||||
var_start = pch;
|
||||
n = 0;
|
||||
|
||||
while (*pch) {
|
||||
#ifdef NLS16
|
||||
if ((mblen (pch, MB_CUR_MAX) > 1) ||
|
||||
((mblen (pch, MB_CUR_MAX) == 1) &&
|
||||
((*pch == '_') || (isalnum (*pch))))) {
|
||||
#else
|
||||
if (isalnum (*pch) || *pch == '_') {
|
||||
#endif /* NLS16 */
|
||||
|
||||
#ifdef NLS16
|
||||
len = mblen (pch, MB_CUR_MAX);
|
||||
#else
|
||||
len = 1;
|
||||
#endif /* NLS16 */
|
||||
n += len;
|
||||
pch += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef NLS16
|
||||
if (found_brace && (mblen (pch, MB_CUR_MAX) == 1) && (*pch == '}'))
|
||||
#else
|
||||
if (found_brace && *pch == '}')
|
||||
#endif /* NLS16 */
|
||||
/*
|
||||
* Move past the closing brace
|
||||
*/
|
||||
pch++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
/*
|
||||
* Nothing 'recognizable' follows the $ or ${
|
||||
*/
|
||||
pbeg = pch;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stuff the environment variable name in 'variable' and then
|
||||
* get its value. If the variable doesn't exist, leave its
|
||||
* name in the string.
|
||||
*/
|
||||
(void) strncpy (variable, var_start, n);
|
||||
variable[n] = '\0';
|
||||
|
||||
if ((value = getenv (variable)) == NULL) {
|
||||
/*
|
||||
* Leave what looks like an environment variable in place.
|
||||
*/
|
||||
pbeg = pch;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen (value) == 0) {
|
||||
pbeg = pch;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to replace the variable definition with the string
|
||||
* pointed to by 'value'. So create a string that contains the
|
||||
* characters before the environment variable, then the contents
|
||||
* of 'value' and finally, the characters after the environment
|
||||
* variable.
|
||||
*/
|
||||
if (string_end == string_start)
|
||||
/*
|
||||
* There is nothing to prepend before 'value'.
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
else {
|
||||
(void) strncpy (buf, string_start, (string_end - string_start));
|
||||
buf[(string_end - string_start)] = '\0';
|
||||
}
|
||||
(void) strcat (buf, value);
|
||||
len = strlen (buf);
|
||||
if (*pch != '\0')
|
||||
(void) strcat (buf, pch);
|
||||
|
||||
/*
|
||||
* Now put 'buf' into 'string'.
|
||||
*/
|
||||
*string = realloc (*string, strlen (buf) + 1);
|
||||
(void) strcpy (*string, buf);
|
||||
pch = *string + len;
|
||||
pbeg = pch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Even if no substitutions were made, the variable must
|
||||
* be put in the environment.
|
||||
*/
|
||||
(void) putenv (*string);
|
||||
if (buf) free(buf);
|
||||
}
|
||||
500
cde/lib/DtSvc/DtEncap/spc-net.c
Normal file
500
cde/lib/DtSvc/DtEncap/spc-net.c
Normal file
@@ -0,0 +1,500 @@
|
||||
/* $XConsortium: spc-net.c /main/9 1996/11/21 19:53:44 drk $
|
||||
* File: spc-net.c
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#define __need_timeval
|
||||
#define __need_fd_set
|
||||
#define __need_all_errors
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define X_INCLUDE_NETDB_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <bms/MemoryMgr.h>
|
||||
#include <SPC/spc-proto.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
extern int SPC_Initialized;
|
||||
|
||||
/*
|
||||
****
|
||||
**** Client-side code
|
||||
****
|
||||
*/
|
||||
|
||||
/* Variables representing the local machine (initialized only once) */
|
||||
|
||||
static struct hostent *official_hp = NULL;
|
||||
XeString official_hostname = NULL;
|
||||
|
||||
/*
|
||||
* my_gethost will return a copy of the data returned by gethostbyname
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static struct hostent *my_gethost(XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
struct hostent *host_def, *copy;
|
||||
int alias_count, i, addr_count, addrlen;
|
||||
_Xgethostbynameparams host_buf;
|
||||
|
||||
host_def = _XGethostbyname(hostname, host_buf);
|
||||
if (host_def == NULL)
|
||||
return(FALSE);
|
||||
|
||||
copy=(struct hostent *)XeMalloc(sizeof(struct hostent));
|
||||
|
||||
/* Copy non-pointer info */
|
||||
memcpy((char *)copy, (char *)host_def, sizeof(struct hostent));
|
||||
|
||||
alias_count=0;
|
||||
|
||||
while(host_def->h_aliases[alias_count++]);
|
||||
|
||||
copy->h_aliases=(char **)XeMalloc(alias_count*(sizeof(XeString)));
|
||||
|
||||
addr_count=0;
|
||||
while(host_def->h_addr_list[addr_count++]);
|
||||
|
||||
copy->h_addr_list=(char **)XeMalloc(addr_count*(sizeof(XeString)));
|
||||
|
||||
/* Copy Hostname */
|
||||
|
||||
copy->h_name=SPC_copy_string(host_def->h_name);
|
||||
|
||||
/* Copy the host address. We do not use SPC_copy_string here,
|
||||
because the address is not a string, and may have embedded
|
||||
NULLs in it. */
|
||||
|
||||
addrlen = host_def->h_length;
|
||||
addr_count -= 1;
|
||||
copy->h_addr_list[addr_count]=XeChar_NULL;
|
||||
for (i=0; i < addr_count; i++) {
|
||||
copy->h_addr_list[i]=(char *)XeMalloc(addrlen);
|
||||
memcpy(copy->h_addr_list[i], host_def->h_addr_list[i], addrlen);
|
||||
}
|
||||
|
||||
while(alias_count--) {
|
||||
copy->h_aliases[alias_count]=SPC_copy_string(host_def->h_aliases[alias_count]);
|
||||
}
|
||||
|
||||
return(copy);
|
||||
}
|
||||
|
||||
/*
|
||||
* SPC_Lookup_Host will try its darndest to return a hostent structure
|
||||
* for the passed hostname.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static struct hostent *SPC_Lookup_Host(XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
struct hostent *official_def;
|
||||
|
||||
official_def = my_gethost(hostname);
|
||||
if(!official_def) {
|
||||
SPC_Error(SPC_Unknown_Host, hostname);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(official_def);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* SPC_Init_Local_Host_Info will initialize the local host info. It
|
||||
* is intended to be called only once.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
Boolean SPC_Init_Local_Host_Info(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
official_hostname=(XeString) XeMalloc(MAXHOSTNAMELEN+1);
|
||||
|
||||
Xegethostname(official_hostname, MAXHOSTNAMELEN);
|
||||
official_hostname[MAXHOSTNAMELEN]=0;
|
||||
|
||||
if(!official_hp)
|
||||
official_hp = SPC_Lookup_Host(official_hostname);
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(official_hp != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* SPC_Local_Hostname takes a string indicating a hostname, and returns
|
||||
* TRUE if it represents a local host, and FALSE if it is remote.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Local_Hostname(XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Return TRUE if the specified hostname is local, otherwise it's remote */
|
||||
|
||||
/* If no hostname specified, then local by definition */
|
||||
|
||||
if (!hostname || !*hostname) return TRUE;
|
||||
|
||||
#ifdef DEBUG
|
||||
return(FALSE);
|
||||
#endif
|
||||
|
||||
return(XeIsLocalHostP(hostname));
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* SPC_Open_Connection will a connection pointer to be used for any
|
||||
* subsequent communication to the remote host. It will either return
|
||||
* an already opened connection, or create and initialize a new one.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Connection_Ptr SPC_Open_Connection(XeString hostname)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Connection_Ptr connection;
|
||||
int seqno;
|
||||
XeString canonical_hostname;
|
||||
int tmp_errorno;
|
||||
|
||||
/* I was told that XeFindShortHost was the correct routine to use here,
|
||||
but that may change in the future. */
|
||||
|
||||
canonical_hostname=XeFindShortHost(hostname);
|
||||
|
||||
/* check for a currently open connection */
|
||||
connection=SPC_Lookup_Connection(canonical_hostname);
|
||||
if(connection) {
|
||||
if(connection->connected) {
|
||||
XeFree(canonical_hostname);
|
||||
return(connection);
|
||||
}
|
||||
else {
|
||||
SPC_Close_Connection(connection);
|
||||
connection=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* None currently open. Grab a new one & initialize it. */
|
||||
|
||||
if((connection = SPC_Make_Connection(canonical_hostname))==SPC_ERROR) {
|
||||
SPC_Close_Connection(connection);
|
||||
XeFree(canonical_hostname);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
connection->local=official_hp;
|
||||
if((connection->remote = SPC_Lookup_Host(canonical_hostname)) == SPC_ERROR) {
|
||||
SPC_Close_Connection(connection);
|
||||
XeFree(canonical_hostname);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(SPC_Contact_Server(connection)==SPC_ERROR) {
|
||||
SPC_Close_Connection(connection);
|
||||
XeFree(canonical_hostname);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
connection->connected=TRUE;
|
||||
|
||||
if(SPC_Validate_User(canonical_hostname, connection)==SPC_ERROR) {
|
||||
SPC_Close_Connection(connection);
|
||||
XeFree(canonical_hostname);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
seqno=SPC_Write_Protocol_Request(connection, NULL, ENVIRON_RESET);
|
||||
_DtSvcProcessLock();
|
||||
tmp_errorno = XeSPCErrorNumber;
|
||||
if(SPC_Waitfor_Reply(connection, NULL, seqno) == SPC_ERROR) {
|
||||
SPC_Close_Connection(connection);
|
||||
/*
|
||||
* XeSPCErrorNumber could have been changed but want to
|
||||
* return the value from Write_Protocol_Request to the
|
||||
* client.
|
||||
*/
|
||||
if (tmp_errorno != 0)
|
||||
XeSPCErrorNumber = tmp_errorno;
|
||||
XeFree(canonical_hostname);
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/* We no long ever send a RESET_TERMIO request as this was hpux */
|
||||
/* specific and VERY non-portable. */
|
||||
|
||||
if (connection->protocol_version >= 2) {
|
||||
seqno=SPC_Write_Protocol_Request(connection, NULL, RESET_TERMIOS);
|
||||
if(SPC_Waitfor_Reply(connection, NULL, seqno) == SPC_ERROR) {
|
||||
SPC_Close_Connection(connection);
|
||||
XeFree(canonical_hostname);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
XeFree(canonical_hostname);
|
||||
return(connection);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Open_Socket(SPC_Connection_Ptr conn,
|
||||
int type)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
struct servent *service;
|
||||
|
||||
conn->sid=socket(type, SOCK_STREAM, NULL);
|
||||
if(conn->sid == ERROR) {
|
||||
SPC_Error(SPC_Bad_Socket);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
service=getservbyname(SPC_SERVICE, SPC_PROTOCOL);
|
||||
if (!service) {
|
||||
SPC_Error(SPC_Bad_Service, SPC_SERVICE, SPC_PROTOCOL);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(service->s_port);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* SPC_Contact_Server will attempt to contact the server specified by
|
||||
* the passed connection data structure. IT ASSUMES THAT ALL FIELDS
|
||||
* EXCEPT THE SOCKET ID ARE FILLED IN!!!
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Contact_Server(SPC_Connection_Ptr connection)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
struct sockaddr_in saddr;
|
||||
short addrtype;
|
||||
struct hostent *remote;
|
||||
|
||||
|
||||
/* Check that the connection is initialized correctly */
|
||||
if(!connection)
|
||||
return(SPC_ERROR);
|
||||
if(!(remote=connection->remote))
|
||||
return(SPC_ERROR);
|
||||
if(connection->connected)
|
||||
return(TRUE);
|
||||
|
||||
addrtype=saddr.sin_family=remote->h_addrtype;
|
||||
if(!(saddr.sin_port=SPC_Open_Socket(connection, addrtype)))
|
||||
return(SPC_ERROR);
|
||||
memcpy(&saddr.sin_addr, remote->h_addr, remote->h_length);
|
||||
|
||||
if(connect(connection->sid, (struct sockaddr *)&saddr, sizeof(saddr)) == ERROR) {
|
||||
SPC_Error(SPC_Bad_Connect,
|
||||
XeFindShortHost(remote->h_name));
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
****
|
||||
**** Server (daemon) side code
|
||||
****
|
||||
*/
|
||||
|
||||
#define BACKLOG 50
|
||||
#define MAX_SERVER_BIND_ATTEMPTS 30
|
||||
#define SERVER_PAUSE_INTERVAL 10
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Connection_Ptr SPC_Init_Child(SPC_Connection_Ptr conn,
|
||||
int from)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* We are the child. Close the connection file descriptor
|
||||
(which is the socket, not our input). */
|
||||
close(conn->sid);
|
||||
|
||||
/* Make the from file descriptor correspond to STDIN/STDOUT */
|
||||
dup2(from, STDIN);
|
||||
close(from);
|
||||
dup2(STDIN, STDOUT);
|
||||
|
||||
/* make conn point to STDIN */
|
||||
|
||||
conn->sid=STDIN;
|
||||
|
||||
return(conn);
|
||||
}
|
||||
|
||||
SPC_Connection_Ptr SPC_Standalone_Daemon(SPC_Connection_Ptr conn)
|
||||
{
|
||||
struct sockaddr_in saddr, client_saddr;
|
||||
#ifdef USL
|
||||
/* Only UnixWare 2.02 uses the Spec1170 parameter profile for accept(). */
|
||||
size_t len=sizeof(client_saddr);
|
||||
#else
|
||||
int len=sizeof(client_saddr);
|
||||
#endif
|
||||
int server_bind_attempts = MAX_SERVER_BIND_ATTEMPTS;
|
||||
int server_bind_pause = SERVER_PAUSE_INTERVAL;
|
||||
int pid, from;
|
||||
#if defined(__aix)
|
||||
int on=1; /* required by setsockopt */
|
||||
#endif
|
||||
|
||||
saddr.sin_family=AF_INET;
|
||||
if(!(saddr.sin_port=SPC_Open_Socket(conn, saddr.sin_family)))
|
||||
return(SPC_ERROR);
|
||||
saddr.sin_addr.s_addr=INADDR_ANY; /* Any host address */
|
||||
|
||||
/* Reuse the socket address if it is still in a timeout state */
|
||||
|
||||
#if defined(__aix)
|
||||
if (setsockopt(conn->sid, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))==ERROR) {
|
||||
#else
|
||||
if (setsockopt(conn->sid, SOL_SOCKET, SO_REUSEADDR, NULL, NULL)==ERROR) {
|
||||
#endif
|
||||
SPC_Error(SPC_Bad_Reuse);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
while (bind(conn->sid, (struct sockaddr *)&saddr, sizeof(saddr)) == ERROR) {
|
||||
if (errno == EADDRINUSE) {
|
||||
SPC_Error(SPC_Bind_Timeout);
|
||||
/* Try to get the connection in a little while */
|
||||
if (server_bind_attempts > 0) {
|
||||
server_bind_attempts--;
|
||||
sleep(server_bind_pause);
|
||||
}
|
||||
else {
|
||||
/* We don't want to wait forever */
|
||||
SPC_Error(SPC_Timeout);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
} else {
|
||||
SPC_Error(SPC_Bad_Bind);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up a queue for incoming connection requests */
|
||||
|
||||
listen(conn->sid, BACKLOG);
|
||||
|
||||
/* We are running standalone, so we need to loop forever waiting for
|
||||
requests. When we get one, we will fork a child to take care of
|
||||
the processing for us, and then the parent will listen some more */
|
||||
|
||||
for(;;) {
|
||||
struct hostent *addr_ret;
|
||||
_Xgethostbynameparams addr_buf;
|
||||
|
||||
/* Attempt to accept a connection with a client */
|
||||
|
||||
from = accept(conn->sid, (struct sockaddr *)&client_saddr, &len);
|
||||
if (from == ERROR) {
|
||||
SPC_Error(SPC_Bad_Accept);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
addr_ret = _XGethostbyaddr((char *)&client_saddr.sin_addr,
|
||||
sizeof(client_saddr.sin_addr),
|
||||
client_saddr.sin_family,
|
||||
addr_buf);
|
||||
|
||||
conn->remote = addr_ret;
|
||||
strncpy(conn->hostname, conn->remote->h_name, MAXHOSTNAMELEN);
|
||||
|
||||
#ifdef DEBUG
|
||||
pid = NULL;
|
||||
#else
|
||||
/* Fork a process to handle I/O from/to client */
|
||||
pid = fork();
|
||||
#endif
|
||||
|
||||
if (pid == ERROR) {
|
||||
SPC_Error(SPC_Cannot_Fork);
|
||||
/* We don't return here, but simply go around for a new try */
|
||||
}
|
||||
|
||||
if (!pid)
|
||||
/* We are the child. Do whatever processing we need to do
|
||||
on the connection & return */
|
||||
return(SPC_Init_Child(conn, from));
|
||||
/* Otherwise, we are still the parent. Loop around for another
|
||||
connection request */
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Inetd_Daemon(SPC_Connection_Ptr conn)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
conn->sid=0;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Connection_Ptr SPC_Start_Daemon(int standalone)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Connection_Ptr connection;
|
||||
|
||||
/* Do whatever it takes to initialize SPC */
|
||||
_DtSvcProcessLock();
|
||||
if (!SPC_Initialized)
|
||||
if(SPC_Initialize()==SPC_ERROR) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/* Get ourselves a connection structure. We don't know the name
|
||||
of the remote client yet, so use the null string as hostname */
|
||||
|
||||
if((connection=SPC_Make_Connection(NULL))==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
connection->local=official_hp;
|
||||
if(standalone) {
|
||||
if((SPC_Standalone_Daemon(connection))==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
} else {
|
||||
if((SPC_Inetd_Daemon(connection))==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
connection->connected=TRUE;
|
||||
return(connection);
|
||||
}
|
||||
666
cde/lib/DtSvc/DtEncap/spc-obj.c
Normal file
666
cde/lib/DtSvc/DtEncap/spc-obj.c
Normal file
@@ -0,0 +1,666 @@
|
||||
/*
|
||||
* File: spc-obj.c $TOG: spc-obj.c /main/6 1997/12/29 10:43:29 bill $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <signal.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <bms/MemoryMgr.h>
|
||||
|
||||
#include <SPC/spc-proto.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/* global declarations */
|
||||
|
||||
/* SPC_Initialized is in bmsglob.c */
|
||||
|
||||
extern int SPC_Initialized;
|
||||
|
||||
/* external declarations */
|
||||
|
||||
extern SPC_Channel_Ptr spc_activation_list;
|
||||
extern XeString spc_user_environment_file;
|
||||
|
||||
/*
|
||||
* Global variable to specifying whether the process using this
|
||||
* library is a SPC client or a SPC daemon. If the process is a
|
||||
* client, the SIGCLD signal handler will not be installed.
|
||||
* However, if the process is the daemon, the signal handler will
|
||||
* be installed.
|
||||
*
|
||||
* This will be set to 'SPC_I_AM_A_DAEMON' by the spcd process.
|
||||
*/
|
||||
int SPC_who_am_i = SPC_I_AM_A_CLIENT;
|
||||
|
||||
/* Initialization functions for class objects */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
object *alloc_channel_object(object_clasp c)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
object *p=(object *) XeMalloc((unsigned) c->object_size);
|
||||
memset(p, NULL, (int) c->object_size);
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void channel_class_init(object_clasp t)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
channel_clasp c = (channel_clasp) t;
|
||||
|
||||
c->new_obj = alloc_channel_object;
|
||||
|
||||
c->open = open_channel_object;
|
||||
c->close = close_channel_object;
|
||||
c->read = read_channel_object;
|
||||
c->write = write_channel_object;
|
||||
c->reset = reset_channel_object;
|
||||
c->pre_fork = pre_fork_channel_object;
|
||||
c->post_fork = post_fork_channel_object;
|
||||
c->exec_proc = exec_proc_channel_object;
|
||||
c->signal = signal_channel_object;
|
||||
c->wait_for_termination = channel_object_wait_for_termination;
|
||||
c->attach = attach_channel_object;
|
||||
c->input = NULL;
|
||||
c->add_input = add_input_channel_object;
|
||||
c->remove_logfile = remove_logfile_channel_object;
|
||||
}
|
||||
|
||||
static struct channel_class channel_class_struct = {
|
||||
(root_clasp) &root_class, /* base class pointer */
|
||||
"channel", /* class name */
|
||||
channel_class_init, /* class initialize function */
|
||||
sizeof(SPC_Channel), /* size */
|
||||
0
|
||||
};
|
||||
|
||||
channel_clasp channel_class = &channel_class_struct;
|
||||
|
||||
static Wire dummy_wire={
|
||||
0, /* Flags */
|
||||
-1, -1, /* File Descriptors */
|
||||
(XeString) "/dev/null", /* Master PTY */
|
||||
(XeString) "/dev/null", /* Slave PTY */
|
||||
0, 0, /* Toolkit IDs */
|
||||
NULL /* pointer to next wire */
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_ResetTerminator(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
struct sigaction svect;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (SPC_who_am_i == SPC_I_AM_A_DAEMON) {
|
||||
svect.sa_handler = SPC_Child_Terminated;
|
||||
sigemptyset(&svect.sa_mask);
|
||||
svect.sa_flags = 0;
|
||||
|
||||
if(sigaction(SIGCHLD, &svect, (struct sigaction *)NULL)==ERROR) {
|
||||
SPC_Error(SPC_No_Signal_Handler);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Initialize(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
XeString home;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(SPC_Initialized) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
spc_init_fds();
|
||||
|
||||
if (!SPC_ResetTerminator()) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(!SPC_Init_Local_Host_Info()) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(SPC_Setup_Synchronous_Terminator()==SPC_ERROR) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(home=getenv("HOME")) {
|
||||
spc_user_environment_file=(XeString) XeMalloc(strlen(home)+
|
||||
strlen(SPCD_ENV_HOME_DIRECTORY)+strlen(SPCD_ENV_FILE)+3);
|
||||
sprintf(spc_user_environment_file, "%s/%s/%s",
|
||||
home, SPCD_ENV_HOME_DIRECTORY, SPCD_ENV_FILE);
|
||||
}
|
||||
|
||||
SPC_Initialized=TRUE;
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** SPC_Initialize_Channel will create & return a channel object,
|
||||
** based on the values of hostname and iomode.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr SPC_Initialize_Channel(XeString hostname,
|
||||
int iomode)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Channel_Ptr channel;
|
||||
|
||||
/* Check for local or remote machine. If remote, create a
|
||||
remote channel object */
|
||||
if (!SPC_Local_Hostname(hostname)) {
|
||||
channel=(SPC_Channel_Ptr)object_create((object_clasp)remote_channel_class);
|
||||
|
||||
} else {
|
||||
|
||||
/* We are local. Create the appropriate object. */
|
||||
|
||||
if(IS_SPCIO_NOIOMODE(iomode))
|
||||
channel=(SPC_Channel_Ptr)object_create((object_clasp)noio_channel_class);
|
||||
|
||||
if(IS_SPCIO_PIPE(iomode))
|
||||
channel=(SPC_Channel_Ptr)object_create((object_clasp)pipe_channel_class);
|
||||
|
||||
if(IS_SPCIO_PTY(iomode))
|
||||
channel=(SPC_Channel_Ptr)object_create((object_clasp)pty_channel_class);
|
||||
|
||||
}
|
||||
|
||||
return(channel);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** SPC_Channel_Terminated will do any work necessary on a channel when
|
||||
** we detect that a subprocess has terminated.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void SPC_Channel_Terminated(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int type, cause;
|
||||
|
||||
SPC_Change_State(channel, NULL, -1, 0);
|
||||
|
||||
/* Set the close timeout. If we are on a PTY, we will return
|
||||
after two seconds if we are waiting for EOF */
|
||||
|
||||
channel->close_timeout=2;
|
||||
|
||||
if(IS_DATA(channel) && (channel->Input_Handler)) {
|
||||
while(IS_SPCIO_DATA(channel->wires[STDOUT]->flags))
|
||||
SPC_Input_Handler(channel, STDOUT);
|
||||
while(IS_SPCIO_DATA(channel->wires[STDERR]->flags))
|
||||
SPC_Input_Handler(channel, STDERR);
|
||||
}
|
||||
|
||||
if(channel->Terminate_Handler) {
|
||||
XeSPCGetProcessStatus(channel, &type, &cause);
|
||||
(* channel->Terminate_Handler)
|
||||
(channel, channel->pid, type, cause, channel->Terminate_Data);
|
||||
}
|
||||
|
||||
channel->close_timeout=0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** SPC_Check style makes sure that we have a legal IOMode.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Check_Style(int iomode)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int stylecount=0;
|
||||
|
||||
/* First, make sure that we have only one style bit set */
|
||||
|
||||
/*** NOTE - We can probably do something more tricky here, to be more
|
||||
efficient. However, I am going to do this the slow way to be safe */
|
||||
|
||||
if(IS_SPCIO_NOIOMODE(iomode))
|
||||
stylecount++;
|
||||
if(IS_SPCIO_PIPE(iomode))
|
||||
stylecount++;
|
||||
if(IS_SPCIO_PTY(iomode))
|
||||
stylecount++;
|
||||
|
||||
if(stylecount != 1) {
|
||||
SPC_Error(SPC_Illegal_Iomode);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* Okay, now check to make sure we don't have any conflicting
|
||||
modes set */
|
||||
|
||||
if ((IS_SPCIO_LINEEDIT(iomode) && IS_SPCIO_PIPE(iomode)) ||
|
||||
(IS_SPCIO_PTY(iomode) && IS_SPCIO_WAIT(iomode) &&
|
||||
!IS_SPCIO_TOOLKIT(iomode)) ||
|
||||
(!IS_SPCIO_NOIO(iomode) && IS_SPCIO_USE_LOGFILE(iomode))
|
||||
)
|
||||
{
|
||||
SPC_Error(SPC_Illegal_Iomode);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** SPC_Transform_Iomode will transform a user-specified iomode into
|
||||
** one that is suitable for use by SPC. It will then check the new
|
||||
** iomode to make sure that it is legal.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Transform_Iomode(int iomode)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(IS_SPCIO_NOIO(iomode))
|
||||
iomode |= SPCIO_NOIOMODE;
|
||||
if(IS_SPCIO_DEFAULT(iomode))
|
||||
iomode |= SPCIO_DEFAULT;
|
||||
if(IS_SPCIO_TOOLKIT(iomode))
|
||||
iomode |= SPCIO_SYNC_TERMINATOR;
|
||||
|
||||
/* Check to make sure that the iomode is consistent */
|
||||
|
||||
if(SPC_Check_Style(iomode)==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(iomode);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** SPC_Newline_Filter will return only lines that end in newlines, or
|
||||
** 'ntoread' characters if no newline is found in time. It will also
|
||||
** return as many characters as have been read in the case of EOF.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Newline_Filter(SPC_Channel_Ptr channel,
|
||||
int connector,
|
||||
XeString buffer,
|
||||
int ntoread)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
buffered_data_ptr cbuf;
|
||||
XeString usrptr;
|
||||
XeString cbufptr;
|
||||
int nchars, nlcopied, scalarlen, nchars_this_buffer;
|
||||
|
||||
if(!(cbuf=channel->linebufs[connector])) {
|
||||
if((cbuf=SPC_New_Buffered_Data_Ptr())==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
channel->linebufs[connector]=cbuf;
|
||||
}
|
||||
|
||||
usrptr=buffer;
|
||||
cbufptr=cbuf->data+cbuf->offset;
|
||||
nchars=0;
|
||||
nlcopied = FALSE;
|
||||
channel->IOMode &= ~SPCIO_HAS_DATA;
|
||||
|
||||
do {
|
||||
|
||||
nchars_this_buffer=0;
|
||||
scalarlen=cbuf->len;
|
||||
|
||||
while(nchars<ntoread && nchars_this_buffer<scalarlen && !nlcopied) {
|
||||
nlcopied = (*cbufptr == Newline);
|
||||
*usrptr++ = (*cbufptr++);
|
||||
nchars++;
|
||||
nchars_this_buffer++;
|
||||
}
|
||||
|
||||
if(nchars == ntoread || nlcopied) {
|
||||
cbuf->offset += nchars_this_buffer;
|
||||
cbuf->len -= nchars_this_buffer;
|
||||
if(strchr(cbuf->data+cbuf->offset, Newline))
|
||||
channel->IOMode |= SPCIO_HAS_DATA;
|
||||
return(nchars);
|
||||
}
|
||||
|
||||
cbufptr = cbuf->data;
|
||||
cbuf->offset = 0;
|
||||
do {
|
||||
cbuf->len=mempf3(channel, read, connector, cbufptr, SPC_BUFSIZ);
|
||||
} while(cbuf->len == (EXCEPT_FLAG));
|
||||
|
||||
cbufptr[cbuf->len]=0;
|
||||
|
||||
} while((cbuf->len) > 0);
|
||||
|
||||
return(nchars);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Input_Handler(SPC_Channel_Ptr channel,
|
||||
int connector)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int nchars;
|
||||
XeChar spc_iobuffer[SPC_BUFSIZ+1];
|
||||
|
||||
channel->IOMode &= ~SPCIO_HAS_DATA;
|
||||
|
||||
do {
|
||||
|
||||
nchars=(*channel->read_filter)
|
||||
(channel, connector, spc_iobuffer, SPC_BUFSIZ);
|
||||
|
||||
/* Check nchars. If it is EXCEPT_FLAG, we had a special occurance (such
|
||||
as an ioctl on a PTY). In any case, don't do any more processing */
|
||||
|
||||
if(nchars==EXCEPT_FLAG)
|
||||
return(FALSE);
|
||||
|
||||
/* Call Read handlers */
|
||||
|
||||
spc_iobuffer[nchars]=XeChar_NULL;
|
||||
|
||||
if(channel->Input_Handler)
|
||||
(* channel->Input_Handler)
|
||||
(channel->client_data, spc_iobuffer, nchars, connector);
|
||||
|
||||
} while(HAS_DATA(channel));
|
||||
|
||||
return(nchars);
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Method definitions for channel objects
|
||||
***
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine handles initialization which must occur for every channel.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr open_channel_object(SPC_Channel_Ptr channel,
|
||||
int iomode,
|
||||
XeString UNUSED_PARM(hostname))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
|
||||
/* initialize local data structures */
|
||||
|
||||
/* If we are doing line-oriented IO, set the read filter
|
||||
to be the NL filter. Otherwise, set it to be the read
|
||||
method. */
|
||||
|
||||
if(IS_SPCIO_LINEORIENTED(iomode))
|
||||
channel->read_filter=SPC_Newline_Filter;
|
||||
else
|
||||
channel->read_filter=channel->class_ptr->read;
|
||||
|
||||
channel->cid=(int)channel;
|
||||
channel->identifier = Channel_Identifier;
|
||||
channel->IOMode = iomode;
|
||||
channel->wires[STDIN] = (&dummy_wire);
|
||||
channel->wires[STDOUT]= (&dummy_wire);
|
||||
channel->wires[STDERR]= (&dummy_wire);
|
||||
channel->file_descs[STDIN] = -1;
|
||||
channel->file_descs[STDOUT]= -1;
|
||||
channel->file_descs[STDERR]= -1;
|
||||
channel->wire_list=NULL;
|
||||
channel->logfile=NULL;
|
||||
|
||||
/* Link it into the activation list (at the front for now) */
|
||||
|
||||
channel->next = spc_activation_list;
|
||||
spc_activation_list = channel;
|
||||
|
||||
return(channel);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** This method will get called AFTER the work done in the child methods,
|
||||
** so's we can deallocate all memory associated with this channel
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int close_channel_object (SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *wirelist, *next_wire;
|
||||
int i;
|
||||
SPC_Channel_Ptr trail, ptr;
|
||||
|
||||
/* Remove the channel from the activation list */
|
||||
|
||||
if(spc_activation_list == channel)
|
||||
spc_activation_list = channel->next;
|
||||
else {
|
||||
trail = spc_activation_list;
|
||||
while(trail) {
|
||||
ptr = trail->next;
|
||||
if(ptr == channel) {
|
||||
trail->next = ptr->next;
|
||||
break;
|
||||
}
|
||||
trail=ptr;
|
||||
}
|
||||
if(!trail) {
|
||||
SPC_Error(SPC_Closed_Channel);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate any memory allocated to the subfields */
|
||||
|
||||
if(IS_SPCIO_DEALLOC_ARGV(channel->IOMode))
|
||||
SPC_Free_Envp(channel->argv);
|
||||
SPC_Free_Envp(channel->envp);
|
||||
|
||||
wirelist=channel->wire_list;
|
||||
while(wirelist) {
|
||||
next_wire=wirelist->next;
|
||||
free_wire(wirelist);
|
||||
wirelist=next_wire;
|
||||
}
|
||||
|
||||
for(i=1; i<3; i++)
|
||||
if(channel->linebufs[i])
|
||||
free((char *)channel->linebufs[i]);
|
||||
|
||||
/* Free the queue associated with the channel */
|
||||
|
||||
SPC_Flush_Queued_Data(channel);
|
||||
Xe_release_queue(channel->queued_remote_data);
|
||||
|
||||
/* Deallocate the channel */
|
||||
|
||||
free((char *)channel);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int read_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(connector), /* STDOUT or STDERR */
|
||||
XeString UNUSED_PARM(buffer),
|
||||
int UNUSED_PARM(nbytes))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
/* need to check consistency between connector and READ/WRITE/ERROR here */
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int write_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
XeString UNUSED_PARM(buffer),
|
||||
int UNUSED_PARM(nbytes))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
/* check for consistent arguments (channel open for WRITE) */
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int reset_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
channel->IOMode &= ~SPCIO_DATA;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int pre_fork_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *wirelist;
|
||||
int flag=0;
|
||||
|
||||
/* Set all wires to be "data ready" */
|
||||
|
||||
for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next) {
|
||||
wirelist->flags |= SPCIO_DATA;
|
||||
flag=1;
|
||||
}
|
||||
|
||||
/* Move to the "Running & (possibly) data ready" state */
|
||||
|
||||
SPC_Change_State(channel, NULL, flag, 1);
|
||||
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int post_fork_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(parentp))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int exec_proc_channel_object (SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
XeString *tmp_argv;
|
||||
int iomode=channel->IOMode;
|
||||
|
||||
/* If there is no argv specified, fix it up to be the convention
|
||||
(argv[0] = file pathname) */
|
||||
|
||||
if (channel->argv == NULL) {
|
||||
tmp_argv=Alloc_Argv(2);
|
||||
if(tmp_argv==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
tmp_argv[0]=SPC_copy_string(channel->path);
|
||||
tmp_argv[1]=NULL;
|
||||
channel->argv = tmp_argv;
|
||||
channel->IOMode |= SPCIO_DEALLOC_ARGV;
|
||||
}
|
||||
|
||||
if(IS_SPCIO_WAIT(channel->IOMode))
|
||||
XeSPCRegisterTerminator(channel, NULL, NULL);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
signal_channel_object (SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(sig))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int channel_object_wait_for_termination(SPC_Channel_Ptr UNUSED_PARM(channel))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
attach_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(pid))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
add_input_channel_object(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
SbInputHandlerProc UNUSED_PARM(handler),
|
||||
void *UNUSED_PARM(data) )
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
remove_logfile_channel_object(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(IS_SPCIO_USE_LOGFILE(channel->IOMode))
|
||||
return(TRUE);
|
||||
else
|
||||
return(FALSE);
|
||||
}
|
||||
1928
cde/lib/DtSvc/DtEncap/spc-proto.c
Normal file
1928
cde/lib/DtSvc/DtEncap/spc-proto.c
Normal file
File diff suppressed because it is too large
Load Diff
203
cde/lib/DtSvc/DtEncap/spc-sm.c
Normal file
203
cde/lib/DtSvc/DtEncap/spc-sm.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* File: spc-sm.c $XConsortium: spc-sm.c /main/4 1996/04/21 19:10:39 drk $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <signal.h>
|
||||
#include <SPC/spcP.h>
|
||||
|
||||
/*
|
||||
**
|
||||
** Definitions for blocking signals
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
static int (* spc_state_table[16]) (SPC_Channel_Ptr channel, int connector)= {
|
||||
|
||||
/* old_state new_state */
|
||||
|
||||
NULL, /* 00 00 */
|
||||
NULL, /* 00 01 */
|
||||
error_fun, /* 00 10 */
|
||||
NULL, /* 00 11 */
|
||||
sigcld_with_reset, /* 01 00 */
|
||||
NULL, /* 01 01 */
|
||||
error_fun, /* 01 10 */
|
||||
error_fun, /* 01 11 */
|
||||
connector_eof_with_reset, /* 10 00 */
|
||||
error_fun, /* 10 01 */
|
||||
NULL, /* 10 10 */
|
||||
error_fun, /* 10 11 */
|
||||
NULL, /* 11 00 */
|
||||
connector_eof, /* 11 01 */
|
||||
NULL, /* 11 10 */
|
||||
NULL /* 11 11 */
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Change_State(SPC_Channel_Ptr channel,
|
||||
int connector,
|
||||
int data_line,
|
||||
int process_line)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int iomode=channel->IOMode;
|
||||
int old_state=CHANNEL_STATE(iomode);
|
||||
int new_state, state_index;
|
||||
int (*fun)(SPC_Channel_Ptr, int);
|
||||
int funretval;
|
||||
|
||||
sigset_t newsigmask, oldsigmask;
|
||||
|
||||
sigemptyset(&newsigmask);
|
||||
sigemptyset(&oldsigmask);
|
||||
|
||||
/* Process don't cares */
|
||||
sigaddset(&newsigmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
|
||||
|
||||
if(data_line == -1)
|
||||
data_line=DATA_LINE(old_state);
|
||||
if(process_line == -1)
|
||||
process_line = PROC_LINE(old_state);
|
||||
|
||||
/* create new state */
|
||||
|
||||
new_state=MAKE_STATE(data_line, process_line);
|
||||
|
||||
/* If no state change, return */
|
||||
|
||||
if(new_state == old_state) {
|
||||
sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Lookup & process transition function */
|
||||
|
||||
state_index=MAKE_STATE_INDEX(old_state, new_state);
|
||||
|
||||
fun=spc_state_table[state_index];
|
||||
|
||||
if(fun == error_fun) {
|
||||
sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
channel->IOMode=MAKE_CHANNEL_STATE(iomode, new_state);
|
||||
if(!fun) {
|
||||
sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
funretval=((*fun)(channel, connector));
|
||||
|
||||
sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
|
||||
return funretval;
|
||||
|
||||
}
|
||||
|
||||
/* error_fun is not ever called. It is just a placeholder for an
|
||||
error condition in the state table */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
error_fun(SPC_Channel_Ptr UNUSED_PARM(channel),
|
||||
int UNUSED_PARM(connector))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
** This routine is called when an EOF is detected on a specific
|
||||
** connector within a channel, but the channel still has a subprocess
|
||||
** associated with it. It will clear the data ready flag on the
|
||||
** indicated wire. After that, it will look at all the wires
|
||||
** associated with the channel and set the channel's data flag to the
|
||||
** inclusive OR of the individual wire's data flags.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
connector_eof(SPC_Channel_Ptr channel,
|
||||
int connector)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *wire=channel->wires[connector];
|
||||
Wire *tmpwire;
|
||||
int channelflag=0;
|
||||
int iomode=channel->IOMode;
|
||||
|
||||
if(!wire)
|
||||
return(FALSE);
|
||||
|
||||
wire->flags &= ~SPCIO_DATA;
|
||||
|
||||
if(IS_SPCIO_STDOUT(iomode)) {
|
||||
tmpwire=channel->wires[STDOUT];
|
||||
channelflag |= IS_SPCIO_DATA(tmpwire->flags);
|
||||
}
|
||||
|
||||
if(IS_SPCIO_STDERR(iomode) && IS_SPCIO_SEPARATE(iomode)) {
|
||||
tmpwire=channel->wires[STDERR];
|
||||
channelflag |= IS_SPCIO_DATA(tmpwire->flags);
|
||||
}
|
||||
|
||||
if(channelflag)
|
||||
channel->IOMode |= SPCIO_DATA;
|
||||
else
|
||||
channel->IOMode &= ~SPCIO_DATA;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** This routine is called when there is no subprocess associated with
|
||||
** the channel, and an EOF is detected on a connector. It will first
|
||||
** call connector_eof on the channel/connector, and if the channel
|
||||
** does not have its data flag set, it will reset the channel.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
connector_eof_with_reset(SPC_Channel_Ptr channel,
|
||||
int connector)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
connector_eof(channel, connector);
|
||||
if(!IS_DATA(channel))
|
||||
XeSPCReset(channel);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** This routine is called when the child associated with the channel
|
||||
** dies, and there is no data available to be read on the channel.
|
||||
** It will simply reset then channel.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
sigcld_with_reset(SPC_Channel_Ptr channel,
|
||||
int UNUSED_PARM(connector))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
mempf0(channel, reset);
|
||||
return(TRUE);
|
||||
}
|
||||
618
cde/lib/DtSvc/DtEncap/spc-termio.c
Normal file
618
cde/lib/DtSvc/DtEncap/spc-termio.c
Normal file
@@ -0,0 +1,618 @@
|
||||
/*
|
||||
* File: spc-termio.c $TOG: spc-termio.c /main/5 1998/04/03 17:08:32 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1990, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h>
|
||||
#include <bms/stringbuf.h>
|
||||
|
||||
#include <termios.h>
|
||||
#if !defined(linux)
|
||||
#include <sys/termio.h>
|
||||
#endif
|
||||
#include <codelibs/stringx.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define STRTOKX(b,f) strtokx((b), (f))
|
||||
#else
|
||||
#define STRTOKX(b,f) strtokx((char **)(&b), (f))
|
||||
#endif
|
||||
|
||||
/***************************************************************************************
|
||||
|
||||
The routines in this file decode and encode a termios struct back and forth between the
|
||||
actual binary representation of the structure and an ASCII string representation which
|
||||
may be portably sent across the network.
|
||||
|
||||
<version>!<i-flags>!<o-flags>!<c-flags>!<l-flags>!<i-speed>!<o-speed>!<cc-array>
|
||||
|
||||
Where:
|
||||
|
||||
<version> == the termios struct protocal version (currently XPG3)
|
||||
|
||||
<i-flags> == comma separated list of input mode flags as defined in
|
||||
the termios.h header file.
|
||||
|
||||
<o-flags> == comma separated list of output mode flags as defined in
|
||||
the termios.h header file.
|
||||
|
||||
<c-flags> == comma separated list of control mode flags as defined in
|
||||
the termios.h header file. The terminal speed info is
|
||||
not part of this list.
|
||||
|
||||
<i-speed> == The input speed as defined in the termios.h header file.
|
||||
|
||||
<o-speed> == The output speed as defined in the termios.h header file.
|
||||
|
||||
<cc-array> == comma separated list of control control character names and
|
||||
values formatted as (<name>=<value),<name>=<value>...)
|
||||
|
||||
******************************************************************************************/
|
||||
|
||||
#define SPC_TERMIO_VER_FIELD 1 /* Define field indicies for above string */
|
||||
#define SPC_TERMIO_IMODE_FIELD 2
|
||||
#define SPC_TERMIO_OMODE_FIELD 3
|
||||
#define SPC_TERMIO_CMODE_FIELD 4
|
||||
#define SPC_TERMIO_LMODE_FIELD 5
|
||||
#define SPC_TERMIO_ISPEED_FIELD 6
|
||||
#define SPC_TERMIO_OSPEED_FIELD 7
|
||||
#define SPC_TERMIO_CC_FIELD 8
|
||||
#define SPC_TERMIO_LAST_FIELD SPC_TERMIO_CC_FIELD
|
||||
|
||||
#define SPC_TERMIO_SEP "!" /* These three MUST be only 1 char */
|
||||
#define SPC_TCFLAG_SEP ","
|
||||
#define SPC_CC_SEP "="
|
||||
|
||||
#define SPC_CC_FORMAT "%u" /* CC values are printed with this format */
|
||||
|
||||
struct modes_s
|
||||
{
|
||||
XeString name;
|
||||
tcflag_t value;
|
||||
};
|
||||
|
||||
struct baud_s
|
||||
{
|
||||
XeString name;
|
||||
speed_t speed;
|
||||
};
|
||||
|
||||
struct cc_s
|
||||
{
|
||||
XeString name;
|
||||
cc_t value;
|
||||
};
|
||||
|
||||
/* The following lists are the valid componants of a "struct termios" */
|
||||
/* as defined in XPG3. These MUST be kept up to date with the X/Open */
|
||||
/* standard. No platform specific items can exist here as we pass this */
|
||||
/* data to other systems on the network and they be from any vendor. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
#define SPC_TERMIO_VERSION "XPG3"
|
||||
|
||||
#define END_OF_LIST "End_Of_List"
|
||||
|
||||
static struct modes_s Input_modes[] = {
|
||||
"BRKINT", BRKINT,
|
||||
"ICRNL", ICRNL,
|
||||
"IGNBRK", IGNBRK,
|
||||
"IGNCR", IGNCR,
|
||||
"IGNPAR", IGNPAR,
|
||||
"INLCR", INLCR,
|
||||
"INPCK", INPCK,
|
||||
"ISTRIP", ISTRIP,
|
||||
"IXOFF", IXOFF,
|
||||
"IXON", IXON,
|
||||
"PARMRK", PARMRK,
|
||||
END_OF_LIST, 0
|
||||
};
|
||||
|
||||
static struct modes_s Output_modes[] = {
|
||||
"OPOST", OPOST,
|
||||
"ONLCR", ONLCR,
|
||||
"OCRNL", OCRNL,
|
||||
"ONOCR", ONOCR,
|
||||
"ONLRET", ONLRET,
|
||||
"OFILL", OFILL,
|
||||
"OFDEL", OFDEL,
|
||||
"NLDLY", NLDLY,
|
||||
"NL0", NL0,
|
||||
"NL1", NL1,
|
||||
"CRDLY", CRDLY,
|
||||
"CR0", CR0,
|
||||
"CR1", CR1,
|
||||
"CR2", CR2,
|
||||
"CR3", CR3,
|
||||
"TABDLY", TABDLY,
|
||||
"TAB0", TAB0,
|
||||
"TAB1", TAB1,
|
||||
"TAB2", TAB2,
|
||||
"TAB3", TAB3,
|
||||
"BSDLY", BSDLY,
|
||||
"BS0", BS0,
|
||||
"BS1", BS1,
|
||||
"VTDLY", VTDLY,
|
||||
"VT0", VT0,
|
||||
"VT1", VT1,
|
||||
"FFDLY", FFDLY,
|
||||
"FF0", FF0,
|
||||
"FF1", FF1,
|
||||
END_OF_LIST, 0
|
||||
};
|
||||
|
||||
|
||||
static struct baud_s Baud_rates[] = {
|
||||
"B0", B0,
|
||||
"B50", B50,
|
||||
"B75", B75,
|
||||
"B110", B110,
|
||||
"B134", B134,
|
||||
"B150", B150,
|
||||
"B200", B200,
|
||||
"B300", B300,
|
||||
"B600", B600,
|
||||
"B1200", B1200,
|
||||
"B1800", B1800,
|
||||
"B2400", B2400,
|
||||
"B4800", B4800,
|
||||
"B9600", B9600,
|
||||
"B19200", B19200,
|
||||
"B38400", B38400,
|
||||
END_OF_LIST, 0
|
||||
};
|
||||
|
||||
|
||||
static struct modes_s Control_modes[] = {
|
||||
"CSIZE", CSIZE,
|
||||
"CS5", CS5,
|
||||
"CS6", CS6,
|
||||
"CS7", CS7,
|
||||
"CS8", CS8,
|
||||
"CSTOPB", CSTOPB,
|
||||
"CREAD", CREAD,
|
||||
"PARENB", PARENB,
|
||||
"PARODD", PARODD,
|
||||
"HUPCL", HUPCL,
|
||||
"CLOCAL", CLOCAL,
|
||||
END_OF_LIST, 0
|
||||
};
|
||||
|
||||
|
||||
static struct modes_s Local_modes[] = {
|
||||
"ECHO", ECHO,
|
||||
"ECHOE", ECHOE,
|
||||
"ECHOK", ECHOK,
|
||||
"ECHONL", ECHONL,
|
||||
"ICANON", ICANON,
|
||||
"IEXTEN", IEXTEN,
|
||||
"ISIG", ISIG,
|
||||
"NOFLSH", NOFLSH,
|
||||
"TOSTOP", TOSTOP,
|
||||
END_OF_LIST, 0
|
||||
};
|
||||
|
||||
|
||||
static struct cc_s CC_Array[] = {
|
||||
"VEOF", VEOF,
|
||||
"VEOL", VEOL,
|
||||
"VERASE", VERASE,
|
||||
"VINTR", VINTR,
|
||||
"VKILL", VKILL,
|
||||
"VMIN", VMIN,
|
||||
"VQUIT", VQUIT,
|
||||
"VSTART", VSTART,
|
||||
"VSTOP", VSTOP,
|
||||
"VSUSP", VSUSP,
|
||||
"VTIME", VTIME,
|
||||
END_OF_LIST, 0
|
||||
};
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static void
|
||||
SPC_Decode_TCflag(tcflag_t flag,
|
||||
struct modes_s modes[],
|
||||
XeStringBuffer buff)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Boolean first_time = TRUE;
|
||||
|
||||
/* Given a binary representation of flag (tcflag_t), convert */
|
||||
/* it into a comma separated list of ASCII flag names. */
|
||||
|
||||
while (strcmp(modes->name, END_OF_LIST) != 0)
|
||||
{
|
||||
if ( (modes->value & flag) == modes->value)
|
||||
{
|
||||
if (first_time)
|
||||
first_time = FALSE;
|
||||
else
|
||||
XeAppendToStringBuffer(buff, SPC_TCFLAG_SEP);
|
||||
|
||||
XeAppendToStringBuffer(buff, modes->name);
|
||||
}
|
||||
modes++;
|
||||
}
|
||||
|
||||
/* We need at least one blank for strtokx to work when */
|
||||
/* we take this string apart on the other side. */
|
||||
/* --------------------------------------------------- */
|
||||
if (first_time)
|
||||
XeAppendToStringBuffer(buff, (XeString)" ");
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static tcflag_t
|
||||
SPC_Encode_TCflag(XeString buff,
|
||||
struct modes_s modes[])
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Given a comma separated list of flag names, convert the list */
|
||||
/* into a "tcflag_t" (binary) representation of that list. */
|
||||
|
||||
XeString item;
|
||||
tcflag_t flag = (tcflag_t)0;
|
||||
struct modes_s *orig_modes = modes;
|
||||
|
||||
if (!*buff)
|
||||
return flag;
|
||||
|
||||
while (item = (XeString)STRTOKX(buff, SPC_TCFLAG_SEP))
|
||||
{
|
||||
Boolean found = FALSE;
|
||||
|
||||
modes = orig_modes;
|
||||
while (strcmp(modes->name, END_OF_LIST) != 0)
|
||||
{
|
||||
if (strcmp(modes->name, item) == 0)
|
||||
{
|
||||
flag |= modes->value;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
modes++;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
SPC_Error(SPC_Bad_Termios_Mode, item);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static void
|
||||
SPC_Decode_Speed(speed_t speed,
|
||||
struct baud_s bauds[],
|
||||
XeStringBuffer buff)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Given a binary "speed_t" speed specification, convert it into */
|
||||
/* a single ASCII string. */
|
||||
|
||||
while (strcmp(bauds->name, END_OF_LIST) != 0)
|
||||
{
|
||||
if (bauds->speed == speed)
|
||||
{
|
||||
XeAppendToStringBuffer(buff, bauds->name);
|
||||
return;
|
||||
}
|
||||
bauds++;
|
||||
}
|
||||
|
||||
/* We need at least one blank for strtokx to work when */
|
||||
/* we take this string apart on the other side. */
|
||||
/* --------------------------------------------------- */
|
||||
XeAppendToStringBuffer(buff, (XeString)" ");
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static speed_t
|
||||
SPC_Encode_Speed(XeString buff,
|
||||
struct baud_s bauds[])
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
#define DEFAULT_SPEED B9600
|
||||
|
||||
/* Given a single ASCII name of a termio speed item, convert it into */
|
||||
/* a binary (speed_t) representation. */
|
||||
|
||||
if (!*buff)
|
||||
return DEFAULT_SPEED;
|
||||
|
||||
while (strcmp(bauds->name, END_OF_LIST) != 0)
|
||||
{
|
||||
if (strcmp(bauds->name, buff) == 0)
|
||||
return bauds->speed;
|
||||
bauds++;
|
||||
}
|
||||
|
||||
SPC_Error(SPC_Bad_Termios_Speed, buff);
|
||||
return DEFAULT_SPEED;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static void
|
||||
SPC_Decode_CC(cc_t ccs[],
|
||||
struct cc_s cc_array[],
|
||||
XeStringBuffer buff)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Boolean first_time = TRUE;
|
||||
|
||||
/* Given an array of cc_s from a termios struct (binary */
|
||||
/* representation), convert it into a comma sepearted list of */
|
||||
/* CC names and values of the form <name>=<value> */
|
||||
|
||||
while (strcmp(cc_array->name, END_OF_LIST) != 0)
|
||||
{
|
||||
int index = ccs[cc_array->value];
|
||||
if ( index != 0 )
|
||||
{
|
||||
XeChar num[30];
|
||||
|
||||
if (first_time)
|
||||
first_time = FALSE;
|
||||
else
|
||||
XeAppendToStringBuffer(buff, SPC_TCFLAG_SEP);
|
||||
|
||||
XeAppendToStringBuffer(buff, cc_array->name);
|
||||
XeAppendToStringBuffer(buff, SPC_CC_SEP);
|
||||
sprintf(num, SPC_CC_FORMAT, index);
|
||||
XeAppendToStringBuffer(buff, num);
|
||||
}
|
||||
cc_array++;
|
||||
}
|
||||
|
||||
/* We need at least one blank for strtokx to work when */
|
||||
/* we take this string apart on the other side. */
|
||||
/* --------------------------------------------------- */
|
||||
if (first_time)
|
||||
XeAppendToStringBuffer(buff, (XeString)" ");
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
static void
|
||||
SPC_Encode_CC(XeString buff,
|
||||
cc_t ccs[],
|
||||
struct cc_s cc_array[])
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* we should have gotten a string that looks like this: */
|
||||
/* */
|
||||
/* <V-Name>=<value>,<V-Name>=<value>... */
|
||||
/* */
|
||||
/* For example: VEOF=4,VKILL=8 */
|
||||
/* */
|
||||
/* Parse this array and store the values in the "ccs" array passed in */
|
||||
/* to us. It is assumed that the <V-name> strings are all defined in */
|
||||
/* the "cc_array" list passed to us. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
XeString cc_name, cc_value;
|
||||
int i;
|
||||
unsigned int a_cc;
|
||||
struct cc_s *orig_cc_array = cc_array;
|
||||
|
||||
for(i=0; i<NCCS; i++)
|
||||
ccs[i] = 0;
|
||||
|
||||
if (!*buff) return;
|
||||
|
||||
while (cc_name = (XeString)STRTOKX(buff, SPC_TCFLAG_SEP))
|
||||
{
|
||||
Boolean found = FALSE;
|
||||
|
||||
cc_value = strchr(cc_name, SPC_CC_SEP[0]); /* Go find the "=" */
|
||||
if (!cc_value)
|
||||
{
|
||||
SPC_Error(SPC_Bad_Termios_CC, cc_name);
|
||||
continue;
|
||||
}
|
||||
*cc_value++ = XeChar_NULL; /* Replace "=" with null */
|
||||
|
||||
|
||||
/* Look for "V-Name" in table ... */
|
||||
/* ------------------------------ */
|
||||
cc_array = orig_cc_array;
|
||||
while (strcmp(cc_array->name, END_OF_LIST) != 0)
|
||||
{
|
||||
if (strcmp(cc_array->name, cc_name) == 0)
|
||||
{
|
||||
if (sscanf(cc_value, SPC_CC_FORMAT, &a_cc) != 1)
|
||||
{
|
||||
*(cc_value-1) = SPC_CC_SEP[0];
|
||||
SPC_Error(SPC_Bad_Termios_CC, cc_name);
|
||||
}
|
||||
else
|
||||
ccs[cc_array->value] = a_cc;
|
||||
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
cc_array++;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
*(cc_value-1) = SPC_CC_SEP[0];
|
||||
SPC_Error(SPC_Bad_Termios_CC, cc_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString SPC_Decode_Termios(struct termios *tio)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Given a termios struct, return an ascii string representation of */
|
||||
/* it as defined at the front of this file. */
|
||||
|
||||
#define RESULT_BUFF_SIZE 32
|
||||
|
||||
XeString all;
|
||||
speed_t speed;
|
||||
XeStringBuffer result = XeMakeStringBuffer(RESULT_BUFF_SIZE);
|
||||
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_VERSION);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
SPC_Decode_TCflag(tio->c_iflag, Input_modes, result);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
SPC_Decode_TCflag(tio->c_oflag, Output_modes, result);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
SPC_Decode_TCflag(tio->c_cflag, Control_modes, result);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
SPC_Decode_TCflag(tio->c_lflag, Local_modes, result);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
speed = cfgetispeed(tio);
|
||||
SPC_Decode_Speed(speed, Baud_rates, result);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
speed = cfgetospeed(tio);
|
||||
SPC_Decode_Speed(speed, Baud_rates, result);
|
||||
XeAppendToStringBuffer(result, SPC_TERMIO_SEP);
|
||||
|
||||
SPC_Decode_CC(tio->c_cc, CC_Array, result);
|
||||
|
||||
all = strdup(result->buffer);
|
||||
|
||||
XeFree(result->buffer);
|
||||
XeFree(result);
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void SPC_Encode_Termios(XeString buff, struct termios *tio)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Decodes the ascii representation of the termios struct. The format */
|
||||
/* of the string is defined at the front of this file. */
|
||||
|
||||
XeString item;
|
||||
XeString protocol_version;
|
||||
int item_cnt = 0;
|
||||
speed_t speed;
|
||||
|
||||
while (item = (XeString)STRTOKX(buff, SPC_TERMIO_SEP))
|
||||
{
|
||||
/* We can possibly have an all blank field. Walk past them */
|
||||
/* because the routines we will be calling don't expect any */
|
||||
/* blanks in the string (but they do check for empty stings).*/
|
||||
while (*item == (XeChar)' ') item++;
|
||||
|
||||
switch(++item_cnt)
|
||||
{
|
||||
case SPC_TERMIO_VER_FIELD :
|
||||
protocol_version = item;
|
||||
/* Check this some day ??? */
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_IMODE_FIELD :
|
||||
tio->c_iflag = SPC_Encode_TCflag(item, Input_modes);
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_OMODE_FIELD :
|
||||
tio->c_oflag = SPC_Encode_TCflag(item, Output_modes);
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_CMODE_FIELD :
|
||||
tio->c_cflag = SPC_Encode_TCflag(item, Control_modes);
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_LMODE_FIELD :
|
||||
tio->c_lflag = SPC_Encode_TCflag(item, Local_modes);
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_ISPEED_FIELD :
|
||||
speed = SPC_Encode_Speed(item, Baud_rates);
|
||||
cfsetispeed(tio, speed);
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_OSPEED_FIELD :
|
||||
speed = SPC_Encode_Speed(item, Baud_rates);
|
||||
cfsetospeed(tio, speed);
|
||||
break;
|
||||
|
||||
case SPC_TERMIO_CC_FIELD :
|
||||
SPC_Encode_CC(item, tio->c_cc, CC_Array);
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
|
||||
} /* while */
|
||||
|
||||
if (item_cnt != SPC_TERMIO_LAST_FIELD)
|
||||
SPC_Error(SPC_Bad_Termios_Proto,
|
||||
(XeString) ((item_cnt < SPC_TERMIO_LAST_FIELD) ? "Too Few" : "Too Many"));
|
||||
|
||||
}
|
||||
|
||||
#ifdef TESTING
|
||||
/*----------------------------------------------------------------------+*/
|
||||
main()
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString s, s1, s2;
|
||||
int i;
|
||||
struct termios tio, tio2;
|
||||
speed_t speed;
|
||||
|
||||
tio.c_iflag = BRKINT | IGNPAR | ICRNL | IXON;
|
||||
tio.c_oflag = OPOST | ONLCR;
|
||||
tio.c_cflag = CS7 | CREAD | CLOCAL;
|
||||
tio.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK;
|
||||
|
||||
tio.c_reserved = 0;
|
||||
for(i=0; i<NCCS; i++)
|
||||
tio.c_cc[i] = 0;
|
||||
tio.c_cc[VERASE] = 101;
|
||||
tio.c_cc[VEOF] = 102;
|
||||
tio.c_cc[VSTOP] = 103;
|
||||
|
||||
|
||||
tio2.c_iflag = 0;
|
||||
tio2.c_oflag = 0;
|
||||
tio2.c_cflag = 0;
|
||||
tio2.c_lflag = 0;
|
||||
|
||||
tio2.c_reserved = 0;
|
||||
for(i=0; i<NCCS; i++)
|
||||
tio2.c_cc[i] = 0;
|
||||
|
||||
cfsetispeed(&tio, B9600);
|
||||
cfsetospeed(&tio, B1200);
|
||||
|
||||
s1 = strdup(s = SPC_Decode_Termios(&tio));
|
||||
printf("Decoded string=\n<%s>\n\n", s);
|
||||
|
||||
|
||||
SPC_Encode_Termios(s, &tio2);
|
||||
s2 = strdup(s = SPC_Decode_Termios(&tio2));
|
||||
printf("String after Encoding/decoding=\n<%s>\n\n", s2);
|
||||
|
||||
if (strcmp(s1, s2) == 0)
|
||||
printf("...Identical ...\n");
|
||||
else
|
||||
printf("...Mismatch ...\n");
|
||||
|
||||
}
|
||||
#endif /* TESTING */
|
||||
289
cde/lib/DtSvc/DtEncap/spc-util.c
Normal file
289
cde/lib/DtSvc/DtEncap/spc-util.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* File: spc-util.c $XConsortium: spc-util.c /main/5 1996/06/21 17:33:16 ageorge $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <SPC/spcP.h>
|
||||
#include <bms/MemoryMgr.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/* The application's SPC activation list */
|
||||
SPC_Channel_Ptr spc_activation_list = NULL;
|
||||
|
||||
/* Allocate us up a wire */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
Wire *get_new_wire(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
Wire *tmp_wire;
|
||||
|
||||
tmp_wire=(Wire *)XeMalloc(sizeof(Wire));
|
||||
memset(tmp_wire, NULL, sizeof(Wire));
|
||||
|
||||
tmp_wire->master_name=(XeString)XeMalloc(PTY_NAMLEN);
|
||||
memset(tmp_wire->master_name, NULL, PTY_NAMLEN);
|
||||
tmp_wire->slave_name =(XeString)XeMalloc(PTY_NAMLEN);
|
||||
memset(tmp_wire->slave_name, NULL, PTY_NAMLEN);
|
||||
tmp_wire->fd[0] = tmp_wire->fd[1] = (-1);
|
||||
tmp_wire->read_toolkit_id = (-1);
|
||||
tmp_wire->except_toolkit_id = (-1);
|
||||
return(tmp_wire);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void free_wire(Wire *wire)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
free(wire->master_name);
|
||||
free(wire->slave_name);
|
||||
free((char *)wire);
|
||||
}
|
||||
|
||||
/*
|
||||
* Channel object access
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr SPC_Find_PID(int pid)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Attempt to return a channel which currently handles process number PID */
|
||||
SPC_Channel_Ptr spc;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
for (spc = spc_activation_list; spc != NULL; spc = spc->next) {
|
||||
if (spc->pid == pid) break;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return spc; /* NULL when not found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Miscellaneous
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
spc_close(int fd)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Close a file descriptor which was referenced through an SPC structure */
|
||||
if(fd != -1)
|
||||
close(fd);
|
||||
|
||||
return(fd);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
spc_dup2(int from, int to)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int retval;
|
||||
|
||||
/* Dup file descriptors. If a null descriptor, then use /dev/null */
|
||||
static int devnull = NULL;
|
||||
|
||||
if (from == to)
|
||||
return(TRUE);
|
||||
|
||||
if (from == -1) {
|
||||
_DtSvcProcessLock();
|
||||
if (!devnull)
|
||||
devnull = open("/dev/null", 0);
|
||||
/* Use /dev/null when no source file descriptor */
|
||||
from = devnull;
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/* Now do the dup2 */
|
||||
retval=dup2(from, to);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_fd_to_connector(SPC_Channel_Ptr channel,
|
||||
int fd)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(Stdout(channel) == fd)
|
||||
return(STDOUT);
|
||||
if(Stdin(channel) == fd)
|
||||
return(STDIN);
|
||||
if(Stderr(channel) == fd)
|
||||
return(STDERR);
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
XeString *Alloc_Argv(int n)
|
||||
{
|
||||
/* Allocate an array to hold argv list */
|
||||
XeString *av;
|
||||
|
||||
av = (XeString *)XeMalloc((n + 1) * sizeof(XeString));
|
||||
|
||||
/* Zero the space so we don't have to worry about trailing NULL */
|
||||
memset((XeString) av, NULL, (n + 1) * sizeof(XeString));
|
||||
|
||||
return(av);
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Toolkit integration stuff, without direct calls to the toolkit.
|
||||
***
|
||||
*/
|
||||
|
||||
int break_on_termination=FALSE;
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void SPC_Conditional_Packet_Handler(void * UNUSED_PARM(client_data),
|
||||
int * source,
|
||||
SPCInputId * UNUSED_PARM(id))
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Channel_Ptr channel;
|
||||
|
||||
channel = XeSPCHandleTerminator(*source);
|
||||
|
||||
/* Okay, blast out of our wait */
|
||||
_DtSvcProcessLock();
|
||||
if( (channel==SPC_ERROR || !IS_ACTIVE(channel)) &&
|
||||
break_on_termination)
|
||||
SPC_XtBreak();
|
||||
_DtSvcProcessUnlock();
|
||||
/* return(TRUE); */
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int sprintf_len (XeString s, XeString format, ...)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
if (s) *s = XeChar_NULL;
|
||||
vsprintf(s, format, ap);
|
||||
return(strlen(s));
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** _path_search is a generalized function used for parsing the PATH
|
||||
*** environment variable wrt a passed filename. It will run down the
|
||||
*** passed path variable looking for ':'. When it finds one (or hits
|
||||
*** the end of the string), it will concatenate the substring with
|
||||
*** filename, passing the result to the passed path_search_predicate.
|
||||
*** If this predicate returns true, the function will return with a
|
||||
*** true value. If all elements of the path are processed with no
|
||||
*** true result from the predicate, the function will return false.
|
||||
***
|
||||
*** A few special cases:
|
||||
*** - If the filename begins with '/' (an absolute path), the
|
||||
*** funciton will return the value of the predicate on the
|
||||
*** filename (e.g. PATH processing will not be done).
|
||||
*** - a NULL value of any path component will be interpreted as the
|
||||
*** current directory ('.').
|
||||
*** - a NULL value for the path parameter means use the PATH
|
||||
*** environment variable.
|
||||
*** - a NULL value for filename will return FALSE
|
||||
***
|
||||
*/
|
||||
|
||||
/*
|
||||
***
|
||||
*** MAXPATHLEN is defined in sbstdinc.h
|
||||
***
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
Boolean _path_search (XeString path, XeString filename, path_search_predicate p)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
XeString path_rest, next_colon=NULL;
|
||||
XeChar buffer[MAXPATHLEN+1];
|
||||
XeChar path_component[MAXPATHLEN+1];
|
||||
int path_component_len;
|
||||
int filename_len;
|
||||
int component_seperator=(int)':'; /* this is here because strchr takes an in */
|
||||
|
||||
if(!filename)
|
||||
return(FALSE);
|
||||
|
||||
if(*filename == '/')
|
||||
return((*p)(filename, NULL, filename));
|
||||
|
||||
filename_len = strlen(filename);
|
||||
if(!path)
|
||||
path=getenv("PATH");
|
||||
|
||||
for( (path_rest=path ,
|
||||
next_colon=strchr(path_rest, component_seperator));
|
||||
path_rest && *path_rest;
|
||||
next_colon=strchr(path_rest, component_seperator)) {
|
||||
|
||||
/*
|
||||
** Copy path component into buffer
|
||||
*/
|
||||
|
||||
if(next_colon) { /* found colon */
|
||||
path_component_len = next_colon-path_rest;
|
||||
strncpy(buffer, path_rest, path_component_len);
|
||||
buffer[path_component_len]=NULL;
|
||||
path_rest=next_colon+1;
|
||||
if(!*path_rest)
|
||||
/* We've seen a ':' at the end of the string. Make path_rest be "."
|
||||
next go-round */
|
||||
path_rest=".";
|
||||
} else { /* no colon */
|
||||
path_component_len = strlen(path_rest);
|
||||
strcpy(buffer, path_rest);
|
||||
path_rest=NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** if path component is NULL, use default ('.');
|
||||
*/
|
||||
|
||||
if(!buffer[0]) {
|
||||
buffer[0] = '.';
|
||||
buffer[1] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Concatenate filename
|
||||
*/
|
||||
|
||||
if((path_component_len + filename_len + 1) < MAXPATHLEN) {
|
||||
path_component[0]=0;
|
||||
strcat(path_component, buffer);
|
||||
strcat(buffer, "/");
|
||||
strcat(buffer, filename);
|
||||
|
||||
/*
|
||||
** Check this file. If the predicate returns true, we return true.
|
||||
*/
|
||||
|
||||
if((*p)(buffer, path_component, filename))
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** We've checked all components. Return False.
|
||||
*/
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
242
cde/lib/DtSvc/DtEncap/spc-xt.c
Normal file
242
cde/lib/DtSvc/DtEncap/spc-xt.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* File: spc-xt.c $TOG: spc-xt.c /main/6 1998/03/16 14:41:02 mgreess $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#define __need_fd_set
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <time.h>
|
||||
#include <SPC/spcP.h>
|
||||
/* #include <bms/SbEvent.h> */ /* This file now included by spcP.h */
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/* Externals */
|
||||
|
||||
extern int break_on_termination;
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
/* First, declarations */
|
||||
|
||||
typedef struct {
|
||||
SbInputId read_id;
|
||||
SbInputId except_id;
|
||||
} SPC_Callback_Struct;
|
||||
|
||||
static SPC_Callback_Struct **SPC_Fd_Mapping = NULL;
|
||||
|
||||
#define SPC_LOOKUP_FD_MAPPING(fd) SPC_Fd_Mapping[(fd)]
|
||||
|
||||
static Boolean spc_xe_termination_flag;
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
static int SPC_AddInput(int source,
|
||||
SPC_Callback_Condition condition,
|
||||
SbInputId id)
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Callback_Struct *structptr = NULL;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (SPC_Fd_Mapping == NULL) {
|
||||
SPC_Fd_Mapping = (SPC_Callback_Struct **)
|
||||
XeMalloc (FD_SETSIZE * sizeof (SPC_Callback_Struct *));
|
||||
memset(SPC_Fd_Mapping, NULL, FD_SETSIZE * sizeof(SPC_Callback_Struct *));
|
||||
}
|
||||
structptr=SPC_LOOKUP_FD_MAPPING(source);
|
||||
|
||||
if(!structptr) {
|
||||
structptr=(SPC_Callback_Struct *) XeMalloc(sizeof(SPC_Callback_Struct));
|
||||
SPC_LOOKUP_FD_MAPPING(source)=structptr;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
switch (condition) {
|
||||
|
||||
case SPC_Input:
|
||||
case SPC_Terminator:
|
||||
case SPC_Client:
|
||||
structptr->read_id = id;
|
||||
break;
|
||||
|
||||
case SPC_Exception:
|
||||
structptr->except_id = id;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(source);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
static SbInputId SPC_RemoveInput(int source,
|
||||
SPC_Callback_Condition condition)
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Callback_Struct *structptr = NULL;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (SPC_Fd_Mapping == NULL) {
|
||||
SPC_Fd_Mapping = (SPC_Callback_Struct **)
|
||||
XeMalloc (FD_SETSIZE * sizeof (SPC_Callback_Struct *));
|
||||
memset(SPC_Fd_Mapping, NULL, FD_SETSIZE * sizeof(SPC_Callback_Struct *));
|
||||
}
|
||||
structptr=SPC_LOOKUP_FD_MAPPING(source);
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
switch(condition) {
|
||||
|
||||
case SPC_Input:
|
||||
case SPC_Terminator:
|
||||
case SPC_Client:
|
||||
return structptr->read_id;
|
||||
|
||||
case SPC_Exception:
|
||||
return structptr->except_id;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
static SPC_Select(void )
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
break_on_termination=TRUE;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
spc_xe_termination_flag= FALSE;
|
||||
|
||||
/* Use a function pointer so we don't have explict dependancy */
|
||||
/* on libXe.a */
|
||||
/* ---------------------------------------------------------- */
|
||||
if (SbMainLoopUntil_hookfn == NULL)
|
||||
(void) fprintf (stderr, "Error: SbMainLoopUntil = NULL\n");
|
||||
else
|
||||
(*SbMainLoopUntil_hookfn)(&spc_xe_termination_flag);
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
break_on_termination=FALSE;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
int SPC_Wait_For_Termination(SPC_Channel_Ptr channel)
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
int result;
|
||||
|
||||
call_parent_method(channel, wait_for_termination, (channel), result);
|
||||
|
||||
if(result==SPC_ERROR) return(SPC_ERROR);
|
||||
|
||||
do {
|
||||
|
||||
if(SPC_Select() == SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
} while(IS_ACTIVE(channel));
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
void SPC_XtBreak(void)
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if(!spc_xe_termination_flag) {
|
||||
spc_xe_termination_flag = TRUE;
|
||||
if (SbBreakMainLoop_hookfn == NULL)
|
||||
(void) fprintf (stderr, "Error: SbBreakMainLoop = NULL\n");
|
||||
else
|
||||
(*SbBreakMainLoop_hookfn)();
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
void SPC_XtAddInput(SPC_Channel_Ptr channel,
|
||||
int *id_addr,
|
||||
int fd,
|
||||
spc_handler_func_type handler,
|
||||
SPC_Callback_Condition condition)
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
SbInputId id;
|
||||
|
||||
switch(condition) {
|
||||
|
||||
case SPC_Input:
|
||||
case SPC_Terminator:
|
||||
case SPC_Client:
|
||||
/* fprintf(stderr, "SPC add input/terminator for %d\n", fd); */
|
||||
if (SbAddInput_hookfn == NULL)
|
||||
(void) fprintf (stderr, "Error: SbAddInput = NULL\n");
|
||||
else
|
||||
id = (*SbAddInput_hookfn)(fd, handler, channel);
|
||||
break;
|
||||
|
||||
case SPC_Exception:
|
||||
/* fprintf(stderr, "SPC add exception for %d\n", fd); */
|
||||
if (SbAddException_hookfn == NULL)
|
||||
(void) fprintf (stderr, "Error: SbAddException = NULL\n");
|
||||
else
|
||||
id = (*SbAddException_hookfn)(fd, handler, channel);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
*id_addr=SPC_AddInput(fd, condition, id);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
void SPC_XtRemoveInput(int *id_addr,
|
||||
SPC_Callback_Condition condition)
|
||||
/*-----------------------------------------------------------------------+*/
|
||||
{
|
||||
if((*id_addr) != -1) {
|
||||
|
||||
switch(condition) {
|
||||
|
||||
case SPC_Input:
|
||||
case SPC_Terminator:
|
||||
case SPC_Client:
|
||||
/* fprintf(stderr, "SPC remove input/terminator\n"); */
|
||||
if (SbRemoveInput_hookfn == NULL)
|
||||
(void) fprintf (stderr, "Error: SbRemoveInput = NULL\n");
|
||||
else
|
||||
(*SbRemoveInput_hookfn)(SPC_RemoveInput(*id_addr, condition));
|
||||
break;
|
||||
|
||||
case SPC_Exception:
|
||||
/* fprintf(stderr, "SPC remove exception"); */
|
||||
if (SbRemoveException_hookfn == NULL)
|
||||
(void) fprintf (stderr, "Error: SbRemoveException = NULL\n");
|
||||
else
|
||||
(*SbRemoveException_hookfn)(SPC_RemoveInput(*id_addr, condition));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
*id_addr=(-1);
|
||||
}
|
||||
}
|
||||
860
cde/lib/DtSvc/DtEncap/spc.c
Normal file
860
cde/lib/DtSvc/DtEncap/spc.c
Normal file
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* File: spc.c $XConsortium: spc.c /main/6 1996/06/21 17:33:08 ageorge $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
#include <signal.h>
|
||||
#include <SPC/spcP.h>
|
||||
#include <SPC/spc-proto.h>
|
||||
#include <bms/spc.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/* spc.c */
|
||||
int SPC_Process_Single_Prot_Request (protocol_request_ptr req, SPC_Channel_Ptr channel);
|
||||
|
||||
|
||||
/* This is the SPC error number variable */
|
||||
/* extern int XeSPCErrorNumber; */
|
||||
|
||||
/* Externals */
|
||||
|
||||
extern int SPC_Initialized;
|
||||
extern SPC_Channel_Ptr spc_activation_list;
|
||||
extern SPC_Connection_Ptr connection_list;
|
||||
extern SPC_Connection_Ptr read_terminator;
|
||||
extern XeString official_hostname;
|
||||
|
||||
int max_fds = 0; /* Set up below. */
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void
|
||||
spc_init_fds(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if (!max_fds)
|
||||
# ifdef __bsd
|
||||
max_fds = getdtablesize();
|
||||
# else
|
||||
max_fds = (int)sysconf(_SC_OPEN_MAX);
|
||||
# endif
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Sub-Process Control access routines. These are just functional
|
||||
*** interfaces to the underlying methods.
|
||||
***
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr XeSPCOpen(XeString hostname,
|
||||
int iomode)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Attempt to open an SPC channel - return TRUE if we succeed */
|
||||
SPC_Channel_Ptr channel;
|
||||
|
||||
/* Check for initialization */
|
||||
_DtSvcProcessLock();
|
||||
if(!SPC_Initialized)
|
||||
if(SPC_Initialize() == SPC_ERROR) {
|
||||
_DtSvcProcessUnlock();
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/* The user specified iomode needs to be processed before we can use it.
|
||||
Process the puppy. */
|
||||
|
||||
iomode=SPC_Transform_Iomode(iomode);
|
||||
if(iomode==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* Get a new channel object */
|
||||
|
||||
channel=SPC_Initialize_Channel(hostname, iomode);
|
||||
|
||||
/* check that everything was okay */
|
||||
|
||||
if(channel==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* call the open method for it */
|
||||
|
||||
return((SPC_Channel_Ptr) mempf2(channel, open, iomode, hostname));
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCClose(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(IS_ACTIVE(channel))
|
||||
XeSPCKillProcess(channel, FALSE);
|
||||
|
||||
if(IS_SPCIO_DELAY_CLOSE(channel->IOMode)) {
|
||||
channel->IOMode |= SPCIO_DO_CLOSE;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
channel->IOMode &= ~SPCIO_DO_CLOSE;
|
||||
|
||||
return(mempf0(channel, close));
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCReset(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(IS_ACTIVE(channel))
|
||||
XeSPCKillProcess(channel, FALSE);
|
||||
|
||||
channel->IOMode &= ~SPCIO_ACTIVE;
|
||||
|
||||
if(mempf0(channel, reset)==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCRead(SPC_Channel_Ptr channel,
|
||||
int connector, /* STDOUT or STDERR */
|
||||
XeString buffer,
|
||||
int length)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
int n;
|
||||
|
||||
/* check for legal arguments */
|
||||
|
||||
if (channel==SPC_ERROR || !buffer ||
|
||||
!(connector==STDOUT || connector==STDERR) ||
|
||||
(length < 0)) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* check state of the channel */
|
||||
if (!IS_DATA(channel) || !IS_SPCIO_DATA(channel->wires[connector]->flags))
|
||||
return(0);
|
||||
|
||||
/* call the read filter */
|
||||
|
||||
do {
|
||||
n=(*channel->read_filter)(channel, connector, buffer, length);
|
||||
} while(n == (EXCEPT_FLAG));
|
||||
|
||||
/* Check for an error */
|
||||
|
||||
if (n == SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
return(n);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCWrite(SPC_Channel_Ptr channel,
|
||||
XeString buffer,
|
||||
int length)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int n;
|
||||
|
||||
/* check for legal arguments */
|
||||
|
||||
if (channel==SPC_ERROR || !buffer || (length<0)) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* check the state of the channel */
|
||||
|
||||
if(!IS_ACTIVE(channel)) {
|
||||
SPC_Error(SPC_Inactive_Channel);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* call the write method */
|
||||
|
||||
n=mempf2(channel, write, buffer, length);
|
||||
|
||||
return(n);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCActive(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if (channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* Is the passed channel active? */
|
||||
return (IS_ACTIVE(channel));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCData(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(IS_DATA(channel));
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCExecuteProcess(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(IS_ACTIVE(channel) || IS_DATA(channel)) {
|
||||
SPC_Error(SPC_Active_Channel);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if((retval=mempf0(channel, exec_proc))==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if (IS_SPCIO_WAIT(channel->IOMode)) {
|
||||
/* Wait for sub-process to finish */
|
||||
SPC_Wait_For_Termination(channel);
|
||||
}
|
||||
|
||||
return(retval);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCSignalProcess(SPC_Channel_Ptr channel,
|
||||
int sig)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if ((channel==SPC_ERROR) ||
|
||||
(channel->pid <= 0) ||
|
||||
(sig < 0)
|
||||
#ifdef NOT_IN_XPG3_YET
|
||||
|| (sig>=NSIG) /* Not a good idea for interoperability anyway */
|
||||
#endif
|
||||
) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* This routine does not check to see if the channel is active. */
|
||||
|
||||
return(mempf1(channel, signal, sig));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCAddInput(SPC_Channel_Ptr channel,
|
||||
SbInputHandlerProc handler,
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void * client_data)
|
||||
{
|
||||
if(!channel) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(!handler && !channel->Input_Handler)
|
||||
return(TRUE);
|
||||
|
||||
if(handler) {
|
||||
channel->Input_Handler = handler;
|
||||
channel->client_data = client_data;
|
||||
}
|
||||
|
||||
return(mempf2(channel, add_input, handler, client_data));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCRegisterTerminator(SPC_Channel_Ptr channel,
|
||||
SPC_TerminateHandlerType terminator,
|
||||
void * client_data)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Connection_Ptr conn;
|
||||
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* Okay. If we have a pty channel, we have to check that we
|
||||
have an input handler. I don't like doing this here, but ther
|
||||
are no methods for this routine, so it has to be done. */
|
||||
|
||||
if(IS_SPCIO_PTY(channel->IOMode) && !channel->Input_Handler) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
channel->IOMode |= SPCIO_SYNC_TERMINATOR;
|
||||
if(terminator) {
|
||||
channel->Terminate_Handler = terminator;
|
||||
channel->Terminate_Data = client_data;
|
||||
}
|
||||
|
||||
conn=SPC_Channel_Terminator_Connection(channel);
|
||||
if(conn->termination_id == -1)
|
||||
SPC_XtAddInput(channel, &conn->termination_id, conn->sid,
|
||||
SPC_Conditional_Packet_Handler, SPC_Terminator);
|
||||
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCAttach(SPC_Channel_Ptr channel,
|
||||
int pid)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
|
||||
{
|
||||
if(channel==SPC_ERROR || pid<=0) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(mempf1(channel, attach, pid));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCDetach(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(channel == SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
channel->pid = 0;
|
||||
channel->IOMode &= ~SPCIO_ACTIVE;
|
||||
|
||||
return XeSPCReset(channel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
***
|
||||
*** "Composite" functions -- Those which are defined in terms of the
|
||||
*** above primitives. One assumption is that the above primitives check
|
||||
*** their arguments, so the composite functions need only check any
|
||||
*** additional arguments.
|
||||
***
|
||||
*/
|
||||
|
||||
/*
|
||||
**
|
||||
** Start with subprocess creation routines
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCSpawn(XeString pathname,
|
||||
XeString context_dir,
|
||||
XeString *argv,
|
||||
XeString *envp,
|
||||
SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* Assign the command arguments to this channel and attempt to Execute */
|
||||
|
||||
if(channel->envp) {
|
||||
SPC_Free_Envp(channel->envp);
|
||||
channel->envp=NULL;
|
||||
}
|
||||
if(channel->argv && IS_SPCIO_DEALLOC_ARGV(channel->IOMode)) {
|
||||
SPC_Free_Envp(channel->argv);
|
||||
channel->IOMode &= ~SPCIO_DEALLOC_ARGV;
|
||||
channel->argv=NULL;
|
||||
}
|
||||
|
||||
channel->context_dir=context_dir;
|
||||
channel->argv = argv;
|
||||
channel->path = pathname;
|
||||
|
||||
channel->envp=SPC_Create_Default_Envp(channel->envp);
|
||||
channel->envp=SPC_Merge_Envp(channel->envp, envp);
|
||||
channel->envp=SPC_Fixup_Environment(channel->envp, channel);
|
||||
|
||||
if(IS_SPCIO_SYSTEM(channel->IOMode))
|
||||
if(SPC_MakeSystemCommand(channel)==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
/* Execute the process (XeSPCExecuteProcess will check arguments */
|
||||
|
||||
return(XeSPCExecuteProcess(channel));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr XeSPCOpenAndSpawn(XeString hostname,
|
||||
int iomode,
|
||||
XeString pathname,
|
||||
XeString context_dir,
|
||||
XeString *argv,
|
||||
XeString *envp)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* This simply wraps together the two steps: Open and Spawn */
|
||||
SPC_Channel_Ptr channel;
|
||||
|
||||
channel = XeSPCOpen(hostname, iomode);
|
||||
if(channel==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
|
||||
if (XeSPCSpawn(pathname, context_dir, argv, envp, channel)!=SPC_ERROR)
|
||||
return(channel);
|
||||
|
||||
/* Close the channel and return SPC_ERROR */
|
||||
XeSPCClose(channel);
|
||||
return(SPC_ERROR);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Signalling routines
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void
|
||||
XeSPCKillProcesses(int wait)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Attempt to KILL all the sub-process that we know of */
|
||||
SPC_Channel_Ptr spc;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
for (spc = spc_activation_list; spc != (SPC_Channel_Ptr) NULL; spc = spc->next)
|
||||
XeSPCKillProcess(spc, wait);
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCKillProcess(SPC_Channel_Ptr channel,
|
||||
int wait)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Attempt to KILL the sub-process (should we nullify the pid?) */
|
||||
int result;
|
||||
|
||||
if(!channel)
|
||||
return(FALSE);
|
||||
|
||||
if(IS_ACTIVE(channel)) {
|
||||
result = XeSPCSignalProcess(channel, SIGKILL);
|
||||
if(result==SPC_ERROR)
|
||||
return(SPC_ERROR);
|
||||
if (wait || IS_SPCIO_SYNC_TERM(channel->IOMode))
|
||||
SPC_Wait_For_Termination(channel);
|
||||
return result;
|
||||
} else
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCInterruptProcess(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Attempt to INTerrupt the sub-process */
|
||||
|
||||
return(XeSPCSignalProcess(channel, SIGINT));
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Process information routines.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeString XeSPCGetDevice(SPC_Channel_Ptr channel,
|
||||
int connector,
|
||||
int side)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(!channel) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/* Return the device name which corresponds to the side of a channel */
|
||||
if (connector>=STDIN && connector<=STDERR) {
|
||||
if (side == MASTER_SIDE)
|
||||
return(channel->wires[connector]->master_name);
|
||||
if (side == SLAVE_SIDE)
|
||||
return(channel->wires[connector]->slave_name);
|
||||
}
|
||||
|
||||
/* For no channel or incorrect side, return SPC_ERROR */
|
||||
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCGetProcessStatus(SPC_Channel_Ptr channel,
|
||||
int *type,
|
||||
int *cause)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
/* Fill in the type and cause of a process termination */
|
||||
int high, low;
|
||||
|
||||
if(!channel || !type || !cause) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
low = channel->status & WAIT_STATUS_MASK;
|
||||
high = (channel->status >> 8) & WAIT_STATUS_MASK;
|
||||
|
||||
*cause = high;
|
||||
|
||||
switch (low) {
|
||||
|
||||
case IS_WAIT_STATUS_STOPPED:
|
||||
*type = SPC_PROCESS_STOPPED;
|
||||
break;
|
||||
|
||||
case IS_WAIT_STATUS_EXITED:
|
||||
*type = SPC_PROCESS_EXITED;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!*cause) {
|
||||
*cause = low;
|
||||
*type = SPC_PROCESS_SIGNALLED;
|
||||
}
|
||||
break;
|
||||
|
||||
} /* End switch on status */
|
||||
|
||||
/* When a process is still active return FALSE */
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCGetPID(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(!channel) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
return (channel->pid);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int XeSPCGetLogfile(SPC_Channel_Ptr channel,
|
||||
XeString *host,
|
||||
XeString *file)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(!channel || !IS_SPCIO_USE_LOGFILE(channel->IOMode)) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
*file=channel->logfile;
|
||||
_DtSvcProcessLock();
|
||||
if(IS_REMOTE(channel))
|
||||
*host=channel->connection->hostname;
|
||||
else
|
||||
*host= official_hostname;
|
||||
_DtSvcProcessUnlock();
|
||||
return(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
int XeSPCRemoveLogfile(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
if(!channel) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(mempf0(channel, remove_logfile));
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Synchronous termination
|
||||
**
|
||||
*/
|
||||
|
||||
#define SINGLE_PROT_DATA(req, channel, connector) \
|
||||
if(!channel->queued_remote_data) \
|
||||
channel->queued_remote_data=Xe_make_queue(FALSE); \
|
||||
Xe_push_queue(channel->queued_remote_data, req); \
|
||||
if(channel->Input_Handler) { \
|
||||
SPC_Input_Handler(channel, connector); \
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** SPC_Process_Single_Prot_Request will return TRUE if it is okay
|
||||
** for the caller to free the protocol request.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Process_Single_Prot_Request(protocol_request_ptr req, SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
switch(req->request_type) {
|
||||
|
||||
case APPLICATION_DIED:
|
||||
|
||||
READ_APPLICATION_DIED(req->dataptr, channel->status);
|
||||
SPC_Channel_Terminated(channel);
|
||||
return(TRUE);
|
||||
|
||||
case APPLICATION_STDOUT:
|
||||
SINGLE_PROT_DATA(req, channel, STDOUT);
|
||||
return(FALSE);
|
||||
|
||||
case APPLICATION_STDERR:
|
||||
SINGLE_PROT_DATA(req, channel, STDERR);
|
||||
return(FALSE);
|
||||
|
||||
default:
|
||||
SPC_Error(SPC_Internal_Error);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPC_Channel_Ptr XeSPCHandleTerminator(int fd)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Connection_Ptr connection;
|
||||
SPC_Channel_Ptr channel;
|
||||
protocol_request_ptr prot;
|
||||
XeQueue connection_queue;
|
||||
|
||||
if(!(connection=SPC_Lookup_Connection_Fd(fd))) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
if(!(prot=SPC_Read_Protocol(connection))) {
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
connection_queue=connection->queued_remote_data;
|
||||
Xe_push_queue(connection_queue, prot);
|
||||
|
||||
while(prot=(protocol_request_ptr)Xe_pop_queue(connection_queue)) {
|
||||
|
||||
channel=prot->channel;
|
||||
|
||||
if(channel) {
|
||||
channel->IOMode |= SPCIO_DELAY_CLOSE;
|
||||
|
||||
if(SPC_Process_Single_Prot_Request(prot, channel))
|
||||
SPC_Free_Protocol_Ptr(prot);
|
||||
|
||||
channel->IOMode &= ~SPCIO_DELAY_CLOSE;
|
||||
if(IS_SPCIO_DO_CLOSE(channel->IOMode)) {
|
||||
XeSPCClose(channel);
|
||||
channel = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(channel);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Use this call to get the file descriptor for
|
||||
** Synchronous termination.
|
||||
**
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSPCGetChannelSyncFd(SPC_Channel_Ptr channel)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
SPC_Connection_Ptr conn;
|
||||
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
conn=SPC_Channel_Terminator_Connection(channel);
|
||||
return(conn->sid);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Error Handling routines.
|
||||
***
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
SPCError *XeSPCLookupError(int errnum)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
if(errnum<SPC_Min_Error || errnum > SPC_Max_Error) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(SPC_Lookup_Error(errnum));
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Temporarily shutdown input handlers
|
||||
***
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void XeSPCShutdownCallbacks(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Channel_Ptr channel;
|
||||
SPC_Connection_Ptr conn;
|
||||
Wire *wirelist;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
channel=spc_activation_list;
|
||||
conn=connection_list;
|
||||
|
||||
while(channel) {
|
||||
for(wirelist=channel->wire_list; wirelist; wirelist=wirelist->next) {
|
||||
if(wirelist->read_toolkit_id != -1)
|
||||
SPC_XtRemoveInput(&wirelist->read_toolkit_id, SPC_Input);
|
||||
if(wirelist->except_toolkit_id != -1)
|
||||
SPC_XtRemoveInput(&wirelist->except_toolkit_id, SPC_Exception);
|
||||
}
|
||||
channel=channel->next;
|
||||
}
|
||||
|
||||
while(conn) {
|
||||
if(conn->termination_id != -1)
|
||||
SPC_XtRemoveInput(&conn->termination_id, SPC_Terminator);
|
||||
conn=conn->next;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
void XeSPCRestartCallbacks(void)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
SPC_Channel_Ptr channel;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
channel=spc_activation_list;
|
||||
|
||||
while(channel) {
|
||||
if(channel->Input_Handler)
|
||||
XeSPCAddInput(channel, (SbInputHandlerProc)NULL, NULL);
|
||||
if(channel->Terminate_Handler)
|
||||
XeSPCRegisterTerminator(channel, NULL, NULL);
|
||||
channel=channel->next;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/*
|
||||
***
|
||||
*** Okay, now for a non-SPC routine. This one is dealing with setpgrp,
|
||||
*** but it is here because it uses internal SPC routines.
|
||||
***
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------+*/
|
||||
XeSetpgrp(int read_current_termio)
|
||||
/*----------------------------------------------------------------------+*/
|
||||
{
|
||||
|
||||
return(SPC_Setpgrp(read_current_termio));
|
||||
}
|
||||
|
||||
int XeSPCSendEOF(SPC_Channel_Ptr channel)
|
||||
{
|
||||
if(channel==SPC_ERROR) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(mempf0(channel, send_eof));
|
||||
}
|
||||
|
||||
int XeSPCSetTermio(SPC_Channel_Ptr channel, int connection, int side,
|
||||
struct termios *termio)
|
||||
{
|
||||
if(channel==SPC_ERROR || termio == NULL) {
|
||||
SPC_Error(SPC_Bad_Argument);
|
||||
return(SPC_ERROR);
|
||||
}
|
||||
|
||||
return(mempf3(channel, set_termio, connection, side, termio));
|
||||
}
|
||||
|
||||
133
cde/lib/DtSvc/DtEncap/stringbuf.c
Normal file
133
cde/lib/DtSvc/DtEncap/stringbuf.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* File: stringbuf.c $XConsortium: stringbuf.c /main/3 1995/10/26 15:41:59 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <bms/bms.h>
|
||||
#include <bms/stringbuf.h> /* public declarations */
|
||||
#include <bms/MemoryMgr.h> /* Xe_make_struct ... */
|
||||
|
||||
/* Forwards */
|
||||
static int ExpandStringBuffer (XeStringBuffer buffer);
|
||||
|
||||
#ifndef DEBUG
|
||||
# define DEBUG 0
|
||||
#endif
|
||||
|
||||
#define EXPANSION_FACTOR 4
|
||||
|
||||
/**
|
||||
BUFFER_MIN_SIZE was chosen to be 16 so
|
||||
BUFSIZE % EXPANSION_FACTOR > 0
|
||||
and
|
||||
(BUFSIZE + (BUFSIZE % EXPANSION_FACTOR)) % EXPANSION_FACTOR
|
||||
> (BUFSIZE % EXPANSION_FACTOR)
|
||||
**/
|
||||
|
||||
#define BUFFER_MIN_SIZE 16
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
static int
|
||||
ExpandStringBuffer(XeStringBuffer buffer)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
int new_size = buffer->size + buffer->increment;
|
||||
XeString new_string = Xe_make_ntype(new_size, XeChar);
|
||||
|
||||
# if DEBUG >= 3
|
||||
sprintf(debug_string, "expanding string buffer. current size is: %d", buffer->size);
|
||||
print_debug_info(3, debug_string);
|
||||
# endif
|
||||
|
||||
memcpy(new_string, buffer->buffer, buffer->last_char + 1);
|
||||
XeFree(buffer->buffer);
|
||||
buffer->size = new_size;
|
||||
buffer->buffer = new_string;
|
||||
buffer->increment += (buffer->increment % EXPANSION_FACTOR);
|
||||
# if DEBUG >= 3
|
||||
sprintf(debug_string, "new size is: %d", buffer->size);
|
||||
print_debug_info(4, debug_string);
|
||||
# endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
int
|
||||
XeAppendToStringBuffer(XeStringBuffer buffer, XeString string)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
int size = buffer->size;
|
||||
XeString buffer_position; /* so operations are pointer based */
|
||||
int i;
|
||||
|
||||
# if DEBUG >= 5
|
||||
sprintf(debug_string, "appending: \"%s\" to: \"%s\"", string, buffer->buffer);
|
||||
print_debug_info(5, debug_string);
|
||||
# endif
|
||||
|
||||
if (!(string && string[0])) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
buffer_position = &(buffer->buffer[buffer->last_char]);
|
||||
for (i = buffer->last_char; *string ; i++) {
|
||||
if (i == size) {
|
||||
buffer->last_char = i - 1;
|
||||
if (-1 == ExpandStringBuffer(buffer)) return(-1);
|
||||
size = buffer->size;
|
||||
buffer_position = &(buffer->buffer[i]);
|
||||
}
|
||||
*buffer_position++ = *string++;
|
||||
}
|
||||
if (i == size) {
|
||||
buffer->last_char = i - 1;
|
||||
if (-1 == ExpandStringBuffer(buffer)) return(-1);
|
||||
}
|
||||
buffer->buffer[i] = (XeChar) NULL;
|
||||
buffer->last_char = i;
|
||||
# if DEBUG >= 5
|
||||
sprintf(debug_string, "new string is: \"%s\"", buffer->buffer);
|
||||
print_debug_info(6, debug_string);
|
||||
# endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
void
|
||||
XeClearStringBuffer(XeStringBuffer buffer)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeString string = buffer->buffer;
|
||||
string[0] = (XeChar) NULL;
|
||||
buffer->last_char = 0;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------+*/
|
||||
XeStringBuffer
|
||||
XeMakeStringBuffer(int increment_size)
|
||||
/*------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeStringBuffer new_buffer;
|
||||
increment_size = (increment_size > BUFFER_MIN_SIZE)
|
||||
? increment_size
|
||||
: BUFFER_MIN_SIZE;
|
||||
|
||||
new_buffer = Xe_make_struct(_XeStringBuffer);
|
||||
new_buffer->buffer = Xe_make_ntype(increment_size, XeChar);
|
||||
new_buffer->increment = increment_size;
|
||||
new_buffer->size = increment_size;
|
||||
XeClearStringBuffer(new_buffer);
|
||||
return(new_buffer);
|
||||
}
|
||||
245
cde/lib/DtSvc/DtEncap/usersig.c
Normal file
245
cde/lib/DtSvc/DtEncap/usersig.c
Normal file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* File: usersig.c $XConsortium: usersig.c /main/4 1996/06/21 17:33:04 ageorge $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#define __need_all_signals
|
||||
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <bms/bms.h>
|
||||
#include <bms/Symbolic.h>
|
||||
#include <bms/usersig.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
static XeSymTable Xe_sig_table = (XeSymTable) NULL;
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
static void Xe_addsig(XeString name, int value)
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
{
|
||||
XeSymbol sym = Xe_intern(Xe_sig_table, name);
|
||||
sym->value = (void *)value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
static void Xe_init_sig_table(void)
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
{
|
||||
# define SIG_HASH_SIZE 32
|
||||
|
||||
_DtSvcProcessLock();
|
||||
Xe_sig_table = Xe_new_symtab(SIG_HASH_SIZE);
|
||||
|
||||
Xe_addsig((XeString)"SIGABRT", SIGABRT); /* Add the XOPEN XPG3 signals */
|
||||
Xe_addsig((XeString)"SIGALRM", SIGALRM);
|
||||
Xe_addsig((XeString)"SIGFPE", SIGFPE);
|
||||
Xe_addsig((XeString)"SIGHUP", SIGHUP);
|
||||
Xe_addsig((XeString)"SIGILL", SIGILL);
|
||||
Xe_addsig((XeString)"SIGINT", SIGINT);
|
||||
Xe_addsig((XeString)"SIGKILL", SIGKILL);
|
||||
Xe_addsig((XeString)"SIGPIPE", SIGPIPE);
|
||||
Xe_addsig((XeString)"SIGQUIT", SIGQUIT);
|
||||
Xe_addsig((XeString)"SIGSEGV", SIGSEGV);
|
||||
Xe_addsig((XeString)"SIGTERM", SIGTERM);
|
||||
Xe_addsig((XeString)"SIGUSR1", SIGUSR1);
|
||||
Xe_addsig((XeString)"SIGUSR2", SIGUSR2);
|
||||
Xe_addsig((XeString)"SIGCHLD", SIGCHLD);
|
||||
Xe_addsig((XeString)"SIGCONT", SIGCONT);
|
||||
Xe_addsig((XeString)"SIGSTOP", SIGSTOP);
|
||||
Xe_addsig((XeString)"SIGTSTP", SIGTSTP);
|
||||
Xe_addsig((XeString)"SIGTTIN", SIGTTIN);
|
||||
Xe_addsig((XeString)"SIGTTOU", SIGTTOU);
|
||||
|
||||
/* 0 is a valid XPG3 signal, but it doesn't have a name. */
|
||||
|
||||
Xe_addsig((XeString)"ZERO", 0);
|
||||
|
||||
/* Now add signals that may or may not be around on a given platform */
|
||||
|
||||
# ifdef SIGIO
|
||||
Xe_addsig((XeString)"SIGIO", SIGIO); /* hpux sun apollo */
|
||||
# else
|
||||
# ifdef SIGPOLL
|
||||
Xe_addsig((XeString)"SIGIO", SIGPOLL); /* hpux sun apollo */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef SIGPOLL
|
||||
Xe_addsig((XeString)"SIGPOLL", SIGPOLL); /* hpux sun apollo */
|
||||
# else
|
||||
# ifdef SIGIO
|
||||
Xe_addsig((XeString)"SIGPOLL", SIGIO); /* hpux sun apollo */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef SIGEMT
|
||||
Xe_addsig((XeString)"SIGEMT", SIGEMT); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGBUS
|
||||
Xe_addsig((XeString)"SIGBUS", SIGBUS); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGIOT
|
||||
Xe_addsig((XeString)"SIGIOT", SIGIOT); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGURG
|
||||
Xe_addsig((XeString)"SIGURG", SIGURG); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGSYS
|
||||
Xe_addsig((XeString)"SIGSYS", SIGSYS); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGTRAP
|
||||
Xe_addsig((XeString)"SIGTRAP", SIGTRAP); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGPROF
|
||||
Xe_addsig((XeString)"SIGPROF", SIGPROF); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGCLD
|
||||
Xe_addsig((XeString)"SIGCLD", SIGCLD); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGVTALRM
|
||||
Xe_addsig((XeString)"SIGVTALRM", SIGVTALRM); /* hpux sun apollo */
|
||||
# endif
|
||||
|
||||
# ifdef SIGWINCH
|
||||
Xe_addsig((XeString)"SIGWINCH", SIGWINCH);
|
||||
# endif
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
int XeNameToSignal(XeString name)
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
|
||||
/* Return SIG_NOT_IN_TABLE if signal name is not in hash table */
|
||||
|
||||
{
|
||||
XeSymbol sym;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (!Xe_sig_table) Xe_init_sig_table();
|
||||
|
||||
sym = Xe_lookup(Xe_sig_table, name);
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return (sym) ? (int) sym->value : XE_SIG_NOT_IN_TABLE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
XeString XeSignalToName(int sig)
|
||||
/*-------------------------------------------------------------------------+*/
|
||||
{
|
||||
switch (sig)
|
||||
{
|
||||
/* These are XOPEN XPG3 signals */
|
||||
/* ---------------------------- */
|
||||
case SIGABRT: return (XeString)"SIGABRT"; /* "SIGIOT" is an alias */
|
||||
case SIGALRM: return (XeString)"SIGALRM";
|
||||
case SIGFPE: return (XeString)"SIGFPE";
|
||||
case SIGHUP: return (XeString)"SIGHUP";
|
||||
case SIGILL: return (XeString)"SIGILL";
|
||||
case SIGINT: return (XeString)"SIGINT";
|
||||
case SIGKILL: return (XeString)"SIGKILL";
|
||||
case SIGPIPE: return (XeString)"SIGPIPE";
|
||||
case SIGQUIT: return (XeString)"SIGQUIT";
|
||||
case SIGSEGV: return (XeString)"SIGSEGV";
|
||||
case SIGTERM: return (XeString)"SIGTERM";
|
||||
case SIGUSR1: return (XeString)"SIGUSR1";
|
||||
case SIGUSR2: return (XeString)"SIGUSR2";
|
||||
case SIGCHLD: return (XeString)"SIGCHLD"; /* "SIGCLD" is an alias */
|
||||
case SIGCONT: return (XeString)"SIGCONT";
|
||||
case SIGSTOP: return (XeString)"SIGSTOP";
|
||||
case SIGTSTP: return (XeString)"SIGTSTP";
|
||||
case SIGTTIN: return (XeString)"SIGTTIN";
|
||||
case SIGTTOU: return (XeString)"SIGTTOU";
|
||||
|
||||
/* 0 is a valid signal under XPG3, but it doesn't have a signal name */
|
||||
|
||||
case 0: return (XeString)"ZERO";
|
||||
|
||||
|
||||
/* NOTE: we have ifdef's for cases that are duplicated by other values */
|
||||
/* included but contain no code. This is so when you compare this */
|
||||
/* code to the stuff in Xe_init_sig_table() above, you see a one */
|
||||
/* to one correspondance. */
|
||||
|
||||
# ifdef SIGIO /* hpux sun apollo */
|
||||
/* (SIGPOLL, SIGTINT are aliases) */
|
||||
case SIGIO: return (XeString)"SIGIO";
|
||||
# endif
|
||||
|
||||
# ifdef SIGPOLL /* hpux sun apollo */
|
||||
/* ----> Duplicated by SIGIO above
|
||||
case SIGPOLL: return (XeString)"SIGPOLL";
|
||||
*/
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef SIGEMT /* hpux sun apollo */
|
||||
case SIGEMT: return (XeString)"SIGEMT";
|
||||
# endif
|
||||
|
||||
# ifdef SIGBUS /* hpux sun apollo */
|
||||
case SIGBUS: return (XeString)"SIGBUS";
|
||||
# endif
|
||||
|
||||
# ifdef SIGIOT /* hpux sun apollo */
|
||||
/* ----> Duplicated by SIGABRT above
|
||||
|
||||
case SIGIOT: return (XeString)"SIGIOT";
|
||||
*/
|
||||
# endif
|
||||
|
||||
# ifdef SIGURG /* hpux sun apollo */
|
||||
case SIGURG: return (XeString)"SIGURG";
|
||||
# endif
|
||||
|
||||
# ifdef SIGSYS /* hpux sun apollo */
|
||||
case SIGSYS: return (XeString)"SIGSYS";
|
||||
# endif
|
||||
|
||||
# ifdef SIGTRAP /* hpux sun apollo */
|
||||
case SIGTRAP: return (XeString)"SIGTRAP";
|
||||
# endif
|
||||
|
||||
# ifdef SIGPROF /* hpux sun apollo */
|
||||
case SIGPROF: return (XeString)"SIGPROF";
|
||||
# endif
|
||||
|
||||
# ifdef SIGCLD /* hpux sun apollo */
|
||||
/* ----> Duplicated by SIGCHLD above
|
||||
case SIGCLD: return (XeString)"SIGCLD";
|
||||
*/
|
||||
# endif
|
||||
|
||||
# ifdef SIGVTALRM /* hpux sun apollo */
|
||||
case SIGVTALRM: return (XeString)"SIGVTALRM";
|
||||
# endif
|
||||
|
||||
# ifdef SIGWINCH /* sun apollo */
|
||||
case SIGWINCH: return (XeString)"SIGWINCH";
|
||||
# endif
|
||||
|
||||
|
||||
default: return XeString_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
5443
cde/lib/DtSvc/DtUtil1/Action.c
Normal file
5443
cde/lib/DtSvc/DtUtil1/Action.c
Normal file
File diff suppressed because it is too large
Load Diff
117
cde/lib/DtSvc/DtUtil1/Action.h
Normal file
117
cde/lib/DtSvc/DtUtil1/Action.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* $TOG: Action.h /main/4 1998/05/06 15:55:18 rafi $ */
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _Dt_Action_h
|
||||
#define _Dt_Action_h
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Argument types
|
||||
*/
|
||||
|
||||
#define DtACTION_FILE 1 /* file argument */
|
||||
#define DtACTION_BUFFER 2 /* buffer argument */
|
||||
#define DtACTION_STRING 3 /* string argument */
|
||||
#define DtACTION_NULLARG 4 /* untyped return-only argument */
|
||||
|
||||
typedef struct {
|
||||
void *bp; /* location of buffer */
|
||||
int size; /* size of buffer in bytes */
|
||||
char *type; /* (opt.) type of buffer */
|
||||
char *name; /* (opt.) name of buffer object */
|
||||
Boolean writable; /* allow changes to buffer object? */
|
||||
} DtActionBuffer;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
} DtActionFile;
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Structure containing argument information
|
||||
*/
|
||||
int argClass; /* see argument types */
|
||||
union {
|
||||
DtActionFile file;
|
||||
DtActionBuffer buffer;
|
||||
} u;
|
||||
} DtActionArg;
|
||||
|
||||
/*
|
||||
* DtActionStatus codes
|
||||
*/
|
||||
typedef enum {
|
||||
DtACTION_OK, /* If not any of the below */
|
||||
DtACTION_INVALID_ID, /* ID is not valid */
|
||||
DtACTION_INVOKED, /* the action invocation step is done */
|
||||
DtACTION_STATUS_UPDATE, /* status update */
|
||||
DtACTION_DONE, /* normal action termination code */
|
||||
DtACTION_FAILED, /* error running action */
|
||||
DtACTION_CANCELED /* normal action termination by cancel*/
|
||||
} DtActionStatus;
|
||||
|
||||
typedef void (*DtDbReloadCallbackProc)(
|
||||
XtPointer clientData);
|
||||
|
||||
/*
|
||||
* DtActionInvocationID is the fundamental user-space handle to invoked
|
||||
* actions.
|
||||
*/
|
||||
typedef unsigned long DtActionInvocationID;
|
||||
|
||||
typedef void (*DtActionCallbackProc) (
|
||||
DtActionInvocationID id,
|
||||
XtPointer client_data,
|
||||
DtActionArg *actionArgPtr,
|
||||
int actionArgCount,
|
||||
DtActionStatus status);
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern Boolean DtActionExists(
|
||||
char *actionName);
|
||||
|
||||
extern char * DtActionLabel(
|
||||
char *actionName);
|
||||
|
||||
extern char * DtActionDescription(
|
||||
char *actionName);
|
||||
|
||||
extern void DtDbReloadNotify (
|
||||
DtDbReloadCallbackProc proc,
|
||||
XtPointer clientData);
|
||||
|
||||
extern void DtDbLoad(void);
|
||||
|
||||
extern DtActionInvocationID DtActionInvoke (
|
||||
Widget w,
|
||||
char *action,
|
||||
DtActionArg *args,
|
||||
int argCount,
|
||||
char *termOpts,
|
||||
char *execHost,
|
||||
char *contextDir,
|
||||
int useIndicator,
|
||||
DtActionCallbackProc statusUpdateCb,
|
||||
XtPointer client_data);
|
||||
|
||||
extern char * DtActionIcon(
|
||||
char *actionName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_Action_h */
|
||||
1247
cde/lib/DtSvc/DtUtil1/ActionDb.c
Normal file
1247
cde/lib/DtSvc/DtUtil1/ActionDb.c
Normal file
File diff suppressed because it is too large
Load Diff
219
cde/lib/DtSvc/DtUtil1/ActionDb.h
Normal file
219
cde/lib/DtSvc/DtUtil1/ActionDb.h
Normal file
@@ -0,0 +1,219 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File: ActionDb.h
|
||||
* RCS: $XConsortium: ActionDb.h /main/3 1995/10/26 14:58:38 rswiston $
|
||||
* Description: Internal header file for the action database functions.
|
||||
* Language: C
|
||||
* Package: N/A
|
||||
* Status: Experimental (Do Not Distribute)
|
||||
*
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _Dt_ActionDb_h
|
||||
#define _Dt_ActionDb_h
|
||||
|
||||
|
||||
/*
|
||||
* The following constants are used by the database parsing code to
|
||||
* identify the field names for an action definition.
|
||||
*
|
||||
* Recognized Field names for any action definition.
|
||||
*/
|
||||
#define _DtACTION_NAME "ACTION"
|
||||
#define _DtACTION_TYPE "TYPE"
|
||||
#define _DtACTION_LABEL "LABEL"
|
||||
#define _DtACTION_ARG_CLASS "ARG_CLASS"
|
||||
#define _DtACTION_ARG_MODE "ARG_MODE"
|
||||
#define _DtACTION_ARG_TYPE "ARG_TYPE"
|
||||
#define _DtACTION_ARG_COUNT "ARG_COUNT"
|
||||
#define _DtACTION_DESCRIPTION "DESCRIPTION"
|
||||
#define _DtACTION_ICON "ICON"
|
||||
#define _DtACTION_INSTANCE_ICON "INSTANCE_ICON"
|
||||
|
||||
/*
|
||||
* Miscellaneous syntax strings
|
||||
*/
|
||||
#define _DtACT_ANY "*"
|
||||
#define _DtACT_LIST_SEPARATOR_CHAR ','
|
||||
#define _DtACT_GT_CHAR '>'
|
||||
#define _DtACT_LT_CHAR '<'
|
||||
|
||||
|
||||
/*
|
||||
* Valid values for ACTION_TYPE
|
||||
*/
|
||||
#define _DtACTION_MAP "MAP"
|
||||
#define _DtACTION_COMMAND "COMMAND"
|
||||
#define _DtACTION_TT_MSG "TT_MSG"
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
|
||||
#define _DtACTION_DT_REQUEST "DT_REQUEST"
|
||||
#define _DtACTION_DT_NOTIFY "DT_NOTIFY"
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
/*
|
||||
* Field names for "MAP" type actions
|
||||
*/
|
||||
|
||||
#define _DtACTION_MAP_ACTION "MAP_ACTION"
|
||||
|
||||
/*
|
||||
* Field names for the "COMMAND" type actions.
|
||||
*/
|
||||
#define _DtACTION_EXEC_STRING "EXEC_STRING"
|
||||
#define _DtACTION_EXEC_HOST "EXEC_HOST"
|
||||
#define _DtACTION_CWD "CWD"
|
||||
#define _DtACTION_WINDOW_TYPE "WINDOW_TYPE"
|
||||
#define _DtACTION_TERM_OPTS "TERM_OPTS"
|
||||
|
||||
/*
|
||||
* Field names for "TT_MSG" type actions
|
||||
*/
|
||||
#define _DtACTION_TT_CLASS "TT_CLASS"
|
||||
#define _DtACTION_TT_SCOPE "TT_SCOPE"
|
||||
#define _DtACTION_TT_OPERATION "TT_OPERATION"
|
||||
#define _DtACTION_TT_FILE "TT_FILE"
|
||||
/* definitions to decifer TT_ARGn_* fields */
|
||||
#define _DtACTION_TTN_ARG "TT_ARG"
|
||||
#define _DtACTION_TTN_MODE "_MODE"
|
||||
#define _DtACTION_TTN_VTYPE "_VTYPE"
|
||||
#define _DtACTION_TTN_REP_TYPE "_REP_TYPE"
|
||||
#define _DtACTION_TTN_VALUE "_VALUE"
|
||||
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
/*
|
||||
* Field names for "DT_REQUEST" type actions
|
||||
*/
|
||||
#define _DtACTION_DT_REQUEST_NAME "DT_REQUEST_NAME"
|
||||
#define _DtACTION_DT_SVC "DT_SVC"
|
||||
|
||||
/*
|
||||
* Field names for "DT_NOTIFY" type actions
|
||||
*/
|
||||
#define _DtACTION_DT_NOTIFY_NAME "DT_NOTIFY_NAME"
|
||||
#define _DtACTION_DT_NGROUP "DT_NGROUP"
|
||||
|
||||
/*
|
||||
* Field names for DT ARGn (either request or notify)
|
||||
*/
|
||||
#define _DtACTION_DTN_ARG "DT_ARG"
|
||||
#define _DtACTION_DTN_VALUE "_VALUE"
|
||||
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
/*
|
||||
* Valid Field value strings
|
||||
* for Command Actions Window Types
|
||||
*/
|
||||
#define _DtACTION_TERMINAL "TERMINAL"
|
||||
#define _DtACTION_PERM_TERMINAL "PERM_TERMINAL"
|
||||
#define _DtACTION_NO_STDIO "NO_STDIO"
|
||||
|
||||
/*
|
||||
* Valid Field values for ARG_CLASS records.
|
||||
*/
|
||||
#define _DtACTION_BUFFER "BUFFER"
|
||||
#define _DtACTION_FILE "FILE"
|
||||
#define _DtACTION_STRING "STRING"
|
||||
|
||||
/*
|
||||
* Valid Field values for ARG_MODE
|
||||
*/
|
||||
|
||||
#define _DtACT_ARG_MODE_WRITE "w"
|
||||
#define _DtACT_ARG_MODE_NOWRITE "!w"
|
||||
#define _DtACT_ARG_MODE_ANY _DtACT_ANY
|
||||
|
||||
|
||||
/*
|
||||
* Valid Field values for TT_CLASS records.
|
||||
*/
|
||||
#define _DtACTION_TT_NOTICE "TT_NOTICE"
|
||||
#define _DtACTION_TT_REQUEST "TT_REQUEST"
|
||||
|
||||
/*
|
||||
* Valid Field values for TT_SCOPE records.
|
||||
*/
|
||||
#define _DtACTION_TT_SESSION "TT_SESSION"
|
||||
#define _DtACTION_TT_BOTH "TT_BOTH"
|
||||
#define _DtACTION_TT_FILE_IN_SESSION "TT_FILE_IN_SESSION"
|
||||
/* --- same as TT_MSG's TT_FILE field name --------
|
||||
#define _DtACTION_TT_FILE "TT_FILE"
|
||||
*/
|
||||
|
||||
/*
|
||||
* Valid Field values for TT_ARGn_MODE
|
||||
*/
|
||||
#define _DtACTION_TT_MODE_IN "TT_IN"
|
||||
#define _DtACTION_TT_MODE_OUT "TT_OUT"
|
||||
#define _DtACTION_TT_MODE_INOUT "TT_INOUT"
|
||||
|
||||
/*
|
||||
* Valid Field values for TT_ARGn_REP_TYPE
|
||||
*/
|
||||
#define _DtACTION_TT_RTYP_UND "TT_REP_UNDEFINED"
|
||||
#define _DtACTION_TT_RTYP_INT "TT_REP_INTEGER"
|
||||
#define _DtACTION_TT_RTYP_BUF "TT_REP_BUFFER"
|
||||
#define _DtACTION_TT_RTYP_STR "TT_REP_STRING"
|
||||
|
||||
/*
|
||||
* Action Keywords --
|
||||
* these keywords appear in the action database files
|
||||
* in the form: %<qualifier><keyword><prompt string>%
|
||||
* where the optional qualifier in enclosed in: ()
|
||||
* and the optional prompt string is enclosed in: ""
|
||||
*/
|
||||
#define _DtACT_DATABASEHOST_STR "DatabaseHost"
|
||||
#define _DtACT_DISPLAYHOST_STR "DisplayHost"
|
||||
#define _DtACT_LOCALHOST_STR "LocalHost"
|
||||
#define _DtACT_SESSIONHOST_STR "SessionHost"
|
||||
#define _DtACT_ARGS_STR "Args"
|
||||
#define _DtACT_ARG_UNDER_STR "Arg_"
|
||||
|
||||
#define _DtACT_STRING_QUALIFIER "(String)"
|
||||
#define _DtACT_FILE_QUALIFIER "(File)"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Default action field value definitions (these should be strings)
|
||||
* for recognized fields.
|
||||
*/
|
||||
#define _DtACT_LBL_DFLT NULL
|
||||
#define _DtACT_TYPE_DFLT _DtACTION_COMMAND
|
||||
#define _DtACT_ARG_CLASS_DFLT _DtACT_ANY
|
||||
#define _DtACT_ARG_MODE_DFLT _DtACT_ANY
|
||||
#define _DtACT_ARG_TYPE_DFLT _DtACT_ANY
|
||||
#define _DtACT_ARG_CNT_DFLT _DtACT_ANY
|
||||
#define _DtACT_DESC_DFLT NULL
|
||||
#define _DtACT_ICON_DFLT NULL
|
||||
#define _DtACT_MAP_ACT_DFLT NULL
|
||||
#define _DtACT_EXEC_STRG_DFLT NULL
|
||||
#define _DtACT_EXEC_HOST_DFLT \
|
||||
"%" _DtACT_DATABASEHOST_STR "%,%" _DtACT_LOCALHOST_STR "%"
|
||||
#define _DtACT_CWD_DFLT NULL
|
||||
#define _DtACT_WIN_TYPE_DFLT _DtACTION_PERM_TERMINAL
|
||||
#define _DtACT_TERM_OPTS_DFLT NULL
|
||||
#define _DtACT_TT_CLASS_DFLT NULL
|
||||
#define _DtACT_TT_SCOPE_DFLT NULL
|
||||
#define _DtACT_TT_OP_DFLT NULL
|
||||
#define _DtACT_TT_FILE_DFLT NULL
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define _DtACT_DT_REQ_DFLT NULL
|
||||
#define _DtACT_DT_SVC_DFLT NULL
|
||||
#define _DtACT_DT_NTFY_DFLT NULL
|
||||
#define _DtACT_DT_NGRP_DFLT NULL
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
|
||||
|
||||
#endif /* _Dt_ActionDb_h */
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
121
cde/lib/DtSvc/DtUtil1/ActionDbP.h
Normal file
121
cde/lib/DtSvc/DtUtil1/ActionDbP.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File: ActionDbP.h
|
||||
* RCS: $XConsortium: ActionDbP.h /main/3 1995/10/26 14:58:53 rswiston $
|
||||
* Description: Private header file for the action database functions.
|
||||
* Language: C
|
||||
* Package: N/A
|
||||
*
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _Dt_ActionDbP_h
|
||||
#define _Dt_ActionDbP_h
|
||||
|
||||
#include <Dt/DbReader.h>
|
||||
#include <Dt/ActionDb.h>
|
||||
|
||||
#define _DtMAX_NUM_FIELDS 30
|
||||
#define _ActDb_MAX_NUM_FIELDS _DtMAX_NUM_FIELDS
|
||||
|
||||
|
||||
/*
|
||||
* Bitmask field definitions for the action converter bit mask.
|
||||
* These are NOT the bits for the mask in struct ACTION.
|
||||
*/
|
||||
|
||||
#define _ActDb_LABEL_SET (1<<0)
|
||||
#define _ActDb_TYPE_SET (1<<1)
|
||||
#define _ActDb_ARG_CLASS_SET (1<<2)
|
||||
#define _ActDb_ARG_TYPE_SET (1<<3)
|
||||
#define _ActDb_ARG_COUNT_SET (1<<4)
|
||||
#define _ActDb_ARG_MODE_SET (1<<5)
|
||||
#define _ActDb_DESCRIPTION_SET (1<<6)
|
||||
#define _ActDb_ICON_SET (1<<7)
|
||||
|
||||
#define _ActDb_MAP_ACTION_SET (1<<10)
|
||||
|
||||
#define _ActDb_EXEC_STRING_SET (1<<12)
|
||||
#define _ActDb_EXEC_HOST_SET (1<<13)
|
||||
#define _ActDb_CWD_SET (1<<14)
|
||||
#define _ActDb_WINDOW_TYPE_SET (1<<15)
|
||||
#define _ActDb_TERM_OPTS_SET (1<<16)
|
||||
|
||||
#define _ActDb_TT_CLASS_SET (1<<18)
|
||||
#define _ActDb_TT_SCOPE_SET (1<<19)
|
||||
#define _ActDb_TT_OPERATION_SET (1<<20)
|
||||
#define _ActDb_TT_FILE_SET (1<<21)
|
||||
#define _ActDb_TT_ARGN_MODE_SET (1<<22)
|
||||
#define _ActDb_TT_ARGN_VTYP_SET (1<<23)
|
||||
#define _ActDb_TT_ARGN_RTYP_SET (1<<24)
|
||||
#define _ActDb_TT_ARGN_VAL_SET (1<<25)
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define _ActDb_DT_REQ_NAME_SET (1<<26)
|
||||
#define _ActDb_DT_SVC_SET (1<<27)
|
||||
|
||||
#define _ActDb_DT_NTFY_NAME_SET (1<<28)
|
||||
#define _ActDb_DT_NGROUP_SET (1<<29)
|
||||
#define _ActDb_DT_ARGN_VAL_SET (1<<30)
|
||||
/* no mask for ARGn strings */
|
||||
|
||||
|
||||
#define _ActDb_DT_REQUEST_BITS ( _ActDb_DT_REQ_NAME_SET \
|
||||
| _ActDb_DT_SVC_SET )
|
||||
#define _ActDb_DT_NOTIFY_BITS ( _ActDb_DT_NTFY_NAME_SET \
|
||||
| _ActDb_DT_NGROUP_SET )
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
#define _ActDb_TT_BITS ( _ActDb_TT_CLASS_SET \
|
||||
| _ActDb_TT_SCOPE_SET \
|
||||
| _ActDb_TT_OPERATION_SET \
|
||||
| _ActDb_TT_ARGN_MODE_SET \
|
||||
| _ActDb_TT_ARGN_VTYP_SET \
|
||||
| _ActDb_TT_ARGN_RTYP_SET \
|
||||
| _ActDb_TT_ARGN_VAL_SET \
|
||||
| _ActDb_TT_FILE_SET )
|
||||
#define _ActDb_CMD_BITS ( _ActDb_EXEC_STRING_SET \
|
||||
| _ActDb_CWD_SET \
|
||||
| _ActDb_WINDOW_TYPE_SET \
|
||||
| _ActDb_TERM_OPTS_SET )
|
||||
#define _ActDb_MAP_BITS ( _ActDb_MAP_ACTION_SET )
|
||||
|
||||
#define _ActDb_TT_ARGN_BITS ( _ActDb_TT_ARGN_MODE_SET \
|
||||
| _ActDb_TT_ARGN_VTYP_SET \
|
||||
| _ActDb_TT_ARGN_RTYP_SET \
|
||||
| _ActDb_TT_ARGN_VAL_SET )
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define _ActDb_ARGN_BITS ( _ActDb_TT_ARGN_BITS \
|
||||
| _ActDb_DT_ARGN_VAL_SET )
|
||||
#else
|
||||
#define _ActDb_ARGN_BITS ( _ActDb_TT_ARGN_BITS )
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Private (but external) entry points for internal use by Action Database
|
||||
* Library code only.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
|
||||
extern Boolean _DtActionConverter( DtDtsDbField *fields,
|
||||
DtDbPathId pathId,
|
||||
char *hostPrefix,
|
||||
Boolean rejectionStatus);
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
#endif /* _Dt_ActionDbP_h */
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
2371
cde/lib/DtSvc/DtUtil1/ActionFind.c
Normal file
2371
cde/lib/DtSvc/DtUtil1/ActionFind.c
Normal file
File diff suppressed because it is too large
Load Diff
45
cde/lib/DtSvc/DtUtil1/ActionFind.h
Normal file
45
cde/lib/DtSvc/DtUtil1/ActionFind.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* $XConsortium: ActionFind.h /main/4 1995/10/26 14:59:41 rswiston $ */
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: ActionFind.h
|
||||
**
|
||||
** Project: DT
|
||||
**
|
||||
** Description: Public include file for the ActionFind functions.
|
||||
**
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
|
||||
#ifndef _Dt_ActionFind_h
|
||||
#define _Dt_ActionFind_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
#include <Dt/ActionP.h>
|
||||
#include <Dt/DtsDb.h>
|
||||
#include <Dt/DtsMM.h>
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
extern void _DtSortActionDb(void);
|
||||
extern ActionPtr
|
||||
_DtActionFindDBEntry( ActionRequest *reqp,
|
||||
DtShmBoson actQuark );
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
#endif /* _Dt_ActionFind_h */
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
|
||||
827
cde/lib/DtSvc/DtUtil1/ActionP.h
Normal file
827
cde/lib/DtSvc/DtUtil1/ActionP.h
Normal file
@@ -0,0 +1,827 @@
|
||||
/* $XConsortium: ActionP.h /main/3 1995/10/26 14:59:56 rswiston $ */
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: ActionP.h
|
||||
**
|
||||
** Project: DT
|
||||
**
|
||||
** Description: Private include file for the Action Library.
|
||||
**
|
||||
**
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
|
||||
#ifndef _ActionP_h
|
||||
#define _ActionP_h
|
||||
|
||||
#include <Dt/DtP.h>
|
||||
#include <Dt/DbReader.h>
|
||||
#include <Dt/ActionDb.h>
|
||||
#include <Dt/Action.h>
|
||||
#include <Tt/tttk.h>
|
||||
#include <Dt/DtShmDb.h>
|
||||
/*
|
||||
* Environment Variable Names
|
||||
*/
|
||||
#define ENV_SESSION_SVR "SESSION_SVR"
|
||||
/*
|
||||
* Define maximum static buffer size for action code.
|
||||
*/
|
||||
#define _DtAct_MAX_BUF_SIZE 1024
|
||||
|
||||
/*
|
||||
* Data-type field which contains the template for producing filenames
|
||||
* of a given type.
|
||||
*/
|
||||
#define _DtActNAME_TEMPLATE "NAME_TEMPLATE"
|
||||
#define _DtActIS_EXECUTABLE "IS_EXECUTABLE"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* MASK LAYOUT:
|
||||
*
|
||||
* The same layout is used for all the masks (defined herein);, independent of
|
||||
* the data structure in which they are defined. That is, all bit fields for
|
||||
* all masks are non-overlapping. In general, the mask in any given structure
|
||||
* should ONLY contain information in the field appropriate for that structure.
|
||||
*
|
||||
* The action bit mask is broken into the following fields
|
||||
*
|
||||
* --------------------------------------------------------------------------
|
||||
* |act'n |arg |arg |arg | win |args| request | object |treat| not |
|
||||
* |type |class|count|typ | type | | status | status | as | |
|
||||
* |bits |bits |bits |bit | bits |used| bits | bits |file |used |
|
||||
* --------------------------------------------------------------------------
|
||||
* 0 - 4,5 - 8,9 - 12, 13 ,14 - 17,18-19,20 ------- 22,23 ---- 28, 29 ,30-31
|
||||
* | | | | | |
|
||||
* |<-- action mask -->| |<- request->|<- obj. ->|< - >|
|
||||
* mask data |
|
||||
* mask msgCcomp.
|
||||
* mask
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* generic bit manipulation macros
|
||||
*/
|
||||
#define SET_ANY_BITS(mask,bits) ( mask |= (bits) )
|
||||
#define RESET_ANY_BITS(mask,bits) ( mask &= ~(bits) )
|
||||
#define TST_ANY_BITS(mask,bits) ( mask & (bits) )
|
||||
|
||||
/*
|
||||
* Action type bits
|
||||
*/
|
||||
#define _DtAct_CMD_BIT (1<<0)
|
||||
#define _DtAct_MAP_BIT (1<<1)
|
||||
#define _DtAct_TT_MSG_BIT (1<<2)
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define _DtAct_DT_REQ_MSG_BIT (1<<3)
|
||||
#define _DtAct_DT_NTFY_MSG_BIT (1<<4)
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
/*
|
||||
* Action structure mask bits
|
||||
*/
|
||||
#define _DtAct_ARG_CLASS_FILE_BIT (1<<5)
|
||||
#define _DtAct_ARG_CLASS_STRING_BIT (1<<6)
|
||||
#define _DtAct_ARG_CLASS_BUFFER_BIT (1<<7)
|
||||
#define _DtAct_ARG_CLASS_WILD_BIT (1<<8)
|
||||
|
||||
#define _DtAct_ARG_COUNT_LT_BIT (1<<9)
|
||||
#define _DtAct_ARG_COUNT_GT_BIT (1<<10)
|
||||
#define _DtAct_ARG_COUNT_EQ_BIT (1<<11)
|
||||
#define _DtAct_ARG_COUNT_WILD_BIT (1<<12)
|
||||
|
||||
#define _DtAct_ARG_TYPE_WILD_BIT (1<<13)
|
||||
|
||||
#define _DtAct_NO_STDIO_BIT (1<<14)
|
||||
#define _DtAct_TERMINAL_BIT (1<<15)
|
||||
#define _DtAct_PERM_TERM_BIT (1<<16)
|
||||
|
||||
/*
|
||||
* Defines which reflect the actual number
|
||||
* of %ARGn% instances found in the action definition
|
||||
* NOTE: Is this JUST in the EXEC_STRING? or the total number of %ARGn%'s
|
||||
* referenced in all parssed definitions?
|
||||
*
|
||||
*/
|
||||
#define _DtAct_SINGLE_ARG_BIT (1<<18)
|
||||
#define _DtAct_MULTI_ARG_BIT (1<<19)
|
||||
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define _DtAct_ACTION_TYPE_BITS ( _DtAct_CMD_BIT \
|
||||
| _DtAct_MAP_BIT \
|
||||
| _DtAct_DT_NTFY_MSG_BIT \
|
||||
| _DtAct_DT_REQ_MSG_BIT \
|
||||
| _DtAct_TT_MSG_BIT )
|
||||
#else
|
||||
#define _DtAct_ACTION_TYPE_BITS ( _DtAct_CMD_BIT \
|
||||
| _DtAct_MAP_BIT \
|
||||
| _DtAct_TT_MSG_BIT )
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
#define _DtAct_ARG_CLASS_BITS ( _DtAct_ARG_CLASS_FILE_BIT \
|
||||
| _DtAct_ARG_CLASS_STRING_BIT\
|
||||
| _DtAct_ARG_CLASS_BUFFER_BIT \
|
||||
| _DtAct_ARG_CLASS_WILD_BIT )
|
||||
#define _DtAct_ARG_TYPE_BITS ( _DtAct_ARG_TYPE_WILD_BIT )
|
||||
#define _DtAct_ARG_COUNT_BITS ( _DtAct_ARG_COUNT_LT_BIT \
|
||||
| _DtAct_ARG_COUNT_GT_BIT \
|
||||
| _DtAct_ARG_COUNT_EQ_BIT \
|
||||
| _DtAct_ARG_COUNT_WILD_BIT )
|
||||
#define _DtAct_WINTYPE_BITS ( _DtAct_NO_STDIO_BIT \
|
||||
| _DtAct_TERMINAL_BIT \
|
||||
| _DtAct_PERM_TERM_BIT )
|
||||
#define _DtAct_ARGS_USED_BITS ( _DtAct_SINGLE_ARG \
|
||||
| _DtAct_MULTI_ARG )
|
||||
|
||||
#define _DtAct_ACTION_BITS ( _DtAct_ACTION_TYPE_BITS \
|
||||
| _DtAct_ARG_CLASS_BITS \
|
||||
| _DtAct_ARG_TYPE_BITS \
|
||||
| _DtAct_ARG_COUNT_BITS \
|
||||
| _DtAct_WINTYPE_BITS \
|
||||
| _DtAct_ARGS_USED_BITS )
|
||||
|
||||
#define IS_CMD(mask) ( mask & _DtAct_CMD_BIT )
|
||||
#define IS_MAP(mask) ( mask & _DtAct_MAP_BIT )
|
||||
#define IS_TT_MSG(mask) ( mask & _DtAct_TT_MSG_BIT )
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define IS_DT_REQ_MSG(mask) ( mask & _DtAct_DT_REQ_MSG_BIT )
|
||||
#define IS_DT_NOTIFY_MSG(mask) ( mask & _DtAct_DT_NTFY_MSG_BIT )
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
#define SET_CMD_ACTION(mask) ( mask |= _DtAct_CMD_BIT )
|
||||
#define SET_MAP_ACTION(mask) ( mask |= _DtAct_MAP_BIT )
|
||||
#define SET_TT_MSG(mask) ( mask |= _DtAct_TT_MSG_BIT )
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define SET_DT_REQUEST_MSG(mask) ( mask |= _DtAct_DT_REQ_MSG_BIT)
|
||||
#define SET_DT_NOTIFY_MSG(mask) ( mask |= _DtAct_DT_NTFY_MSG_BIT)
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
#define RESET_CMD_ACTION(mask) ( mask &= ~(_DtAct_CMD_BIT))
|
||||
#define RESET_MAP_ACTION(mask) ( mask &= ~(_DtAct_MAP_BIT))
|
||||
#define RESET_TT_MSG(mask) ( mask &= ~(_DtAct_TT_MSG_BIT))
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
#define RESET_DT_REQ_MSG(mask) ( mask &= ~(_DtAct_DT_REQ_MSG_BIT))
|
||||
#define RESET_DT_NOTIFY_MSG(mask) ( mask &= ~(_DtAct_DT_NTFY_MSG_BIT))
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
#define IS_NO_STDIO(mask) ( mask & _DtAct_NO_STDIO_BIT )
|
||||
#define IS_TERMINAL(mask) ( mask & _DtAct_TERMINAL_BIT )
|
||||
#define IS_PERM_TERM(mask) ( mask & _DtAct_PERM_TERM_BIT)
|
||||
|
||||
#define SET_NO_STDIO(mask) ( mask |= _DtAct_NO_STDIO_BIT )
|
||||
#define SET_TERMINAL(mask) ( mask |= _DtAct_TERMINAL_BIT )
|
||||
#define SET_PERM_TERM(mask) ( mask |= _DtAct_PERM_TERM_BIT )
|
||||
|
||||
#define RESET_NO_STDIO(mask) ( mask &= ~(_DtAct_NO_STDIO_BIT ))
|
||||
#define RESET_TERMINAL(mask) ( mask &= ~(_DtAct_TERMINAL_BIT ))
|
||||
#define RESET_PERM_TERM(mask) ( mask &= ~(_DtAct_PERM_TERM_BIT ))
|
||||
|
||||
#define IS_ARG_CLASS_FILE(mask) ( mask & _DtAct_ARG_CLASS_FILE_BIT )
|
||||
#define IS_ARG_CLASS_STRING(mask) ( mask & _DtAct_ARG_CLASS_STRING_BIT )
|
||||
#define IS_ARG_CLASS_BUFFER(mask) ( mask & _DtAct_ARG_CLASS_BUFFER_BIT )
|
||||
#define IS_ARG_CLASS_WILD(mask) ( mask & _DtAct_ARG_CLASS_WILD_BIT )
|
||||
|
||||
#define SET_ARG_CLASS_FILE(mask) ( mask |= _DtAct_ARG_CLASS_FILE_BIT )
|
||||
#define SET_ARG_CLASS_STRING(mask) ( mask |= _DtAct_ARG_CLASS_STRING_BIT)
|
||||
#define SET_ARG_CLASS_BUFFER(mask) ( mask |= _DtAct_ARG_CLASS_BUFFER_BIT)
|
||||
#define SET_ARG_CLASS_WILD(mask) ( mask |= _DtAct_ARG_CLASS_WILD_BIT )
|
||||
|
||||
#define RESET_ARG_CLASS_FILE(mask) (mask &= ~(_DtAct_ARG_CLASS_FILE_BIT))
|
||||
#define RESET_ARG_CLASS_STRING(mask) (mask &= ~(_DtAct_ARG_CLASS_STRING_BIT))
|
||||
#define RESET_ARG_CLASS_BUFFER(mask) (mask &= ~(_DtAct_ARG_CLASS_BUFFER_BIT))
|
||||
#define RESET_ARG_CLASS_WILD(mask) (mask &= ~(_DtAct_ARG_CLASS_WILD_BIT))
|
||||
|
||||
|
||||
#define IS_ARG_TYPE_WILD(mask) ( mask & _DtAct_ARG_TYPE_WILD_BIT )
|
||||
|
||||
#define SET_ARG_TYPE_WILD(mask) ( mask |= _DtAct_ARG_TYPE_WILD_BIT )
|
||||
|
||||
#define RESET_ARG_TYPE_WILD(mask) ( mask &= ~(_DtAct_ARG_TYPE_WILD_BIT))
|
||||
|
||||
#define IS_ARG_COUNT_GT(mask) ( mask & _DtAct_ARG_COUNT_GT_BIT )
|
||||
#define IS_ARG_COUNT_LT(mask) ( mask & _DtAct_ARG_COUNT_LT_BIT )
|
||||
#define IS_ARG_COUNT_EQ(mask) ( mask & _DtAct_ARG_COUNT_EQ_BIT )
|
||||
#define IS_ARG_COUNT_WILD(mask) ( mask & _DtAct_ARG_COUNT_WILD_BIT )
|
||||
|
||||
#define SET_ARG_COUNT_GT(mask) ( mask |= _DtAct_ARG_COUNT_GT_BIT )
|
||||
#define SET_ARG_COUNT_LT(mask) ( mask |= _DtAct_ARG_COUNT_LT_BIT )
|
||||
#define SET_ARG_COUNT_EQ(mask) ( mask |= _DtAct_ARG_COUNT_EQ_BIT )
|
||||
#define SET_ARG_COUNT_WILD(mask) ( mask |= _DtAct_ARG_COUNT_WILD_BIT )
|
||||
|
||||
#define RESET_ARG_COUNT_GT(mask) ( mask &= ~(_DtAct_ARG_COUNT_GT_BIT ))
|
||||
#define RESET_ARG_COUNT_LT(mask) ( mask &= ~(_DtAct_ARG_COUNT_LT_BIT ))
|
||||
#define RESET_ARG_COUNT_EQ(mask) ( mask &= ~(_DtAct_ARG_COUNT_EQ_BIT ))
|
||||
#define RESET_ARG_COUNT_WILD(mask) ( mask &= ~(_DtAct_ARG_COUNT_WILD_BIT ))
|
||||
|
||||
/*
|
||||
* Use of the logical "NOT" operator(!) instead of the bitwise negation
|
||||
* operator(~) is intentional in IS_ARG_NONE_FOUND.
|
||||
*/
|
||||
#define IS_ARG_NONE_FOUND(mask) !( mask & ( _DtAct_SINGLE_ARG_BIT \
|
||||
| _DtAct_MULTI_ARG_BIT ))
|
||||
#define IS_ARG_SINGLE_ARG(mask) ( mask & _DtAct_SINGLE_ARG_BIT )
|
||||
#define IS_ARG_MULTI_ARG(mask) ( mask & _DtAct_MULTI_ARG_BIT )
|
||||
|
||||
#define SET_ARG_NONE_FOUND(mask) ( mask &= ~( _DtAct_SINGLE_ARG_BIT \
|
||||
| _DtAct_MULTI_ARG_BIT ))
|
||||
#define SET_ARG_SINGLE_ARG(mask) ((mask |= _DtAct_SINGLE_ARG_BIT), \
|
||||
( mask &= ~(_DtAct_MULTI_ARG_BIT)))
|
||||
#define SET_ARG_MULTI_ARG(mask) ((mask |= _DtAct_MULTI_ARG_BIT), \
|
||||
( mask &= ~(_DtAct_SINGLE_ARG_BIT)))
|
||||
|
||||
#define RESET_ARG_SINGLE_ARG(mask) ( mask &= ~(_DtAct_SINGLE_ARG_BIT))
|
||||
#define RESET_ARG_MULTI_ARG(mask) ( mask &= ~(_DtAct_MULTI_ARG_BIT))
|
||||
|
||||
/*
|
||||
* ActionRequest structure mask bits
|
||||
*/
|
||||
|
||||
#define _DtAct_REPROCESSING_BIT (1<<20)
|
||||
#define _DtAct_TOO_MANY_MAPS_BIT (1<<21)
|
||||
#define _DtAct_CLONED_REQUEST_BIT (1<<22)
|
||||
|
||||
#define _DtAct_ACTION_REQUEST_BITS ( _DtAct_REPROCESSING_BIT \
|
||||
| _DtAct_TOO_MANY_MAPS_BIT \
|
||||
| _DtAct_CLONED_REQUEST_BIT )
|
||||
|
||||
#define IS_REPROCESSING(mask) ( mask & _DtAct_REPROCESSING_BIT )
|
||||
#define IS_TOO_MANY_MAPS(mask) ( mask & _DtAct_TOO_MANY_MAPS_BIT )
|
||||
#define IS_CLONED_REQUEST(mask) ( mask & _DtAct_CLONED_REQUEST_BIT )
|
||||
|
||||
#define SET_REPROCESSING(mask) ( mask |= _DtAct_REPROCESSING_BIT )
|
||||
#define SET_TOO_MANY_MAPS(mask) ( mask |= _DtAct_TOO_MANY_MAPS_BIT )
|
||||
#define SET_CLONED_REQUEST(mask) ( mask |= _DtAct_CLONED_REQUEST_BIT )
|
||||
|
||||
#define RESET_REPROCESSING(mask) ( mask &= ~(_DtAct_REPROCESSING_BIT))
|
||||
#define RESET_TOO_MANY_MAPS(mask) ( mask &= ~(_DtAct_TOO_MANY_MAPS_BIT))
|
||||
#define RESET_CLONED_REQUEST(mask) ( mask &= ~(_DtAct_CLONED_REQUEST_BIT))
|
||||
|
||||
|
||||
/*
|
||||
* ObjectData structure mask bits
|
||||
*
|
||||
*/
|
||||
|
||||
#define _DtAct_WRITE_OBJ_BIT (1<<23)
|
||||
#define _DtAct_FILE_OBJ_BIT (1<<24)
|
||||
#define _DtAct_BUFFER_OBJ_BIT (1<<25)
|
||||
#define _DtAct_STRING_OBJ_BIT (1<<26)
|
||||
#define _DtAct_DIR_OBJ_BIT (1<<27)
|
||||
#define _DtAct_UNKNOWN_IF_DIR_BIT (1<<28)
|
||||
|
||||
#define _DtAct_OBJ_DATA_BITS ( _DtAct_WRITE_OBJ_BIT \
|
||||
| _DtAct_FILE_OBJ_BIT \
|
||||
| _DtAct_DIR_OBJ_BIT \
|
||||
| _DtAct_BUFFER_OBJ_BIT \
|
||||
| _DtAct_STRING_OBJ_BIT \
|
||||
| _DtAct_UNKNOWN_IF_DIR_BIT )
|
||||
|
||||
#define IS_WRITE_OBJ(mask) ( mask & _DtAct_WRITE_OBJ_BIT )
|
||||
#define IS_FILE_OBJ(mask) ( mask & _DtAct_FILE_OBJ_BIT )
|
||||
#define IS_BUFFER_OBJ(mask) ( mask & _DtAct_BUFFER_OBJ_BIT )
|
||||
#define IS_STRING_OBJ(mask) ( mask & _DtAct_STRING_OBJ_BIT )
|
||||
#define IS_UNKNOWN_IF_DIR(mask) ( mask & _DtAct_UNKNOWN_IF_DIR_BIT )
|
||||
#define IS_DIR_OBJ(mask) ( mask & \
|
||||
( _DtAct_UNKNOWN_IF_DIR_BIT \
|
||||
| _DtAct_DIR_OBJ_BIT ) \
|
||||
== _DtAct_DIR_OBJ_BIT)
|
||||
|
||||
#define SET_WRITE_OBJ(mask) ( mask |= _DtAct_WRITE_OBJ_BIT )
|
||||
#define SET_FILE_OBJ(mask) ( mask |= _DtAct_FILE_OBJ_BIT )
|
||||
#define SET_BUFFER_OBJ(mask) ( mask |= _DtAct_BUFFER_OBJ_BIT )
|
||||
#define SET_STRING_OBJ(mask) ( mask |= _DtAct_STRING_OBJ_BIT )
|
||||
#define SET_DIR_OBJ(mask) ( mask |= _DtAct_DIR_OBJ_BIT )
|
||||
#define SET_UNKNOWN_IF_DIR(mask) ( mask |= _DtAct_UNKNOWN_IF_DIR_BIT)
|
||||
|
||||
#define RESET_WRITE_OBJ(mask) ( mask &= ~(_DtAct_WRITE_OBJ_BIT))
|
||||
#define RESET_FILE_OBJ(mask) ( mask &= ~(_DtAct_FILE_OBJ_BIT))
|
||||
#define RESET_BUFFER_OBJ(mask) ( mask &= ~(_DtAct_BUFFER_OBJ_BIT))
|
||||
#define RESET_STRING_OBJ(mask) ( mask &= ~(_DtAct_STRING_OBJ_BIT))
|
||||
#define RESET_DIR_OBJ(mask) ( mask &= ~(_DtAct_DIR_OBJ_BIT))
|
||||
#define RESET_UNKNOWN_IF_DIR(mask) ( mask &= ~(_DtAct_UNKNOWN_IF_DIR_BIT))
|
||||
|
||||
|
||||
/*
|
||||
* MsgComponent structure mask bits (shared with Object Data?)
|
||||
*/
|
||||
|
||||
#define _DtAct_TREAT_AS_FILE_BIT (1<<29)
|
||||
|
||||
#define _DtAct_MSG_COMP_BITS ( _DtAct_TREAT_AS_FILE_BIT )
|
||||
|
||||
#define IS_TREAT_AS_FILE(mask) ( mask & _DtAct_TREAT_AS_FILE_BIT )
|
||||
#define SET_TREAT_AS_FILE(mask) ( mask |= _DtAct_TREAT_AS_FILE_BIT)
|
||||
#define RESET_TREAT_AS_FILE(mask) ( mask &= ~(_DtAct_TREAT_AS_FILE_BIT))
|
||||
|
||||
|
||||
/* Keyword defines */
|
||||
|
||||
#define NO_KEYWORD -1
|
||||
#define LOCAL_HOST 0
|
||||
#define DATA_HOST 1
|
||||
#define DATABASE_HOST 2
|
||||
#define ARG 3
|
||||
#define DISPLAY_HOST 4
|
||||
#define LABEL 5
|
||||
#define SESSION_HOST 6
|
||||
|
||||
/* Special argNum values */
|
||||
|
||||
#define NO_ARG -1
|
||||
#define ALL_ARGS 0
|
||||
|
||||
/*
|
||||
* ToolTalk base representation type ( tt_argn_rep_type ) values
|
||||
*/
|
||||
#define DtACT_TT_REP_UNDEFINED 0
|
||||
#define DtACT_TT_REP_INT 1
|
||||
#define DtACT_TT_REP_BUFFER 2
|
||||
#define DtACT_TT_REP_STRING 3
|
||||
|
||||
/*
|
||||
* Resource name and class for the EXEC-HOST resource.
|
||||
*/
|
||||
#define DtEXEC_HOSTS_NAME "executionHosts"
|
||||
#define DtEXEC_HOSTS_CLASS "ExecutionHosts"
|
||||
#define DtEXEC_HOSTS_DEFAULT _DtACT_EXEC_HOST_DFLT
|
||||
|
||||
/* Flags to force special processing of filenames */
|
||||
#define _DTAct_TT_VTYPE 1 << 0
|
||||
#define _DTAct_TT_ARG 1 << 1
|
||||
|
||||
/* Structure used to hold the components of a message */
|
||||
|
||||
typedef struct {
|
||||
char *precedingText;
|
||||
char *prompt;
|
||||
int keyword;
|
||||
int argNum;
|
||||
unsigned long mask; /* replaces isFile, isBuffer, isString boolean */
|
||||
} MsgComponent;
|
||||
|
||||
|
||||
typedef struct {
|
||||
MsgComponent *parsedMessage;
|
||||
int numMsgParts;
|
||||
char *compiledMessage;
|
||||
int msgLen;
|
||||
} parsedMsg;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Structs used during the invocation of an action. Once DtActionInvoke()
|
||||
* exits, these structs are generally freed.
|
||||
*
|
||||
*****************************************************************************/
|
||||
typedef struct {
|
||||
/*int winMask; ---> moved into the action mask*/
|
||||
parsedMsg execString;
|
||||
parsedMsg termOpts;
|
||||
char *contextDir;
|
||||
char *contextHost;
|
||||
parsedMsg execHosts;
|
||||
char **execHostArray;
|
||||
int execHostCount;
|
||||
} cmdAttr;
|
||||
|
||||
typedef struct {
|
||||
DtShmBoson map_action;
|
||||
} mapAttr;
|
||||
|
||||
typedef struct {
|
||||
int tt_class;
|
||||
int tt_scope;
|
||||
parsedMsg tt_op;
|
||||
parsedMsg tt_file; /* must be a single file name */
|
||||
int *tt_argn_mode;
|
||||
int mode_count;
|
||||
parsedMsg *tt_argn_vtype;
|
||||
int vtype_count;
|
||||
parsedMsg *tt_argn_value;
|
||||
int value_count;
|
||||
int *tt_argn_rep_type; /* INT, STRING, BUFFER or UNDEFINED */
|
||||
int rep_type_count;
|
||||
} tt_msgAttr;
|
||||
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
typedef struct {
|
||||
parsedMsg service; /* ICCCM service name */
|
||||
parsedMsg request; /* request name string */
|
||||
parsedMsg *argn_value;
|
||||
int value_count;
|
||||
|
||||
} dt_reqAttr;
|
||||
|
||||
typedef struct {
|
||||
parsedMsg ngroup; /* ICCCM notification group */
|
||||
parsedMsg notify; /* notification to be sent */
|
||||
parsedMsg *argn_value;
|
||||
int value_count;
|
||||
} dt_notifyAttr;
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
|
||||
|
||||
typedef struct {
|
||||
DtShmBoson action; /* Might just use a char * here? */
|
||||
DtDbPathId file_name_id; /* id of file wherein the action is defined */
|
||||
char *label; /* localizable action label string */
|
||||
char *description;
|
||||
DtShmBoson *arg_types;
|
||||
int type_count;
|
||||
int arg_count; /* Number of arguments accepted by the action */
|
||||
unsigned long mask; /* action mask -- class/type/arg info */
|
||||
union { /* attributes for the different action kinds */
|
||||
cmdAttr cmd;
|
||||
mapAttr map;
|
||||
tt_msgAttr tt_msg;
|
||||
#ifdef _DT_ALLOW_DT_MSGS
|
||||
dt_reqAttr dt_req;
|
||||
dt_notifyAttr dt_notify;
|
||||
#endif /* _DT_ALLOW_DT_MSGS */
|
||||
} u;
|
||||
} Action, *ActionPtr; /* new action structure and pointer */
|
||||
|
||||
|
||||
/* Structure used to hold each of the object components */
|
||||
|
||||
typedef struct {
|
||||
char * origFilename;
|
||||
char * baseFilename;
|
||||
char * origHostname;
|
||||
int hostIndex;
|
||||
int dirIndex;
|
||||
void * bp; /* pointer to original buffer -- tmp files only */
|
||||
int sizebp; /* size of original buf -- for tmp files only */
|
||||
} fileAttr;
|
||||
|
||||
typedef struct {
|
||||
char * string;
|
||||
} stringAttr;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
void *bp;
|
||||
} bufferAttr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
DtShmBoson type;
|
||||
unsigned long mask;
|
||||
union {
|
||||
fileAttr file;
|
||||
stringAttr string;
|
||||
bufferAttr buffer;
|
||||
} u;
|
||||
} ObjectData;
|
||||
|
||||
|
||||
/*
|
||||
* Structure attached to the button callbacks in the
|
||||
* dialog used to collect missing parameters.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *actionName;
|
||||
int objOffset;
|
||||
int objsUsed;
|
||||
int numObjects;
|
||||
ObjectData *objects;
|
||||
int numPromptInputs;
|
||||
char **promptInputs;
|
||||
int numHostNames;
|
||||
char **hostNames;
|
||||
int numDirNames;
|
||||
char **dirNames;
|
||||
char *termOpts;
|
||||
char *cwdHost;
|
||||
char *cwdDir;
|
||||
ActionPtr clonedAction;
|
||||
unsigned long mask;
|
||||
char *badHostList;
|
||||
char *currentHost;
|
||||
int hostIndex;
|
||||
char *execHost;
|
||||
DtActionInvocationID invocId;
|
||||
unsigned long childId;
|
||||
} ActionRequest;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Structs used to maintain information on invoked actions until they
|
||||
* exit. A few select elements of the ActionRequest and Action structs
|
||||
* will be copied into these strcuts.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
**
|
||||
** Major data-structure diagram for the DtAction invocation layer:
|
||||
**
|
||||
** _DtActInvRec <=== _DtActInvRecArray[ actInvRecArraySize ]
|
||||
** ------------------
|
||||
** | info per |
|
||||
** | DtActionInvoke |
|
||||
** |----------------|
|
||||
** | numChildren |
|
||||
** |----------------|
|
||||
** | childRecs[] | ===> _DtActChildRec
|
||||
** ------------------ ------------------
|
||||
** | info per |
|
||||
** | child request |
|
||||
** |----------------|
|
||||
** | *request | ===> ActionRequest
|
||||
** ------------------ ------------------
|
||||
** | info on users |
|
||||
** | action request |
|
||||
** |----------------|
|
||||
** Action <=== | *clonedAction |
|
||||
** ------------------ ------------------
|
||||
** |info on matching|
|
||||
** | actionDB entry |
|
||||
** |----------------|
|
||||
** | cmd/map/tt/dt |
|
||||
** | attributes of |
|
||||
** | resulting msg |
|
||||
** ------------------
|
||||
**
|
||||
** "ActionRequest" and "Action" were present in VUE 3.0, and have a
|
||||
** scratch-pad like function within DtActionInvoke() to get actions
|
||||
** started. They are not good long-term retainers of information.
|
||||
** Action and ActionRequest are in fact freed when DtActionInvoke()
|
||||
** exits.
|
||||
**
|
||||
** "_DtActInvRec" and "_DtActChildRec" have been introduced to retain
|
||||
** information for the entire life of the actions. Some of the
|
||||
** information from ActionRequest and Action will be copied (mirrored)
|
||||
** up to these structures.
|
||||
**
|
||||
******************************************************************************
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Child Status Macro Definitions -- These values are used in
|
||||
* the status word of the _DtActChildRec child record.
|
||||
*
|
||||
* ****** IMPORTANT NOTE *** IMPORTANT NOTE *** IMPORTANT NOTE ******
|
||||
*
|
||||
* The _DtActCHILD_ macros are also used in cde1/dtexec/Main.c
|
||||
* in the _DtActDtexecDone(Request) message, so in effect they
|
||||
* are also protocol constants that should *never* be changed.
|
||||
* If changed, libDtSvc and dtexec may mis-communicate status.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define _DtActCHILD_UNKNOWN (1<<0) /* 1 - child status unknown */
|
||||
#define _DtActCHILD_PENDING_START (1<<1) /* 2 - child start pending */
|
||||
#define _DtActCHILD_ALIVE_UNKNOWN (1<<2) /* 4 - child alive but unknown*/
|
||||
#define _DtActCHILD_ALIVE (1<<3) /* 8 - child alive and well */
|
||||
#define _DtActCHILD_DONE (1<<4) /* 16 - child done */
|
||||
#define _DtActCHILD_FAILED (1<<5) /* 32 - child failed */
|
||||
#define _DtActCHILD_CANCELED (1<<6) /* 64 - child canceled */
|
||||
|
||||
#define _DtActCHILD_DONE_BITS ( (_DtActCHILD_DONE) | \
|
||||
(_DtActCHILD_FAILED) | \
|
||||
(_DtActCHILD_CANCELED) )
|
||||
|
||||
/*** IMPORTANT NOTE ABOVE *** IMPORTANT NOTE ABOVE *** IMPORTANT NOTE ABOVE ***/
|
||||
|
||||
|
||||
#define ARE_CHILDREN_DONE(mask) ( (mask) & _DtActCHILD_DONE_BITS )
|
||||
|
||||
#define IS_CHILD_UNKNOWN(mask) ( (mask) == _DtActCHILD_UNKNOWN )
|
||||
#define IS_CHILD_PENDING_START(mask) ( (mask) & _DtActCHILD_PENDING_START )
|
||||
#define IS_CHILD_DONE(mask) ( (mask) & _DtActCHILD_DONE)
|
||||
#define IS_CHILD_FAILED(mask) ( (mask) & _DtActCHILD_FAILED)
|
||||
#define IS_CHILD_CANCELED(mask) ( (mask) & _DtActCHILD_CANCELED)
|
||||
#define IS_CHILD_ALIVE(mask) ( (mask) & _DtActCHILD_ALIVE)
|
||||
#define IS_CHILD_ALIVE_UNKOWN(mask) ( (mask) & _DtActCHILD_ALIVE_UNKNOWN)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Information per child of DtActionInvoke()
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Structure useed to map returnable arguments to the child argument list.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int argN; /* Nth returned value (0 based for tooltalk) */
|
||||
int argIdx; /* Nth child argument */
|
||||
} _DtActArgMap;
|
||||
|
||||
typedef struct {
|
||||
unsigned long childId; /* serial # with DtActInvId */
|
||||
unsigned long childState; /* child state */
|
||||
|
||||
/*
|
||||
* Information cloned from "ActionRequest *req"
|
||||
*/
|
||||
int numObjects; /* number of child args */
|
||||
_DtActArgMap *argMap; /* map of returnable args to chd args */
|
||||
|
||||
/*
|
||||
* Information cloned from "ActionPtr clonedAction"
|
||||
*/
|
||||
unsigned long mask; /* action type - IS_xxx() */
|
||||
|
||||
/* a list of tmp file names 5/11/94 --tomg */
|
||||
|
||||
union {
|
||||
struct { /* COMMAND elements */
|
||||
char *TTProcId; /* TT procID handle to child */
|
||||
Tt_message reqMessage; /* Initiator TT Request */
|
||||
Tt_pattern magic_cookie; /* dtexec to libDtSvc cookie */
|
||||
} cmd;
|
||||
struct { /* TT_MSG elements */
|
||||
char *TTProcId; /* TT procID handle to child */
|
||||
Tt_message reqMessage; /* Initiator TT Request */
|
||||
int isTtMedia; /* handled by ttmedia_load ? */
|
||||
Tttk_op TtMediaOp; /* if ttmedia_load, the op */
|
||||
Tt_pattern *subConPats; /* for subcontract_manage */
|
||||
} tt;
|
||||
} u;
|
||||
|
||||
} _DtActChildRecT;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Invocation Status Macro Definitions -- These values are used in
|
||||
* the state word of the _DtActInvRec invocation record.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define _DtActINV_UNKNOWN 0 /* unknown invocation status */
|
||||
#define _DtActINV_ERROR (1<<0) /* invocation error detected */
|
||||
#define _DtActINV_CANCEL (1<<1) /* trying to cancel invocation*/
|
||||
#define _DtActINV_PENDING (1<<2) /* invocation pending */
|
||||
#define _DtActINV_WORKING (1<<3) /* invocation in process */
|
||||
#define _DtActINV_DONE (1<<4) /* invocation step done */
|
||||
#define _DtActINV_COMPLETE (1<<5) /* invocation steps all done */
|
||||
#define _DtActINV_CB_CALLED (1<<6) /* invocation callback called */
|
||||
#define _DtActINV_ID_RETURNED (1<<7) /* invocation id has returned */
|
||||
#define _DtActINV_CMD_QUEUED (1<<8) /* command has been queued */
|
||||
#define _DtActINV_INDICATOR_ON (1<<9) /* busy indicator active bit */
|
||||
|
||||
#define SET_INV_UNKNOWN(mask) (mask = 0)
|
||||
|
||||
#define SET_INV_ERROR(mask) (mask |= _DtActINV_ERROR)
|
||||
#define SET_INV_CANCEL(mask) (mask |= _DtActINV_CANCEL)
|
||||
#define SET_INV_PENDING(mask) (mask |= _DtActINV_PENDING)
|
||||
#define SET_INV_WORKING(mask) (mask |= _DtActINV_WORKING)
|
||||
#define SET_INV_DONE(mask) (mask |= _DtActINV_DONE)
|
||||
#define SET_INV_COMPLETE(mask) (mask |= _DtActINV_COMPLETE)
|
||||
#define SET_INV_CB_CALLED(mask) (mask |= _DtActINV_CB_CALLED)
|
||||
#define SET_INV_ID_RETURNED(mask) (mask |= _DtActINV_ID_RETURNED)
|
||||
#define SET_INV_CMD_QUEUED(mask) (mask |= _DtActINV_CMD_QUEUED)
|
||||
#define SET_INV_INDICATOR_ON(mask) (mask |= _DtActINV_INDICATOR_ON)
|
||||
|
||||
#define RESET_INV_ERROR(mask) (mask &= ~(_DtActINV_ERROR))
|
||||
#define RESET_INV_CANCEL(mask) (mask &= ~(_DtActINV_CANCEL))
|
||||
#define RESET_INV_PENDING(mask) (mask &= ~(_DtActINV_PENDING))
|
||||
#define RESET_INV_WORKING(mask) (mask &= ~(_DtActINV_WORKING))
|
||||
#define RESET_INV_COMPLETE(mask) (mask &= ~(_DtActINV_COMPLETE))
|
||||
#define RESET_INV_DONE(mask) (mask &= ~(_DtActINV_DONE))
|
||||
#define RESET_INV_CB_CALLED(mask) (mask &= ~(_DtActINV_CB_CALLED))
|
||||
#define RESET_INV_ID_RETURNED(mask) (mask &= ~(_DtActINV_ID_RETURNED))
|
||||
#define RESET_INV_CMD_QUEUED(mask) (mask &= ~(_DtActINV_CMD_QUEUED))
|
||||
#define RESET_INV_INDICATOR_ON(mask) (mask &= ~(_DtActINV_INDICATOR_ON))
|
||||
|
||||
#define IS_INV_FINISHED(mask) ( !((mask) & _DtActINV_CMD_QUEUED) \
|
||||
&& ((mask) & (_DtActINV_COMPLETE \
|
||||
| _DtActINV_CANCEL)) )
|
||||
#define IS_INV_UNKNOWN(mask) ( (mask) == _DtActINV_UNKNOWN )
|
||||
|
||||
#define IS_INV_ERROR(mask) ((mask) & _DtActINV_ERROR )
|
||||
#define IS_INV_CANCEL(mask) ((mask) & _DtActINV_CANCEL )
|
||||
#define IS_INV_PENDING(mask) ((mask) & _DtActINV_PENDING )
|
||||
#define IS_INV_WORKING(mask) ((mask) & _DtActINV_WORKING )
|
||||
#define IS_INV_DONE(mask) ((mask) & _DtActINV_DONE )
|
||||
#define IS_INV_COMPLETE(mask) ((mask) & _DtActINV_COMPLETE )
|
||||
#define IS_INV_CB_CALLED(mask) ((mask) & _DtActINV_CB_CALLED )
|
||||
#define IS_INV_ID_RETURNED(mask) ((mask) & _DtActINV_ID_RETURNED )
|
||||
#define IS_INV_CMD_QUEUED(mask) ((mask) & _DtActINV_CMD_QUEUED )
|
||||
#define IS_INV_INDICATOR_ON(mask) ((mask) & _DtActINV_INDICATOR_ON )
|
||||
|
||||
#define CALL_INV_CB(mask) ((IS_INV_FINISHED(mask)) && \
|
||||
(IS_INV_ID_RETURNED(mask)) && \
|
||||
!(IS_INV_CB_CALLED(mask)))
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Information per DtActionInvoke()
|
||||
*
|
||||
* Note: For TT_MSG(NOTICE)'s during CDE 1.0, this struct will disappear
|
||||
* immediately after the NOTICEs are sent.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned long mask; /* encodes object class and writable flag */
|
||||
int size; /* original size (buffers only) */
|
||||
char *type; /* original type (buffers only) */
|
||||
char *name; /* encodes (tmp) file name associated with the
|
||||
object (if any) */
|
||||
} _DtActArgInfo;
|
||||
|
||||
typedef struct {
|
||||
DtActionStatus userStatus;
|
||||
DtActionArg *newArgp;
|
||||
int newArgc;
|
||||
} _DtActUpdateCache;
|
||||
|
||||
typedef struct _DtActInvRec {
|
||||
unsigned long state; /* invocation state */
|
||||
DtActionInvocationID id; /* identifying invocation ID */
|
||||
Widget w; /* users widget id */
|
||||
DtActionCallbackProc cb; /* users callback */
|
||||
XtPointer client_data; /* users client data for cb */
|
||||
_DtActArgInfo *info; /* template w/ .argClass info */
|
||||
int ac; /* original # of arguments */
|
||||
int numChildren; /* number of childRec's. */
|
||||
_DtActChildRecT **childRec; /* array of child Rec's */
|
||||
int cachedUploadCnt;/* cached callback updates */
|
||||
_DtActUpdateCache *cachedUploads; /* data for */
|
||||
} _DtActInvRecT;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Structs for dialogs/prompts
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* Structure used to hold a prompt string destined for a dialog */
|
||||
|
||||
typedef struct {
|
||||
int argIndex;
|
||||
char *prompt;
|
||||
} PromptEntry;
|
||||
|
||||
|
||||
/* Structure used to contain prompt dialog information */
|
||||
|
||||
typedef struct {
|
||||
int argIndex;
|
||||
Widget promptWidget;
|
||||
} DialogPromptEntry;
|
||||
|
||||
typedef struct {
|
||||
ActionRequest * request;
|
||||
Widget topLevel;
|
||||
Widget associatedWidget;
|
||||
int numPrompts;
|
||||
DialogPromptEntry * prompts;
|
||||
} PromptDialog;
|
||||
|
||||
|
||||
/* Structure used to contain abort/continue dialog information */
|
||||
|
||||
typedef struct {
|
||||
ActionRequest * request;
|
||||
Widget topLevel;
|
||||
Widget associatedWidget;
|
||||
int numPrompts;
|
||||
PromptEntry * prompts;
|
||||
} ContinueDialog;
|
||||
|
||||
|
||||
/* Structure passed to request passed/failed callbacks */
|
||||
|
||||
typedef struct {
|
||||
Widget associatedWidget;
|
||||
char *actionLabel;
|
||||
int offset;
|
||||
ActionPtr actionPtr; /* Ptr to the action that
|
||||
was invoked. */
|
||||
ActionRequest *requestPtr;
|
||||
DtActionInvocationID actInvId; /* A standard invocation id */
|
||||
unsigned long childId; /* An id to further identify
|
||||
children of actInvId */
|
||||
} CallbackData;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Private External Function Declarations -- not for public consumption
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
extern void _DtFreeActionStruct( ActionPtr action) ;
|
||||
|
||||
#endif /* _ActionP_h */
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
1862
cde/lib/DtSvc/DtUtil1/ActionTt.c
Normal file
1862
cde/lib/DtSvc/DtUtil1/ActionTt.c
Normal file
File diff suppressed because it is too large
Load Diff
1960
cde/lib/DtSvc/DtUtil1/ActionUtil.c
Normal file
1960
cde/lib/DtSvc/DtUtil1/ActionUtil.c
Normal file
File diff suppressed because it is too large
Load Diff
92
cde/lib/DtSvc/DtUtil1/ActionUtilP.h
Normal file
92
cde/lib/DtSvc/DtUtil1/ActionUtilP.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* $XConsortium: ActionUtilP.h /main/3 1995/10/26 15:01:19 rswiston $ */
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: ActionUtilP.h
|
||||
**
|
||||
** Project: DT
|
||||
**
|
||||
** Description: Private include file for the Action Library Utilities.
|
||||
**
|
||||
**
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
|
||||
#ifndef _ActionUtilP_h
|
||||
#define _ActionUtilP_h
|
||||
|
||||
#include <X11/Intrinsic.h> /* for Display struct definition */
|
||||
#include "ActionP.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Macro to protect against sending a NULL pointer to certain
|
||||
* library functions (i.e. sprintf, strlen, ...) with on some
|
||||
* systems choke on a NULL pointer.
|
||||
*
|
||||
****************************************************************************/
|
||||
#define _DtActNULL_GUARD(s) ((s) ? (s) : "")
|
||||
|
||||
/******************************************************************************
|
||||
External Utility Function Declarations
|
||||
|
||||
These functions are for internal use and are not part of the
|
||||
public Action API. Each of the following functions returns a
|
||||
newly allocated version of the desired string. It is up to the
|
||||
caller to free the strings obtained.
|
||||
******************************************************************************/
|
||||
|
||||
extern char *_DtBasename(const char *s);
|
||||
extern char *_DtDirname(const char *s);
|
||||
extern char *_DtPathname(const char *s);
|
||||
extern char *_DtHostString(const char *s);
|
||||
extern char *_DtGetSessionHostName( void );
|
||||
extern char *_DtGetDisplayHostName( Display *d);
|
||||
extern char *_DtGetLocalHostName( void );
|
||||
extern char *_DtGetExecHostsDefault (void);
|
||||
extern char *_DtGetActionIconDefault (void);
|
||||
extern char *_DtGetDtTmpDir(void);
|
||||
extern char *_DtActGenerateTmpFile(char *dir,
|
||||
char *format,
|
||||
mode_t mode,
|
||||
int *fd );
|
||||
extern int _DtIsSameHost( const char *host1, const char *host2 );
|
||||
extern void _DtRemoveTrailingBlanksInPlace(char **s);
|
||||
extern int _DtExecuteAccess(const char *path);
|
||||
|
||||
extern DtActionInvocationID _DtActAllocID();
|
||||
extern _DtActInvRecT *_DtActAllocInvRec();
|
||||
extern _DtActChildRecT *_DtActAllocChildRec( _DtActInvRecT *recp );
|
||||
extern int _DtActDeleteInvRec( DtActionInvocationID id);
|
||||
extern _DtActInvRecT *_DtActFindInvRec( DtActionInvocationID id);
|
||||
extern _DtActChildRecT *_DtActFindChildRec(
|
||||
DtActionInvocationID id,
|
||||
unsigned long childId);
|
||||
extern unsigned long _DtActEvalChildren(DtActionInvocationID id);
|
||||
extern void _DtActExecutionLeafNodeCleanup(
|
||||
DtActionInvocationID id,
|
||||
DtActionArg *newArgp,
|
||||
int newArgc,
|
||||
int respectQuitBlock);
|
||||
extern DtActionArg *_DtActMallocEmptyArgArray(int ac);
|
||||
extern void _DtActFreeArgArray( DtActionArg *argp, int ac );
|
||||
extern void *_DtActReadTmpFileToBuffer (
|
||||
char *fname,
|
||||
int *sizep);
|
||||
extern int _DtActGetCmdReturnArgs (
|
||||
DtActionInvocationID invId,
|
||||
_DtActChildRecT *childp,
|
||||
DtActionArg **aargv );
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
#endif /* _ActionUtilP_h */
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
|
||||
|
||||
177
cde/lib/DtSvc/DtUtil1/CmdInv.h
Normal file
177
cde/lib/DtSvc/DtUtil1/CmdInv.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/* $XConsortium: CmdInv.h /main/6 1996/01/23 10:41:03 barstow $ */
|
||||
/***************************************************************************
|
||||
*
|
||||
* File: CmdInv.h
|
||||
* Description: Public header for the command invocation system.
|
||||
* Language: C
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _CmdInv_h
|
||||
#define _CmdInv_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <Dt/Message.h>
|
||||
#include <Dt/Spc.h>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DtCmdInvExecuteProc - This type is is used to define the parameters
|
||||
* needed in the callback functions for success and failure notification
|
||||
* of a Command Invoker execution call.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
typedef void (*DtCmdInvExecuteProc) (
|
||||
char *message, /* NULL if the request is successful.
|
||||
* Otherwise an error message. */
|
||||
void *client_data
|
||||
);
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function: void _DtInitializeCommandInvoker (
|
||||
* Display *display,
|
||||
* char *toolClass,
|
||||
* char *applicationClass,
|
||||
* DtSvcReceiveProc reloadDBHandler,
|
||||
* XtAppContext appContext)
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* display - The X server display connection.
|
||||
*
|
||||
* toolClass - The BMS tool class of the client.
|
||||
*
|
||||
* applicationClass - The application class of the client (see
|
||||
* XtInitialize). This is needed to add the
|
||||
* Command Invoker's resources to the client's
|
||||
* resources.
|
||||
*
|
||||
* reloadDBHandler - Function to be called if a RELOAD-TYPES-DB
|
||||
* request is made. If the client does not read
|
||||
* DT action and/or filetype databases, NULL must
|
||||
* be used.
|
||||
*
|
||||
* appContext - The client's application context. Must be NULL
|
||||
* if the client does not use an application
|
||||
* context.
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* This function allows a client to internalize the functionality
|
||||
* of the DT "Command Invoker". By using this library and the
|
||||
* Action Library, requests for the Command Invoker will be done
|
||||
* internally instead of sending a request to a separate Command
|
||||
* Invoker process.
|
||||
*
|
||||
* For local execution, the "fork" and "execvp" system calls are
|
||||
* used. For remote execution, the "SPCD" is used.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
extern void
|
||||
_DtInitializeCommandInvoker(
|
||||
Display *display,
|
||||
char *toolClass,
|
||||
char *applicationClass,
|
||||
DtSvcReceiveProc reloadDBHandler,
|
||||
XtAppContext appContext);
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function: void _DtCommandInvokerExecute (
|
||||
* char *request_name,
|
||||
* char *context_host,
|
||||
* char *context_dir,
|
||||
* char *context_file,
|
||||
* char *exec_parameters,
|
||||
* char *exec_host,
|
||||
* char *exec_string,
|
||||
* DtCmdInvExecProc success_proc,
|
||||
* void *success_data,
|
||||
* DtCmdInvExecProc failure_proc,
|
||||
* void *failure_data)
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* request_name - The request name (defined in "CommandM.h").
|
||||
*
|
||||
* context_host - Name of the host where request is executed from. If
|
||||
* NULL, the "exec_host" parameter is used. Note: this
|
||||
* should not be confused with execution host, described
|
||||
* below.
|
||||
*
|
||||
* context_dir - Directory where the request should be executed. If
|
||||
* NULL, the HOME directory is used.
|
||||
*
|
||||
* context_file - Not currently used by the Command Invoker.
|
||||
*
|
||||
* exec_parameters - Command Invoker execution parameters. See External
|
||||
* Specification for more information.
|
||||
* If set to NULL, "-" is used.
|
||||
*
|
||||
* exec_host - Name of the host where the request is executed.
|
||||
*
|
||||
* exec_string - The command line to execute.
|
||||
*
|
||||
* success_proc - The function to be invoked if the request is
|
||||
* successfully executed.
|
||||
*
|
||||
* success_data - Client data for successful execution.
|
||||
*
|
||||
* failure_proc - The function to be invoked if an attempt to exeucte
|
||||
* the request fails.
|
||||
*
|
||||
* failure_data - Client data for unsuccessful execution.
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* This function allows a client to use the DT "Command Invoker"
|
||||
* Library for its' process execution. This function is intended
|
||||
* for processes which do not use the Action Library.
|
||||
*
|
||||
* For local execution, the "fork" and "execvp" system calls are
|
||||
* used. For remote execution, the "SPCD" is used.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* This function must be preceeded by a call to
|
||||
* "_DtInitializeCommandInvoker".
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
extern void
|
||||
_DtCommandInvokerExecute(
|
||||
char *request_name,
|
||||
char *context_host,
|
||||
char *context_dir,
|
||||
char *context_file,
|
||||
char *exec_parameters,
|
||||
char *exec_host,
|
||||
char *exec_string,
|
||||
DtCmdInvExecuteProc success_proc,
|
||||
void *success_data,
|
||||
DtCmdInvExecuteProc failure_proc,
|
||||
void *failure_data);
|
||||
|
||||
extern SPC_Channel_Ptr _DtSPCOpen( char *hostname,
|
||||
int iomode,
|
||||
char *errorMessage); /* MODIFIED */
|
||||
|
||||
extern int _DtSPCSpawn(
|
||||
char *path,
|
||||
char *context,
|
||||
char **args,
|
||||
char **env,
|
||||
SPC_Channel_Ptr chan,
|
||||
char *execHost,
|
||||
char *contextHost,
|
||||
char *contextDir,
|
||||
char *errorMessage); /* MODIFIED */
|
||||
|
||||
#endif /* _CmdInv_h */
|
||||
184
cde/lib/DtSvc/DtUtil1/CmdInvP.h
Normal file
184
cde/lib/DtSvc/DtUtil1/CmdInvP.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/* $TOG: CmdInvP.h /main/5 1998/07/30 12:10:30 mgreess $ */
|
||||
/***************************************************************************
|
||||
*
|
||||
* File: CmdInvP.h
|
||||
* Description: Command execution system private externs and includes
|
||||
* Language: C
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _CmdInvP_h
|
||||
#define _CmdInvP_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h> /* MAXPATHNAMELEN */
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#include <Dt/DtP.h>
|
||||
#include <Dt/DtNlUtils.h>
|
||||
#include <Dt/Message.h>
|
||||
#include <bms/SbEvent.h>
|
||||
#include <bms/XeUserMsg.h>
|
||||
#include <Dt/Spc.h>
|
||||
#include <Dt/CmdInv.h>
|
||||
#include <Dt/ActionP.h>
|
||||
#include <Dt/Connect.h>
|
||||
|
||||
#ifndef CDE_INSTALLATION_TOP
|
||||
#define CDE_INSTALLATION_TOP "/opt/dt"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Resource names and classes for the Command Invoker.
|
||||
*/
|
||||
#define DtLOCAL_TERMINAL_NAME "localTerminal"
|
||||
#define DtLOCAL_TERMINAL_CLASS "LocalTerminal"
|
||||
|
||||
#define DtREMOTE_TERMINALS_NAME "remoteTerminals"
|
||||
#define DtREMOTE_TERMINALS_CLASS "RemoteTerminals"
|
||||
|
||||
#define DtWAIT_TIME_NAME "waitTime"
|
||||
#define DtWAIT_TIME_CLASS "WaitTime"
|
||||
|
||||
#define DtDTEXEC_PATH_NAME "dtexecPath"
|
||||
#define DtDTEXEC_PATH_CLASS "DtexecPath"
|
||||
|
||||
#define DtEXECUTION_HOST_LOGGING_NAME "executionHostLogging"
|
||||
#define DtEXECUTION_HOST_LOGGING_CLASS "ExecutionHostLogging"
|
||||
|
||||
|
||||
/*
|
||||
* Structure for saving the "state" of a remote request that is
|
||||
* queued while waiting for a remote subprocess to terminate.
|
||||
*/
|
||||
typedef struct _Cmd_RequestQueue {
|
||||
SPC_Channel_Ptr channel;
|
||||
char *context;
|
||||
char *exec_host;
|
||||
char *exec_string;
|
||||
char **argv;
|
||||
int winType;
|
||||
unsigned long request_num;
|
||||
DtSvcMsgContext replyContext;
|
||||
DtCmdInvExecuteProc success_proc;
|
||||
void *success_data;
|
||||
DtCmdInvExecuteProc failure_proc;
|
||||
void *failure_data;
|
||||
struct _Cmd_RequestQueue *next;
|
||||
} Cmd_RequestQueue;
|
||||
|
||||
/*
|
||||
* Command invocation resources.
|
||||
*/
|
||||
typedef struct {
|
||||
char *localTerminal;
|
||||
char **remoteHosts;
|
||||
char **remoteTerminals;
|
||||
int waitTime;
|
||||
char *dtexecPath;
|
||||
Boolean executionHostLogging;
|
||||
} Cmd_Resources;
|
||||
|
||||
/*
|
||||
* Command invocation global variables.
|
||||
*/
|
||||
typedef struct {
|
||||
Boolean terminal_ok;
|
||||
Boolean subprocess_ok;
|
||||
XtAppContext app_context;
|
||||
char **path_list;
|
||||
char *error_directory_name_map;
|
||||
char *error_subprocess;
|
||||
char *error_terminal;
|
||||
} Cmd_Globals;
|
||||
|
||||
/*
|
||||
* Defaults for the Resources.
|
||||
*/
|
||||
#define DtWAIT_TIME_DEFAULT 3 /* In seconds. */
|
||||
#define DtTERMINAL_DEFAULT "dtterm"
|
||||
|
||||
#define DtCMD_INV_SUB_PROCESS CDE_INSTALLATION_TOP "/bin/dtexec"
|
||||
|
||||
/*
|
||||
* Temporary buffer size.
|
||||
*/
|
||||
#define MAX_BUF_SIZE 1024
|
||||
|
||||
/*
|
||||
* Window types:
|
||||
*/
|
||||
#define NO_STDIO 0
|
||||
#define TERMINAL 1
|
||||
#define PERM_TERMINAL 2
|
||||
|
||||
/*
|
||||
* Command execution return status:
|
||||
*/
|
||||
#define _CMD_EXECUTE_SUCCESS 1
|
||||
#define _CMD_EXECUTE_FAILURE 2
|
||||
#define _CMD_EXECUTE_QUEUED 3
|
||||
#define _CMD_EXECUTE_FATAL 4
|
||||
|
||||
/*
|
||||
* External declarations for the global Command Invoker variables.
|
||||
*/
|
||||
extern Cmd_Resources cmd_Resources;
|
||||
extern Cmd_Globals cmd_Globals;
|
||||
|
||||
/*
|
||||
******* Public Function Declarations for CmdSpc.c *******
|
||||
*/
|
||||
|
||||
extern SbInputId _DtCmdSPCAddInputHandler (
|
||||
int fd,
|
||||
SbInputCallbackProc proc,
|
||||
void *data);
|
||||
extern SbInputId _DtCmdSPCAddExceptionHandler (
|
||||
int fd,
|
||||
SbInputCallbackProc proc,
|
||||
void *data);
|
||||
extern void _DtCmdLogErrorMessage(
|
||||
char *message) ;
|
||||
|
||||
|
||||
/*
|
||||
******* Public Function Declarations for CmdProcess.c *******
|
||||
*/
|
||||
|
||||
extern void _DtCmdCreateTerminalCommand(
|
||||
char **theCommand,
|
||||
int windowType,
|
||||
char *execString,
|
||||
char *execParms,
|
||||
char *execHost,
|
||||
char *procId,
|
||||
char *tmpFiles) ;
|
||||
extern Boolean _DtCmdCheckForExecutable(
|
||||
char *fileName) ;
|
||||
extern Boolean _DtCmdValidDir(
|
||||
char *clientHost,
|
||||
char *contextDir,
|
||||
char *contextHost) ;
|
||||
extern void _DtCmdGetResources(
|
||||
Display *display);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
******* Public Function Declarations for CmdUtilityP.c *******
|
||||
*/
|
||||
|
||||
extern void _DtCmdBuildPathList( void ) ;
|
||||
|
||||
/******** End Public Function Declarations ********/
|
||||
|
||||
#endif /* _CmdInvP_h */
|
||||
1440
cde/lib/DtSvc/DtUtil1/CmdMain.c
Normal file
1440
cde/lib/DtSvc/DtUtil1/CmdMain.c
Normal file
File diff suppressed because it is too large
Load Diff
792
cde/lib/DtSvc/DtUtil1/CmdProcess.c
Normal file
792
cde/lib/DtSvc/DtUtil1/CmdProcess.c
Normal file
@@ -0,0 +1,792 @@
|
||||
/* $TOG: CmdProcess.c /main/8 1998/04/09 17:47:13 mgreess $ */
|
||||
/***************************************************************************
|
||||
*
|
||||
* File: CmdProcess.c
|
||||
* Description: Miscellaneous functions for the command execution system
|
||||
* Language: C
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
***************************************************************************/
|
||||
|
||||
#include "CmdInvP.h"
|
||||
|
||||
#include <X11/Xproto.h>
|
||||
#include <Dt/CommandM.h>
|
||||
#include <Dt/DtNlUtils.h>
|
||||
#include <Dt/ActionUtilP.h>
|
||||
#include "myassertP.h"
|
||||
|
||||
#if defined(sun) || defined(USL) || defined(__uxp__)
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#if defined(__hp_osf) || defined (__osf__)
|
||||
#include <sys/access.h>
|
||||
#else
|
||||
#if defined(__hpux)
|
||||
#include <sys/getaccess.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <Tt/tt_c.h>
|
||||
|
||||
/*
|
||||
* Global variables:
|
||||
*/
|
||||
Cmd_Resources cmd_Resources = { 0 };
|
||||
Cmd_Globals cmd_Globals = { 0 };
|
||||
|
||||
/******** Static Function Declarations ********/
|
||||
|
||||
static char *_GetRemoteTerminalsResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName);
|
||||
static void GetRemoteTerminalsResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName);
|
||||
static void GetLocalTerminalResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName);
|
||||
static void GetWaitTimeResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName);
|
||||
static void GetDtexecPath (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName);
|
||||
static void GetExecutionHostLoggingResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName);
|
||||
static char *GetRemoteTerminal(
|
||||
char *host);
|
||||
|
||||
/******** End Static Function Declarations ********/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _GetRemoteTerminalsResource - gets the value of the "remoteTerminals"
|
||||
* resource.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
* char *appName; The client's application name.
|
||||
*
|
||||
* RETURNS: a pointer to the "remoteTerminals" resource or NULL if the
|
||||
* resource is not defined.
|
||||
*
|
||||
* NOTES: The space for the returned string is "malloc'ed". The calling
|
||||
* function should free the string.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static char
|
||||
*_GetRemoteTerminalsResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName)
|
||||
{
|
||||
XrmValue resource_value;
|
||||
XrmDatabase db;
|
||||
char *rep_type;
|
||||
char *name;
|
||||
char *class;
|
||||
char *terminals = NULL;
|
||||
|
||||
name = XtMalloc (strlen (DtREMOTE_TERMINALS_NAME) + strlen (appName) + 4);
|
||||
sprintf (name, "%s*%s", appName, DtREMOTE_TERMINALS_NAME);
|
||||
|
||||
class = XtMalloc (strlen (DtREMOTE_TERMINALS_CLASS) + strlen (appClass) + 4);
|
||||
sprintf (class, "%s*%s", appClass, DtREMOTE_TERMINALS_CLASS);
|
||||
|
||||
db = XtDatabase (display);
|
||||
if (XrmGetResource (db, name, class, &rep_type, &resource_value))
|
||||
terminals = (char *) XtNewString (resource_value.addr);
|
||||
|
||||
XtFree (name);
|
||||
XtFree (class);
|
||||
|
||||
return (terminals);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GetRemoteTerminalsResource - initializes the "remoteTerminals" resource.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
* char *appName; The client's application name.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char *cmd_Resources.remoteTerminals; - Set to the list of remote
|
||||
* terminals.
|
||||
*
|
||||
* char *cmd_Resources.remoteHosts; - Set to the list of remote hosts..
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
GetRemoteTerminalsResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName)
|
||||
{
|
||||
int num, j;
|
||||
char *terminals;
|
||||
char *pch, *host;
|
||||
|
||||
if ((terminals = _GetRemoteTerminalsResource (display, appClass, appName))
|
||||
== NULL) {
|
||||
/*
|
||||
* The resource was not specified, and no defaults are set.
|
||||
*/
|
||||
cmd_Resources.remoteHosts = (char **) NULL;
|
||||
cmd_Resources.remoteTerminals = (char **) NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out how many terminals are specified by counting the number of
|
||||
* colons.
|
||||
*/
|
||||
for (pch=terminals, num=0; pch != NULL ; ) {
|
||||
if ((pch = DtStrchr (pch, ':')) != NULL) {
|
||||
/*
|
||||
* Move past the ':'.
|
||||
*/
|
||||
pch++;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num == 0) {
|
||||
/*
|
||||
* No "host:/terminal" pairs were found.
|
||||
*/
|
||||
cmd_Resources.remoteHosts = (char **) NULL;
|
||||
cmd_Resources.remoteTerminals = (char **) NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create space for the pointers to the hosts and terminals and
|
||||
* make room for a NULL terminator.
|
||||
*
|
||||
* Note that the host names and terminal names are "vectorized" in
|
||||
* place by replacing the ':' and ',' characters with '\0'.
|
||||
*/
|
||||
|
||||
cmd_Resources.remoteHosts = (char **) XtMalloc (num * sizeof(char *));
|
||||
cmd_Resources.remoteTerminals = (char **) XtMalloc (num * sizeof(char *));
|
||||
|
||||
for (pch=terminals, j=0; j < num && pch != NULL && *pch != '\0'; j++)
|
||||
{
|
||||
|
||||
host = pch;
|
||||
|
||||
if ((pch = DtStrchr (pch, ':')) == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Null terminate the host and then move past the ':'.
|
||||
*/
|
||||
*pch = '\0';
|
||||
pch++;
|
||||
|
||||
if (*pch == '\0')
|
||||
/*
|
||||
* Found a host but nothing followed it.
|
||||
*/
|
||||
break;
|
||||
|
||||
cmd_Resources.remoteHosts[j] = host;
|
||||
cmd_Resources.remoteTerminals[j] = pch;
|
||||
|
||||
/*
|
||||
* Find the end of this entry and skip past it.
|
||||
*/
|
||||
if ((pch = DtStrchr (pch, ',')) == NULL) {
|
||||
/*
|
||||
* This is the last pair, advance "j" and break the loop.
|
||||
*/
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* End the terminal name.
|
||||
*/
|
||||
*pch = '\0';
|
||||
pch++;
|
||||
}
|
||||
|
||||
/*
|
||||
* NULL terminate the arrays.
|
||||
*/
|
||||
cmd_Resources.remoteHosts[j] = (char *) NULL;
|
||||
cmd_Resources.remoteTerminals[j] = (char *) NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GetLocalTerminalResource - initializes the "localTerminal resource.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
* char *appName; The client's application name.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char *cmd_Resources.localTerminal; - Set to the "localTerminal"
|
||||
* or to DtDEFUALT_TERMINAL.
|
||||
*
|
||||
* Boolean cmd_Globals.terminal_ok; - Set to True if "localTerminal"
|
||||
* is executable and has the correct
|
||||
* permissions; False otherwise.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
GetLocalTerminalResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName)
|
||||
{
|
||||
XrmValue resource_value;
|
||||
char *rep_type;
|
||||
char *name;
|
||||
char *class;
|
||||
XrmDatabase db = XtDatabase (display);
|
||||
|
||||
name = XtMalloc (strlen (DtLOCAL_TERMINAL_NAME) + strlen (appName) + 4);
|
||||
sprintf (name, "%s*%s", appName, DtLOCAL_TERMINAL_NAME);
|
||||
|
||||
class = XtMalloc (strlen (DtLOCAL_TERMINAL_CLASS) + strlen (appClass) + 4);
|
||||
sprintf (class, "%s*%s", appClass, DtLOCAL_TERMINAL_CLASS);
|
||||
|
||||
if (XrmGetResource (db, name, class, &rep_type, &resource_value))
|
||||
cmd_Resources.localTerminal = (char *) XtNewString (resource_value.addr);
|
||||
else
|
||||
cmd_Resources.localTerminal = XtNewString (DtTERMINAL_DEFAULT);
|
||||
|
||||
/*
|
||||
* Check to see if the execvp will potentially fail because the
|
||||
* localTerminal is not accessable or it it is not executable. If not,
|
||||
* log an error message.
|
||||
*/
|
||||
cmd_Globals.terminal_ok = True;
|
||||
if (!(_DtCmdCheckForExecutable (cmd_Resources.localTerminal))) {
|
||||
char *errorMessage = XtMalloc(MAX_BUF_SIZE);
|
||||
|
||||
cmd_Globals.terminal_ok = False;
|
||||
if (errorMessage)
|
||||
{
|
||||
(void) sprintf (errorMessage,
|
||||
cmd_Globals.error_terminal,
|
||||
cmd_Resources.localTerminal);
|
||||
_DtCmdLogErrorMessage (errorMessage);
|
||||
XtFree(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
XtFree (name);
|
||||
XtFree (class);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GetWaitTimeResource - initializes the "waitTime" resource.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
* char *appName; The client's application name.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char *cmd_Resources.waitTime; - Set to the "waitTime" resource
|
||||
* or "True" by default.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
GetWaitTimeResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName)
|
||||
{
|
||||
XrmValue resource_value;
|
||||
char *rep_type;
|
||||
char *name;
|
||||
char *class;
|
||||
XrmDatabase db= XtDatabase (display);
|
||||
|
||||
cmd_Resources.waitTime = DtWAIT_TIME_DEFAULT;
|
||||
|
||||
name = XtMalloc (strlen (DtWAIT_TIME_NAME) + strlen (appName) + 4);
|
||||
sprintf (name, "%s*%s", appName, DtWAIT_TIME_NAME);
|
||||
|
||||
class = XtMalloc (strlen (DtWAIT_TIME_CLASS) + strlen (appClass) + 4);
|
||||
sprintf (class, "%s*%s", appClass, DtWAIT_TIME_CLASS);
|
||||
|
||||
if (XrmGetResource (db, name, class, &rep_type, &resource_value)) {
|
||||
cmd_Resources.waitTime = atoi (resource_value.addr);
|
||||
if (cmd_Resources.waitTime < 0)
|
||||
cmd_Resources.waitTime = DtWAIT_TIME_DEFAULT;
|
||||
}
|
||||
|
||||
XtFree (name);
|
||||
XtFree (class);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GetDtexecPath - initializes the "dtexecPath" resource.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
* char *appName; The client's application name.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char *cmd_Resources.dtexecPath; - Set to the "dtexecPath" resource
|
||||
* or to DtCMD_INV_SUB_PROCESS.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
GetDtexecPath (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName)
|
||||
{
|
||||
XrmValue resource_value;
|
||||
char *rep_type;
|
||||
char errorMessage [MAX_BUF_SIZE];
|
||||
char *name;
|
||||
char *class;
|
||||
XrmDatabase db = XtDatabase (display);
|
||||
|
||||
name = XtMalloc (strlen (DtDTEXEC_PATH_NAME) + strlen (appName) + 4);
|
||||
sprintf (name, "%s*%s", appName, DtDTEXEC_PATH_NAME);
|
||||
|
||||
class = XtMalloc (strlen (DtDTEXEC_PATH_CLASS) + strlen (appClass) + 4);
|
||||
sprintf (class, "%s*%s", appClass, DtDTEXEC_PATH_CLASS);
|
||||
|
||||
if (XrmGetResource (db, name, class, &rep_type, &resource_value))
|
||||
cmd_Resources.dtexecPath = (char *) XtNewString (resource_value.addr);
|
||||
else
|
||||
cmd_Resources.dtexecPath = XtNewString (DtCMD_INV_SUB_PROCESS);
|
||||
|
||||
/*
|
||||
* Check to see if the execvp will potentially fail because the
|
||||
* subprocess is not accessable or it it is not executable. If not,
|
||||
* log an error message.
|
||||
*/
|
||||
cmd_Globals.subprocess_ok = True;
|
||||
if (!(_DtCmdCheckForExecutable (cmd_Resources.dtexecPath))) {
|
||||
char *errorMessage = XtMalloc(MAX_BUF_SIZE);
|
||||
|
||||
cmd_Globals.subprocess_ok = False;
|
||||
if (errorMessage)
|
||||
{
|
||||
(void) sprintf (errorMessage,
|
||||
cmd_Globals.error_subprocess,
|
||||
cmd_Resources.dtexecPath);
|
||||
_DtCmdLogErrorMessage (errorMessage);
|
||||
XtFree(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
XtFree (name);
|
||||
XtFree (class);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GetExecutionHostLoggingResources - initializes the "executionHostLogging"
|
||||
*
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
* char *appName; The client's application name.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char *cmd_Resources.executionHostLogging;
|
||||
*
|
||||
* - Set to the "executionHostLogging" resource or "False" by default.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void
|
||||
GetExecutionHostLoggingResource (
|
||||
Display *display,
|
||||
char *appClass,
|
||||
char *appName)
|
||||
{
|
||||
XrmValue resource_value;
|
||||
char *rep_type;
|
||||
char *name;
|
||||
char *class;
|
||||
XrmDatabase db= XtDatabase (display);
|
||||
|
||||
cmd_Resources.executionHostLogging = False;
|
||||
|
||||
name = XtMalloc (strlen (DtEXECUTION_HOST_LOGGING_NAME) +
|
||||
strlen (appName) + 4);
|
||||
sprintf (name, "%s*%s", appName, DtEXECUTION_HOST_LOGGING_NAME);
|
||||
|
||||
class = XtMalloc (strlen (DtEXECUTION_HOST_LOGGING_CLASS) +
|
||||
strlen (appClass) + 4);
|
||||
sprintf (class, "%s*%s", appClass, DtEXECUTION_HOST_LOGGING_CLASS);
|
||||
|
||||
if (XrmGetResource (db, name, class, &rep_type, &resource_value)) {
|
||||
if (((strcmp (resource_value.addr, "True")) == 0) ||
|
||||
((strcmp (resource_value.addr, "true")) == 0) ||
|
||||
((strcmp (resource_value.addr, "TRUE")) == 0))
|
||||
cmd_Resources.executionHostLogging = True;
|
||||
else if (((strcmp (resource_value.addr, "False")) == 0) ||
|
||||
((strcmp (resource_value.addr, "false")) == 0) ||
|
||||
((strcmp (resource_value.addr, "FALSE")) == 0))
|
||||
cmd_Resources.executionHostLogging = False;
|
||||
}
|
||||
|
||||
XtFree (name);
|
||||
XtFree (class);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* GetRemoteTerminal - takes a host name "host" and searches the list of remote
|
||||
* host:terminal pairs for "host" and if found, returns the corresponding
|
||||
* terminal emulator.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* char *host; - Name of the host to use as the key to find
|
||||
* the terminal emulator name.
|
||||
*
|
||||
* RETURNS: If "host" is found, the corresponding terminal emulator is
|
||||
* returned, otherwise "NULL" is returned.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static char *
|
||||
GetRemoteTerminal(
|
||||
char *host )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cmd_Resources.remoteHosts == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (i=0; cmd_Resources.remoteHosts[i] != NULL; i++) {
|
||||
if ((strcmp (host, cmd_Resources.remoteHosts[i])) == 0)
|
||||
return (cmd_Resources.remoteTerminals[i]);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdCreateTerminalCommand - takes a windowType, execString
|
||||
* and execParms and creates an appropriate command to execute.
|
||||
*
|
||||
* Note that if valid execParms are found, they are simply added
|
||||
* to the execution string, before the "-e" option.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* char **theCommand; - The command line to be expanded and returned.
|
||||
* int windowType; - The request number (window number).
|
||||
* char *execString; - The execution string to be expanded.
|
||||
* char *execParms; - The execution parameters.
|
||||
* char *procId - tooltalk procId for dtexec
|
||||
* char *tmpFiles - string containing tmp file args for dtexec
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char ** theCommand; - Contains the completed execution string.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
_DtCmdCreateTerminalCommand(
|
||||
char **theCommand,
|
||||
int windowType,
|
||||
char *execString,
|
||||
char *execParms,
|
||||
char *execHost,
|
||||
char *procId,
|
||||
char *tmpFiles)
|
||||
{
|
||||
char *pGeom = NULL;
|
||||
char *pName = NULL;
|
||||
char *pTitle = NULL;
|
||||
char options[MAX_BUF_SIZE];
|
||||
char *defaultTerminal;
|
||||
|
||||
strcpy(options,execParms);
|
||||
|
||||
/*
|
||||
* Get the name of the terminal emulator to use.
|
||||
*/
|
||||
if ((defaultTerminal = GetRemoteTerminal (execHost)) == NULL)
|
||||
defaultTerminal = cmd_Resources.localTerminal;
|
||||
|
||||
/*
|
||||
* Create space for the expanded command line.
|
||||
*/
|
||||
*theCommand = (char *) XtMalloc ( strlen (defaultTerminal)
|
||||
+ strlen(options)
|
||||
+ strlen(cmd_Resources.dtexecPath)
|
||||
+ strlen(" -open ") + 4 /* max waitTime len */
|
||||
+ strlen(" -ttprocid ") + strlen(_DtActNULL_GUARD(procId))
|
||||
+ strlen(_DtActNULL_GUARD(tmpFiles))
|
||||
+ strlen(execString) + 9 /* 2 quotes, "-e", 7 blanks, null */ );
|
||||
|
||||
if (windowType == TERMINAL) {
|
||||
(void) sprintf (*theCommand, "%s %s -e %s -open %d -ttprocid '%s' %s %s",
|
||||
defaultTerminal, options, cmd_Resources.dtexecPath,
|
||||
cmd_Resources.waitTime,
|
||||
_DtActNULL_GUARD(procId),
|
||||
_DtActNULL_GUARD(tmpFiles),
|
||||
execString);
|
||||
}
|
||||
else {
|
||||
(void) sprintf (*theCommand, "%s %s -e %s -open -1 -ttprocid '%s' %s %s",
|
||||
defaultTerminal, options, cmd_Resources.dtexecPath,
|
||||
_DtActNULL_GUARD(procId),
|
||||
_DtActNULL_GUARD(tmpFiles),
|
||||
execString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdCheckForExecutable - checks "fileName" to see if it is executable
|
||||
* by the user.
|
||||
*
|
||||
* PARAMETERES:
|
||||
*
|
||||
* char *fileName; - The name of the file to check.
|
||||
*
|
||||
* RETURNS: "True" if the file is access'able && executable, "False" otherwise.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
Boolean
|
||||
_DtCmdCheckForExecutable(
|
||||
char *fileName )
|
||||
{
|
||||
char **ppch;
|
||||
int access;
|
||||
|
||||
|
||||
/* First check to see if the fileName contains the complete path
|
||||
* and is access'able.
|
||||
*/
|
||||
|
||||
switch (access = _DtExecuteAccess(fileName))
|
||||
{
|
||||
/* execution access allowed for this process */
|
||||
case 1: return True;
|
||||
break;
|
||||
/* file found -- not executable by this process */
|
||||
case 0: return False;
|
||||
break;
|
||||
/* file not found -- yet */
|
||||
case -1: /* fall through */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Append fileName to each entry in "cmd_Globals.path_list" and then see
|
||||
* if that is accessable.
|
||||
*/
|
||||
|
||||
for (ppch = cmd_Globals.path_list; *ppch != NULL; ppch++)
|
||||
{
|
||||
char *longName = XtMalloc(MAXPATHLEN);
|
||||
|
||||
if (longName)
|
||||
{
|
||||
(void) sprintf (longName, "%s/%s", *ppch, fileName);
|
||||
switch (access = _DtExecuteAccess(longName))
|
||||
{
|
||||
/* execution access allowed for this process */
|
||||
case 1: return True;
|
||||
break;
|
||||
/* file found -- not executable by this process */
|
||||
case 0: return False;
|
||||
break;
|
||||
/* file not found -- yet */
|
||||
case -1: /* fall through */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
XtFree(longName);
|
||||
}
|
||||
}
|
||||
|
||||
return (False);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdValidDir - takes the client host, context directory and a context host
|
||||
* and checks to see if the directory is valid.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* char *clientHost; - Host where the client is running.
|
||||
*
|
||||
* char *contextDir; - Directory to "chdir" to.
|
||||
*
|
||||
* char *contextHost; - Host where 'contextDir' resides.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* If the context directory is NULL, "chdir" is not run and "True" is
|
||||
* returned.
|
||||
*
|
||||
* RETURNS: "True" if "chdir" succeeds and "False" otherwise.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
Boolean
|
||||
_DtCmdValidDir(
|
||||
char *clientHost,
|
||||
char *contextDir,
|
||||
char *contextHost )
|
||||
{
|
||||
int retValue = 0;
|
||||
|
||||
if (contextDir == NULL)
|
||||
/*
|
||||
* Stay in the same directory.
|
||||
*/
|
||||
return (True);
|
||||
if (contextHost == NULL)
|
||||
/*
|
||||
* Change to 'contextDir'.
|
||||
*/
|
||||
retValue = chdir (contextDir);
|
||||
else if (_DtIsSameHost (clientHost, contextHost))
|
||||
/*
|
||||
* Just change to 'contextDir'.
|
||||
*/
|
||||
retValue = chdir (contextDir);
|
||||
else {
|
||||
/*
|
||||
* Need to create a pathname for the directory.
|
||||
*/
|
||||
char *netfile;
|
||||
char *path;
|
||||
char *errorMessage = XtMalloc(MAX_BUF_SIZE);
|
||||
|
||||
/* Old syntax should no longer appear in contextHost/Dir */
|
||||
myassert( *contextHost != '*' && *contextDir != '*' );
|
||||
netfile = (char *) tt_host_file_netfile (contextHost, contextDir);
|
||||
if (tt_pointer_error (netfile) != TT_OK) {
|
||||
(void) sprintf (errorMessage, cmd_Globals.error_directory_name_map,
|
||||
contextDir, contextHost,
|
||||
tt_status_message (tt_pointer_error(netfile)));
|
||||
_DtCmdLogErrorMessage (errorMessage);
|
||||
return (False);
|
||||
}
|
||||
|
||||
path = (char *) tt_netfile_file (netfile);
|
||||
tt_free (netfile);
|
||||
if (tt_pointer_error (path) != TT_OK) {
|
||||
(void) sprintf (errorMessage, cmd_Globals.error_directory_name_map,
|
||||
contextDir, contextHost,
|
||||
tt_status_message (tt_pointer_error(path)));
|
||||
_DtCmdLogErrorMessage (errorMessage);
|
||||
return (False);
|
||||
}
|
||||
|
||||
retValue = chdir (path);
|
||||
tt_free (path);
|
||||
if (errorMessage) XtFree(errorMessage);
|
||||
}
|
||||
|
||||
if (retValue == -1)
|
||||
return (False);
|
||||
else
|
||||
return (True);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdGetResources - initializes the Command Invoker's resources.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* Display *display; The connection to the X server.
|
||||
*
|
||||
* char *appClass; The client's application class.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
_DtCmdGetResources (
|
||||
Display *display)
|
||||
{
|
||||
char *appClass = NULL;
|
||||
char *appName = NULL;
|
||||
|
||||
/*
|
||||
* Determine the name and class for this client.
|
||||
*/
|
||||
XtGetApplicationNameAndClass (display, &appName, &appClass);
|
||||
|
||||
GetLocalTerminalResource (display, appClass, appName);
|
||||
|
||||
GetRemoteTerminalsResource (display, appClass, appName);
|
||||
|
||||
GetWaitTimeResource (display, appClass, appName);
|
||||
|
||||
GetDtexecPath (display, appClass, appName);
|
||||
|
||||
GetExecutionHostLoggingResource (display, appClass, appName);
|
||||
}
|
||||
99
cde/lib/DtSvc/DtUtil1/CmdSpc.c
Normal file
99
cde/lib/DtSvc/DtUtil1/CmdSpc.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* $XConsortium: CmdSpc.c /main/4 1995/10/26 15:02:34 rswiston $ */
|
||||
/***************************************************************************
|
||||
*
|
||||
* File: CmdSpc.c
|
||||
* Description: Messaging support for the command execution system.
|
||||
* Language: C
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
***************************************************************************/
|
||||
|
||||
#include "CmdInvP.h"
|
||||
|
||||
#include <Dt/UserMsg.h>
|
||||
#include <Dt/CommandM.h>
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdSPCAddInputHandler - Register the Command Invoker AddInputHandler
|
||||
*
|
||||
* PARAMETERS: Those need by a SPC Add Input Handler.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* This function is needed by SPC to get a process termination
|
||||
* callback to get invoked.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
SbInputId
|
||||
_DtCmdSPCAddInputHandler (
|
||||
int fd,
|
||||
SbInputCallbackProc proc,
|
||||
void *data)
|
||||
{
|
||||
if (cmd_Globals.app_context == NULL)
|
||||
return(XtAddInput(fd,
|
||||
(XtPointer) XtInputReadMask,
|
||||
proc,
|
||||
data));
|
||||
else
|
||||
return(XtAppAddInput(cmd_Globals.app_context,
|
||||
fd,
|
||||
(XtPointer) XtInputReadMask,
|
||||
proc,
|
||||
data));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdSPCAddExceptionHandler - Register the Command Invoker AddExceptionHandler
|
||||
*
|
||||
* PARAMETERS: Those need by a SPC Add Exception Input Handler.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* This function is needed by SPC to get a process termination
|
||||
* callback to get invoked.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
SbInputId
|
||||
_DtCmdSPCAddExceptionHandler (
|
||||
int fd,
|
||||
SbInputCallbackProc proc,
|
||||
void *data)
|
||||
{
|
||||
if (cmd_Globals.app_context == NULL)
|
||||
return(XtAddInput(fd,
|
||||
(XtPointer) XtInputExceptMask,
|
||||
proc,
|
||||
data));
|
||||
else
|
||||
return(XtAppAddInput(cmd_Globals.app_context,
|
||||
fd,
|
||||
(XtPointer) XtInputExceptMask,
|
||||
proc,
|
||||
data));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtCmdLogErrorMessage - write an error message to the default log file.
|
||||
*
|
||||
* PARAMETERS:
|
||||
*
|
||||
* char *message; - The error message to log.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
_DtCmdLogErrorMessage(
|
||||
char *message )
|
||||
{
|
||||
_DtSimpleError (DtProgName, DtError, NULL, "%.2000s", message);
|
||||
}
|
||||
96
cde/lib/DtSvc/DtUtil1/CmdUtilityP.c
Normal file
96
cde/lib/DtSvc/DtUtil1/CmdUtilityP.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* $XConsortium: CmdUtilityP.c /main/4 1995/10/26 15:02:50 rswiston $ */
|
||||
/***************************************************************************
|
||||
*
|
||||
* File: CmdUtilityP.c
|
||||
* Description: Private Utility routines for the command invocation system.
|
||||
* Language: C
|
||||
*
|
||||
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
** (c) Copyright 1993, 1994 Novell, Inc.
|
||||
***************************************************************************/
|
||||
|
||||
#include "CmdInvP.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef __apollo
|
||||
#include "/sys5/usr/include/unistd.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Dt/CommandM.h>
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* _DtCmdBuildPathList - this functions builds a list of the path names
|
||||
* that are part of the $PATH environment variable. This is done once
|
||||
* during initialization and the list is then searched whenever
|
||||
* a command is going to be executed.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* char **cmd_Globals.path_list; - Initialized or set to NULL if
|
||||
* $PATH is undefined
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
_DtCmdBuildPathList( void )
|
||||
{
|
||||
int i=0;
|
||||
char *path;
|
||||
int indx;
|
||||
int n=0, pathLen;
|
||||
char *pend, /* Points to the beginning of a directory */
|
||||
*pbeg; /* Points to the end of a directory */
|
||||
|
||||
/* Get the PATH */
|
||||
if ((path = (char *) (getenv ("PATH"))) == NULL) {
|
||||
cmd_Globals.path_list = (char **) NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
pathLen = strlen(path);
|
||||
pbeg = path;
|
||||
|
||||
while (i < pathLen) {
|
||||
n++;
|
||||
cmd_Globals.path_list = (char **) XtRealloc ((char *)cmd_Globals.path_list, n * sizeof (char *));
|
||||
|
||||
if ((indx = DtStrcspn (pbeg, ":")) >= pathLen) {
|
||||
/* At the end of the path */
|
||||
i = pathLen;
|
||||
pend = (char *) pbeg + indx;
|
||||
}
|
||||
else {
|
||||
/* Found a ":" */
|
||||
pend = (char *) pbeg + indx;
|
||||
i += (pend - pbeg) +1;
|
||||
}
|
||||
|
||||
cmd_Globals.path_list[n-1] = (char *) XtMalloc (((pend - pbeg) + 1) *
|
||||
sizeof(char));
|
||||
(void) strncpy (cmd_Globals.path_list[n-1], pbeg, (pend - pbeg));
|
||||
/* Strncpy does not put a '\0' at the EOS if s2 >= s1 */
|
||||
cmd_Globals.path_list[n-1][pend-pbeg] = '\0';
|
||||
|
||||
/* Move past the ":" */
|
||||
if (i < pathLen)
|
||||
pbeg = pend +1;
|
||||
}
|
||||
|
||||
/* May need to NULL terminate cmd_Globals.path_list */
|
||||
if (n > 0) {
|
||||
n++;
|
||||
cmd_Globals.path_list = (char **) XtRealloc ((char *) cmd_Globals.path_list, n * sizeof (char *));
|
||||
cmd_Globals.path_list [n-1] = (char *) NULL;
|
||||
}
|
||||
}
|
||||
304
cde/lib/DtSvc/DtUtil1/DbLoad.c
Normal file
304
cde/lib/DtSvc/DtUtil1/DbLoad.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* +SNOTICE
|
||||
*
|
||||
* $XConsortium: DbLoad.c /main/7 1996/08/28 14:38:07 rswiston $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special restrictions in a
|
||||
* confidential disclosure agreement bertween HP, IBM, Sun, USL, SCO and
|
||||
* Univel. Do not distribute this document outside HP, IBM, Sun, USL, SCO,
|
||||
* or Univel wihtout Sun's specific written approval. This documment and all
|
||||
* copies and derivative works thereof must be returned or destroyed at Sun's
|
||||
* request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* +ENOTICE
|
||||
*/
|
||||
|
||||
/* *
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __hpux
|
||||
#include <ndir.h>
|
||||
#else
|
||||
|
||||
#if defined(sun) || defined(USL) || defined(sco) || defined(__uxp__)
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include <sys/dir.h>
|
||||
#endif /* sun || USL */
|
||||
|
||||
#endif /* __hpux */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NLS16
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <Dt/DtP.h>
|
||||
#include <Dt/Connect.h>
|
||||
#include <Dt/FileUtil.h>
|
||||
#include <Dt/DtNlUtils.h>
|
||||
#include <Dt/Action.h>
|
||||
#include <Dt/ActionDbP.h>
|
||||
#include <Dt/ActionP.h>
|
||||
#include <Dt/ActionFind.h>
|
||||
#include <Dt/DbUtil.h>
|
||||
#include <Dt/DtPStrings.h>
|
||||
#include <Dt/Utility.h>
|
||||
|
||||
#include <Dt/DtsDb.h>
|
||||
#include <Dt/Dts.h>
|
||||
|
||||
#include "myassertP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
extern void _DtDtsDCConverter(DtDtsDbField * fields,
|
||||
DtDbPathId pathId,
|
||||
char *hostPrefix,
|
||||
Boolean rejectionStatus);
|
||||
extern void _DtDtsDAConverter(DtDtsDbField * fields,
|
||||
DtDbPathId pathId,
|
||||
char *hostPrefix,
|
||||
Boolean rejectionStatus);
|
||||
|
||||
extern void _DtDtsSeqReset(void);
|
||||
extern int _DtDtsNextDCSeq(void);
|
||||
extern int _DtDtsNextDASeq(void);
|
||||
|
||||
int use_in_memory_db = False;
|
||||
|
||||
static void
|
||||
_DtOAConverter(DtDtsDbField * fields,
|
||||
DtDbPathId pathId,
|
||||
char *hostPrefix,
|
||||
Boolean rejectionStatus)
|
||||
{
|
||||
DtDtsDbDatabase *dc_db;
|
||||
DtDtsDbDatabase *da_db;
|
||||
DtDtsDbRecord *dc_rec;
|
||||
DtDtsDbRecord *da_rec;
|
||||
DtDtsDbField *fld;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
dc_db = _DtDtsDbGet(DtDTS_DC_NAME);
|
||||
da_db = _DtDtsDbGet(DtDTS_DA_NAME);
|
||||
if ( _DtDtsDbGetRecordByName(dc_db,
|
||||
fields[0].fieldValue) ||
|
||||
_DtDtsDbGetRecordByName(da_db,
|
||||
fields[0].fieldValue))
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Synthesize criteria record -- for this action
|
||||
*/
|
||||
dc_rec = _DtDtsDbAddRecord(_DtDtsDbGet(DtDTS_DC_NAME));
|
||||
dc_rec->recordName = XrmStringToQuark(fields[0].fieldValue);
|
||||
dc_rec->seq = _DtDtsNextDCSeq();
|
||||
dc_rec->pathId = (int)pathId;
|
||||
fld = _DtDtsDbAddField(dc_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_NAME_PATTERN);
|
||||
fld->fieldValue = strdup(fields[0].fieldValue);
|
||||
fld = _DtDtsDbAddField(dc_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_MODE);
|
||||
fld->fieldValue = strdup("fx");
|
||||
fld = _DtDtsDbAddField(dc_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DATA_ATTRIBUTES_NAME);
|
||||
fld->fieldValue = strdup(fields[0].fieldValue);
|
||||
/*
|
||||
* Mark the criteria record as synthetic.
|
||||
*/
|
||||
fld = _DtDtsDbAddField(dc_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_IS_SYNTHETIC);
|
||||
fld->fieldValue = strdup("True");
|
||||
|
||||
/*
|
||||
* Synthesize attribute record -- for this action
|
||||
*/
|
||||
da_rec = _DtDtsDbAddRecord(_DtDtsDbGet(DtDTS_DA_NAME));
|
||||
da_rec->recordName = XrmStringToQuark(fields[0].fieldValue);
|
||||
da_rec->seq = _DtDtsNextDASeq();
|
||||
da_rec->pathId = (int)pathId;
|
||||
fld = _DtDtsDbAddField(da_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_ACTION_LIST);
|
||||
fld->fieldValue = strdup(fields[0].fieldValue);
|
||||
fld = _DtDtsDbAddField(da_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_DATA_HOST);
|
||||
fld->fieldValue = strdup(hostPrefix);
|
||||
|
||||
/*
|
||||
* Mark the attribute record as synthetic.
|
||||
*/
|
||||
fld = _DtDtsDbAddField(da_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_IS_SYNTHETIC);
|
||||
fld->fieldValue = strdup("True");
|
||||
|
||||
fld = _DtDtsDbAddField(da_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_IS_ACTION);
|
||||
fld->fieldValue = strdup("True");
|
||||
|
||||
fld = _DtDtsDbAddField(da_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_IS_TEXT);
|
||||
fld->fieldValue = strdup("False");
|
||||
|
||||
/*
|
||||
* Use the action name as the default copy_to action
|
||||
*/
|
||||
fld = _DtDtsDbAddField(da_rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_COPY_TO_ACTION);
|
||||
fld->fieldValue = strdup(fields[0].fieldValue);
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DtDbLoad -
|
||||
*
|
||||
* Reads in the file types and action databases.
|
||||
* From the Default DtDatabaseDirPaths.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void _DtDbLoad(DtDirPaths *dirs)
|
||||
{
|
||||
_DtDtsMMUnLoad();
|
||||
}
|
||||
|
||||
void
|
||||
DtDbLoad(void)
|
||||
{
|
||||
DtDirPaths *dirs;
|
||||
|
||||
/* Load the requested database files */
|
||||
dirs = _DtGetDatabaseDirPaths();
|
||||
_DtDbLoad(dirs);
|
||||
_DtFreeDatabaseDirPaths(dirs);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtDbLoad(dirs) -
|
||||
*
|
||||
* Reads in the file types and action databases.
|
||||
* From the the given directory path. This function is not part of the
|
||||
* public API but may be used internally to avoid repeated generation of
|
||||
* the default databasedir path.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int
|
||||
_DtDtsMMCreateDb(DtDirPaths *dirs, const char *CacheFile, int override)
|
||||
{
|
||||
DtDbRecordDesc recordDescriptions[3];
|
||||
DtDbConverter criteriaConverters[2];
|
||||
DtDbConverter attributesConverters[2];
|
||||
DtDbConverter actionConverters[3];
|
||||
static int beenCalled = 0;
|
||||
char **list;
|
||||
int i;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
|
||||
use_in_memory_db = TRUE;
|
||||
|
||||
if ( beenCalled ) {
|
||||
/*
|
||||
* Free up existing database.
|
||||
*/
|
||||
_DtDtsSeqReset();
|
||||
DtDtsRelease();
|
||||
_DtFreeActionDB();
|
||||
|
||||
}
|
||||
beenCalled = 1;
|
||||
|
||||
/*
|
||||
* Initialize the databases
|
||||
* -- this call will initializae the Object databases then
|
||||
* add the action database.
|
||||
*/
|
||||
(void) _DtDtsDbAddDatabase(_DtACTION_NAME);
|
||||
|
||||
if ( !dirs )
|
||||
{
|
||||
myassert(dirs); /* register an assertion failure */
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Build up the record descriptions */
|
||||
criteriaConverters[0] = (DtDbConverter) _DtDtsDCConverter;
|
||||
criteriaConverters[1] = NULL;
|
||||
recordDescriptions[0].recordKeyword = DtDTS_DC_NAME;
|
||||
recordDescriptions[0].maxFields = _DtMAX_NUM_FIELDS;
|
||||
recordDescriptions[0].converters = criteriaConverters;
|
||||
|
||||
/* Build up the ot record descriptions */
|
||||
attributesConverters[0] = (DtDbConverter) _DtDtsDAConverter;
|
||||
attributesConverters[1] = NULL;
|
||||
recordDescriptions[1].recordKeyword = DtDTS_DA_NAME;
|
||||
recordDescriptions[1].maxFields = _DtMAX_NUM_FIELDS;
|
||||
recordDescriptions[1].converters = attributesConverters;
|
||||
|
||||
actionConverters[0] = (DtDbConverter) _DtActionConverter;
|
||||
actionConverters[1] = (DtDbConverter) _DtOAConverter;
|
||||
actionConverters[2] = NULL;
|
||||
recordDescriptions[2].recordKeyword = _DtACTION_NAME;
|
||||
recordDescriptions[2].maxFields = _ActDb_MAX_NUM_FIELDS;
|
||||
recordDescriptions[2].converters = actionConverters;
|
||||
|
||||
|
||||
_DtDbRead(dirs, ".dt", recordDescriptions, 3);
|
||||
|
||||
_DtSortActionDb();
|
||||
|
||||
/*
|
||||
* we may eventually want to return a count of the new records.
|
||||
* for now we return a non-zero value to register success.
|
||||
*/
|
||||
|
||||
if ((!_DtDtsMMCreateFile(dirs, CacheFile)) ||
|
||||
(!_DtDtsMMapDB(CacheFile)))
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
if(!override)
|
||||
{
|
||||
unlink(CacheFile);
|
||||
}
|
||||
|
||||
/* now that we have built the databases delete the tmp Db memory
|
||||
used for it (Too, bad we can't delete the memory associcated
|
||||
with the Quarks) */
|
||||
list = (char **)_DtsDbListDb();
|
||||
for(i = 0; list[i]; i++)
|
||||
{
|
||||
_DtDtsDbDeleteDb(_DtDtsDbGet(list[i]));
|
||||
free(list[i]);
|
||||
}
|
||||
free(list);
|
||||
use_in_memory_db = FALSE;
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(1);
|
||||
}
|
||||
1864
cde/lib/DtSvc/DtUtil1/DbReader.c
Normal file
1864
cde/lib/DtSvc/DtUtil1/DbReader.c
Normal file
File diff suppressed because it is too large
Load Diff
166
cde/lib/DtSvc/DtUtil1/DbReader.h
Normal file
166
cde/lib/DtSvc/DtUtil1/DbReader.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* File: DbReader.h $XConsortium: DbReader.h /main/4 1995/10/26 15:03:35 rswiston $
|
||||
*
|
||||
* Description: Public include file for the database reader.
|
||||
*
|
||||
* (c) Copyright 1987, 1988, 1989 by Hewlett-Packard Company
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _Dt_DbReader_h
|
||||
#define _Dt_DbReader_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <Dt/DbUtil.h>
|
||||
|
||||
#define DTRECORDIDENTIFIER NULL
|
||||
#define DTUNLIMITEDFIELDS 0
|
||||
|
||||
/* one set of attribute/pair */
|
||||
typedef struct
|
||||
{
|
||||
XrmQuark fieldName;
|
||||
char *fieldValue;
|
||||
} DtDtsDbField;
|
||||
|
||||
/*
|
||||
* Opaque identifier used for identifying a database file name. The opaque
|
||||
* identifier can be converted to an ascii string, using the function
|
||||
* _DtDbPathIdToString().
|
||||
*/
|
||||
#define DtDbPathId long
|
||||
|
||||
/*
|
||||
* All record converters should expect to be called with the parameters
|
||||
* indicated below:
|
||||
*
|
||||
* fields: This is an array of keyword/value pair strings, each
|
||||
* representing one field value for this database record. NOTE:
|
||||
* the keywords have not been validated; this is the
|
||||
* responsibility of the converter, and is usually accomplished
|
||||
* by calling _DtValidateFieldNames(). The array is NULL
|
||||
* terminated, with the last entry having both the 'fieldName'
|
||||
* and 'fieldValue' pointers set to NULL. The first entry always
|
||||
* represents the record identifier, with the 'fieldName' set
|
||||
* to the record type string, and the 'fieldValue' set to any
|
||||
* remaining data specified on the record identifier line.
|
||||
*
|
||||
* pathId: Is an opaque identifier, which can be used to retrieve the name
|
||||
* of the database file from which this record was obtained. By
|
||||
* calling _DtDbPathIdToString(), the database file, in
|
||||
* "host:/path" format, can be obtained.
|
||||
*
|
||||
* hostPrefix: If the database file was loaded from a machine other than the
|
||||
* local machine, then this string indicates the host prefix, in
|
||||
* "/nfs/<host>" format. If the host was the local host, then
|
||||
* this value is set to NULL.
|
||||
*
|
||||
* rejectionStatus: This flag indicates whether any of the earlier record
|
||||
* converters had rejected this entry. Certain classes
|
||||
* of converters may choose to ignore entries if they
|
||||
* had already been rejected.
|
||||
*
|
||||
* It is the responsibility of the converter to perform any necessary
|
||||
* verification of the passed in set of keywords; the function
|
||||
* _DtValidateFieldNames() is provided as a convenience function for performing
|
||||
* this type of validation. Typically, the converter will write an error to
|
||||
* the user's errorlog file, if an invalid record is encountered.
|
||||
*
|
||||
* It is also the responsibility of the converter to allocate any memory needed
|
||||
* to store the new record. The strings contained within the 'fields' array
|
||||
* will all be freed when the converter returns to _DtDbRead(), so the
|
||||
* converter should make copies of any information it wishes to use in the
|
||||
* future. The converter is also responsible for adding the new record to
|
||||
* whatever storage array it is using to save record information.
|
||||
*
|
||||
* If the converter decides to reject the record, then it should return a
|
||||
* 'True' value. If the record was acceptable, then 'False' should be
|
||||
* returned.
|
||||
*/
|
||||
typedef Boolean (*DtDbConverter) (DtDtsDbField * fields,
|
||||
DtDbPathId pathId,
|
||||
char * hostPrefix,
|
||||
Boolean rejectionStatus);
|
||||
|
||||
/*
|
||||
* This structure defines each record type which should be loaded by
|
||||
* _DtDbRead(). Since _DtDbRead() is capable of loading multiple record types
|
||||
* (i.e ACTION, DATA_CRITERIA, etc) in a single pass, the invoking function will
|
||||
* pass in an array of these structures, for which each element will define a
|
||||
* record type which should be loaded. Each record definition requires the
|
||||
* following information:
|
||||
*
|
||||
* recordKeyword: This is the keyword which uniquely identifies the record
|
||||
* which matches this definition. Examples are "ACTION" and
|
||||
* "DATA_CRITERIA".
|
||||
*
|
||||
* maxFields: Indicates the maximum number of fields which is expected
|
||||
* by this record type; typically, this corresponds to the
|
||||
* number of distinct field keywords supported by this type
|
||||
* of record. This feature is used to prevent runaway database
|
||||
* records from getting out of hand; a runaway database record
|
||||
* typically occurs when the user forgets to include line
|
||||
* continuation characters, and a long 'description' field
|
||||
* is entered. If this parameter is set to
|
||||
* DTUNLIMITEDFIELDS, then the check for runaway records
|
||||
* will be disabled for records of this type.
|
||||
*
|
||||
* converters: This is a NULL-terminated array of function pointers,
|
||||
* corresponding to the set of record converters which will
|
||||
* be called, whenever a record of this type is encountered.
|
||||
* The converters are called in order, and all converters will
|
||||
* be called, even if an earlier one rejects the record. The
|
||||
* last entry in the array must be set to NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
char * recordKeyword;
|
||||
int maxFields;
|
||||
DtDbConverter * converters;
|
||||
} DtDbRecordDesc;
|
||||
|
||||
|
||||
/*
|
||||
* _DtDbRead() is the function which causes the specified set of directories to
|
||||
* be searched for files ending with the specified suffix. Although not
|
||||
* required, the set of directories to search is typically obtained by calling
|
||||
* _DtGetDatabaseDirPaths(). This function supports the loading of multiple
|
||||
* field types, all in a single pass of the database files. This function does
|
||||
* not attempt to manage the memory used to store the information extracted from
|
||||
* the database files; it is the responsibility of the function calling this
|
||||
* procedure to initialize any storage, and it is the responsibility of the
|
||||
* record converters to allocate any memory needed to store and record, along
|
||||
* with adding the record to the appropriate storage array.
|
||||
*
|
||||
* dirs: The set of directories to be searched for database files.
|
||||
*
|
||||
* suffix: The file suffix (i.e. ".vf") used to qualify which files within
|
||||
* the database directories should be loaded.
|
||||
*
|
||||
* recordDescriptions: An array, where each entry describes a database record
|
||||
* which should be loaded during this pass of _DtDbRead().
|
||||
* See the definition for this structure, for more details.
|
||||
*
|
||||
* int numRecordDescriptions: The number of entries in the above array.
|
||||
*/
|
||||
extern void _DtDbRead (DtDirPaths * dirs,
|
||||
char * suffix,
|
||||
DtDbRecordDesc * recordDescriptions,
|
||||
int numRecordDescriptions);
|
||||
|
||||
|
||||
/*
|
||||
* _DtDbPathIdToString() is used to map a filename identifier, represented
|
||||
* by an opaque DtDbPathId value, into its corresponding ascii string
|
||||
* representation. The returned string is owned by the calling application,
|
||||
* which should free it up when no longer needed.
|
||||
*/
|
||||
extern char * _DtDbPathIdToString ( DtDbPathId pathId );
|
||||
|
||||
#endif /* _Dt_DbReader_h */
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
890
cde/lib/DtSvc/DtUtil1/DbUtil.c
Normal file
890
cde/lib/DtSvc/DtUtil1/DbUtil.c
Normal file
@@ -0,0 +1,890 @@
|
||||
/*
|
||||
* $TOG: DbUtil.c /main/13 1998/04/09 17:47:56 mgreess $
|
||||
*
|
||||
* (c) Copyright 1988, 1989, 1990, 1991, 1992, 1993
|
||||
* by Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#ifdef NLS16
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#define X_INCLUDE_DIRENT_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <Dt/DtP.h>
|
||||
#include <Dt/Connect.h>
|
||||
#include <Dt/FileUtil.h>
|
||||
#include <Dt/DtNlUtils.h>
|
||||
#include <Dt/Action.h>
|
||||
#include <Dt/ActionP.h>
|
||||
#include <Dt/ActionDbP.h>
|
||||
#include <Dt/ActionUtilP.h>
|
||||
#include <Dt/DbUtil.h>
|
||||
#include <Dt/Utility.h>
|
||||
|
||||
#include <Dt/ActionDb.h>
|
||||
|
||||
#ifndef S_ISLNK
|
||||
/* This macro is normally defined in stat.h, but not on USL systems. */
|
||||
# define S_ISLNK(_M) ((_M & S_IFMT)==S_IFLNK) /* test for symbolic link */
|
||||
#endif
|
||||
|
||||
#ifndef CDE_INSTALLATION_TOP
|
||||
#define CDE_INSTALLATION_TOP "/opt/dt"
|
||||
#endif
|
||||
|
||||
#ifndef CDE_CONFIGURATION_TOP
|
||||
#define CDE_CONFIGURATION_TOP "/etc/opt/dt"
|
||||
#endif
|
||||
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define FILE_INCREMENT 20
|
||||
|
||||
/* The following string holds the default value of the Dt database
|
||||
* search path. This default search path has the following major
|
||||
* components:
|
||||
*
|
||||
* $HOME/.dt/types[/%L] A location for the user's personal
|
||||
* actions and filetypes.
|
||||
*
|
||||
* <config-location>/appconfig/types[/%L]
|
||||
* The DT location for system-wide
|
||||
* customizations.
|
||||
*
|
||||
* <top-of-dt>/types/[%L] The DT location for default
|
||||
* system-wide actions and filetypes.
|
||||
*/
|
||||
static char DTDATABASESEARCHPATH_DEFAULT[] =
|
||||
"%s/.dt/types/%%L,"
|
||||
"%s/.dt/types,"
|
||||
CDE_CONFIGURATION_TOP "/appconfig/types/%%L,"
|
||||
CDE_CONFIGURATION_TOP "/appconfig/types,"
|
||||
CDE_INSTALLATION_TOP "/appconfig/types/%%L,"
|
||||
CDE_INSTALLATION_TOP "/appconfig/types";
|
||||
|
||||
|
||||
/**** Substitution records used by XtFindFile() in _DtExpandLang() ****/
|
||||
static SubstitutionRec langSubstitutions[] =
|
||||
{
|
||||
{'L', (char *)NULL},
|
||||
{'l', (char *)NULL},
|
||||
{'t', (char *)NULL},
|
||||
{'c', (char *)NULL}
|
||||
};
|
||||
static int nLangSubstitutions = XtNumber(langSubstitutions);
|
||||
|
||||
|
||||
/******** Static Function Declarations ********/
|
||||
|
||||
static Boolean __testPath(
|
||||
String str );
|
||||
static void __setupLangSubstitutions(
|
||||
void );
|
||||
static void __freeLangSubstitutions(
|
||||
void );
|
||||
static char *_DtExpandLang(
|
||||
char *string ) ;
|
||||
static char _DtIsDir(
|
||||
char *path,
|
||||
char *name) ;
|
||||
static void _DtFreeDirVector(
|
||||
char **dir_vector) ;
|
||||
static void __swap(
|
||||
int i ,
|
||||
DtDirPaths *data );
|
||||
static void _DtSortFiles(
|
||||
int low,
|
||||
int n,
|
||||
DtDirPaths *data) ;
|
||||
|
||||
/******** End Static Function Declarations ********/
|
||||
|
||||
/******************
|
||||
*
|
||||
* Function Name: __testPath
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function is needed by XtFindFile(). Always returns True.
|
||||
*
|
||||
* Synopsis:
|
||||
*
|
||||
* path = XtFindFile(..., __testPath);
|
||||
*
|
||||
******************/
|
||||
|
||||
static Boolean
|
||||
__testPath(String str)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
/******************
|
||||
*
|
||||
* Function Name: __setupLangSubstitutions
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function initializes langSubstitutions[] for use by
|
||||
* XtFindFile().
|
||||
*
|
||||
* Synopsis:
|
||||
*
|
||||
* __setupLangSubstitutions();
|
||||
*
|
||||
******************/
|
||||
|
||||
static void
|
||||
__setupLangSubstitutions(void)
|
||||
{
|
||||
char *lang;
|
||||
char *languagePart;
|
||||
char *territoryPart;
|
||||
char *codesetPart;
|
||||
char *tlPtr, *ttPtr, *tcPtr, *endPtr;
|
||||
|
||||
/*
|
||||
* We should really be calling setlocale to determine the "default"
|
||||
* locale but setlocale's return value is not standardized across
|
||||
* the various vendor platforms nor is it consistent within differnt
|
||||
* revs of individual OS's. (e.g. its changing between HP-UX 9.0 and
|
||||
* HP-UX 10.0). The "right" call would be the following line:
|
||||
*
|
||||
* if ((lang = getenv ("LANG")) || (lang = setlocale(LC_C_TYPE,NULL)))
|
||||
*
|
||||
* Here we hard code the default to "C" instead of leaving it NULL.
|
||||
*/
|
||||
languagePart = territoryPart = codesetPart = (char *)NULL;
|
||||
if ((lang = getenv ("LANG")) == (char *)NULL)
|
||||
lang = "C";
|
||||
|
||||
lang = XtNewString(lang); /* free'd in __freeLangSubstitutions() */
|
||||
|
||||
tlPtr = lang;
|
||||
endPtr = (char *)NULL;
|
||||
if ((ttPtr = DtStrchr(tlPtr, '_')) != (char *)NULL)
|
||||
ttPtr++;
|
||||
|
||||
if ((tcPtr = DtStrchr(ttPtr ? ttPtr : tlPtr, '.')) != (char *)NULL)
|
||||
{
|
||||
endPtr = tcPtr++;
|
||||
if (*tcPtr != '\0')
|
||||
codesetPart =
|
||||
XtNewString(tcPtr); /* free'd in __freeLangSubstitutions() */
|
||||
}
|
||||
|
||||
if (ttPtr)
|
||||
{
|
||||
if (endPtr)
|
||||
{
|
||||
int ttLen = endPtr - ttPtr;
|
||||
|
||||
if (ttLen > 0)
|
||||
{
|
||||
/* free'd in __freeLangSubstitutions() */
|
||||
territoryPart = (char *)XtMalloc((ttLen + 1) * sizeof(char));
|
||||
strncpy(territoryPart, ttPtr, ttLen);
|
||||
territoryPart[ttLen] = '\0';
|
||||
}
|
||||
}
|
||||
else territoryPart =
|
||||
XtNewString(ttPtr); /* free'd in __freeLangSubstitutions() */
|
||||
|
||||
endPtr = ttPtr - 1;
|
||||
}
|
||||
|
||||
if (endPtr)
|
||||
{
|
||||
int tlLen = endPtr - tlPtr;
|
||||
|
||||
if (tlLen > 0)
|
||||
{
|
||||
/* free'd in __freeLangSubstitutions() */
|
||||
languagePart = (char *)XtMalloc((tlLen + 1) * sizeof(char));
|
||||
strncpy(languagePart, tlPtr, tlLen);
|
||||
languagePart[tlLen] = '\0';
|
||||
}
|
||||
}
|
||||
else languagePart =
|
||||
XtNewString(tlPtr); /* free'd in __freeLangSubstitutions() */
|
||||
|
||||
langSubstitutions[0].substitution = lang;
|
||||
langSubstitutions[1].substitution = languagePart;
|
||||
langSubstitutions[2].substitution = territoryPart;
|
||||
langSubstitutions[3].substitution = codesetPart;
|
||||
}
|
||||
|
||||
/******************
|
||||
*
|
||||
* Function Name: __freeLangSubstitutions
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function free's the strings allocated by
|
||||
* __setupLangSubstitutions and placed into langSubstitutions[]
|
||||
*
|
||||
* Synopsis:
|
||||
*
|
||||
* __freeLangSubstitutions();
|
||||
*
|
||||
******************/
|
||||
|
||||
static void
|
||||
__freeLangSubstitutions(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nLangSubstitutions; i++)
|
||||
XtFree(langSubstitutions[i].substitution);
|
||||
}
|
||||
|
||||
/******************
|
||||
*
|
||||
* Function Name: _DtExpandLang
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function takes the string "string", and performs the following
|
||||
* replacements:
|
||||
* %L : contents of LANG environment variable.
|
||||
* %l : language part of the LANG environment variable.
|
||||
* %t : territory part of the LANG environment variable.
|
||||
* %c : codeset part of the LANG environment variable.
|
||||
* %% : % (e.g. %%L would be replaced by %L, and
|
||||
* no substitution would be performed on %L)
|
||||
*
|
||||
* If $LANG is not defined, the $LANG is assumed to be "C".
|
||||
*
|
||||
* Synopsis:
|
||||
*
|
||||
* ret_string = _DtExpandLang (string);
|
||||
*
|
||||
* char *ret_string; Returns NULL if "string" is NULL, or it points
|
||||
* to the expanded string.
|
||||
*
|
||||
* char *string; The comma-separated pathnames to expand.
|
||||
*
|
||||
* Note: The caller is responsible for free'ing the returned string.
|
||||
*
|
||||
******************/
|
||||
|
||||
static char *
|
||||
_DtExpandLang(
|
||||
char *string )
|
||||
{
|
||||
char *thisPath;
|
||||
char *newPath;
|
||||
char *modPath;
|
||||
int pathLen, maxPathLen;
|
||||
int nColons;
|
||||
char *tmpPtr, *tmpPtr1;
|
||||
char *newString;
|
||||
char *tokPtr;
|
||||
|
||||
if (string == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* We're going to use XtFindFile() to perform the replacements;
|
||||
* the colon character ':' is used as a delimiter in XtFindFile,
|
||||
* so we escape all colon characters in our string before
|
||||
* passing it along.
|
||||
*/
|
||||
for (nColons = 0, tmpPtr = string;
|
||||
(tmpPtr = DtStrchr(tmpPtr, ':')) != (char *)NULL;
|
||||
nColons++, tmpPtr++)
|
||||
/* EMPTY */
|
||||
;
|
||||
|
||||
newString =
|
||||
(char *)XtCalloc(1, (strlen(string) + nColons + 1) * sizeof(char));
|
||||
for (tmpPtr = string;
|
||||
(tmpPtr1 = DtStrchr(tmpPtr, ':')) != (char *)NULL;
|
||||
tmpPtr = tmpPtr1 + 1)
|
||||
{
|
||||
strncat(newString, tmpPtr, tmpPtr1 - tmpPtr);
|
||||
strcat(newString, "%:");
|
||||
}
|
||||
strcat(newString, tmpPtr);
|
||||
|
||||
__setupLangSubstitutions();
|
||||
|
||||
/*
|
||||
* XtFindFile() assumes that the string into which it's making
|
||||
* substitutions is a path, and therefore it assumes that the
|
||||
* length of the string does not exceed MAXPATHLEN. Since
|
||||
* our string is a series of paths, it CAN exceed MAXPATHLEN.
|
||||
* So, we split our string into individual paths which we then
|
||||
* pass off to XtFindFile().
|
||||
*/
|
||||
pathLen = maxPathLen = 0;
|
||||
newPath = (char *)NULL;
|
||||
for (thisPath = DtStrtok_r(newString, ",", &tokPtr);
|
||||
thisPath != (char *)NULL;
|
||||
thisPath = DtStrtok_r((char *)NULL, ",", &tokPtr))
|
||||
{
|
||||
modPath = XtFindFile(thisPath, langSubstitutions,
|
||||
nLangSubstitutions, __testPath);
|
||||
if (modPath)
|
||||
{
|
||||
char *origPath = modPath;
|
||||
int modLen;
|
||||
|
||||
/*
|
||||
* For some reason, XtFindFile() collapses all '/'
|
||||
* characters EXCEPT at the beginning of the path!
|
||||
* For backwards compatibility, we collapse those here.
|
||||
*/
|
||||
if (*modPath == '/')
|
||||
{
|
||||
while (*(modPath + 1) == '/')
|
||||
modPath++;
|
||||
}
|
||||
modLen = strlen(modPath);
|
||||
|
||||
if (pathLen + modLen + 2 > maxPathLen)
|
||||
{
|
||||
maxPathLen =
|
||||
((pathLen + modLen + 2 + MAXPATHLEN) / MAXPATHLEN) *
|
||||
MAXPATHLEN;
|
||||
newPath =
|
||||
(char *)XtRealloc(newPath, maxPathLen * sizeof(char));
|
||||
}
|
||||
|
||||
if (pathLen > 0)
|
||||
newPath[pathLen++] = ',';
|
||||
strcpy(&(newPath[pathLen]), modPath);
|
||||
pathLen += modLen;
|
||||
|
||||
XtFree(origPath);
|
||||
}
|
||||
}
|
||||
|
||||
__freeLangSubstitutions();
|
||||
XtFree(newString);
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
*
|
||||
* Function Name: _DtIsDir
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function tests a pathname to see if it is a directory.
|
||||
* The path name is received in two pieces, which makes it easy
|
||||
* for the calling function to test a bunch of files in a directory
|
||||
* to see if any are subdirectories.
|
||||
*
|
||||
* This function does NOT handle Softbench-style pathnames with
|
||||
* embedded hostnames.
|
||||
*
|
||||
* Synopsis:
|
||||
*
|
||||
* dir = _DtIsDir (path, name);
|
||||
*
|
||||
* char dir; Returns 0 if the item is not a directory,
|
||||
* 1 if it is.
|
||||
* char *path; The first part of the pathname. Typically
|
||||
* the directory containing the item of interest.
|
||||
* char *name; The second half of the pathname. Typically
|
||||
* the name of the item of interest.
|
||||
*
|
||||
******************/
|
||||
|
||||
static char
|
||||
_DtIsDir(
|
||||
char *path,
|
||||
char *name )
|
||||
{
|
||||
struct stat stat_buf;
|
||||
char *stat_name;
|
||||
|
||||
stat_name = XtMalloc ((Cardinal)(strlen(path) + strlen(name) + 2));
|
||||
(void)strcpy (stat_name, path);
|
||||
(void)strcat (stat_name, "/");
|
||||
(void)strcat (stat_name, name);
|
||||
|
||||
if(stat (stat_name, &stat_buf))
|
||||
{
|
||||
stat_buf.st_mode = 0;
|
||||
}
|
||||
XtFree (stat_name);
|
||||
|
||||
if (stat_buf.st_mode & S_IFDIR)
|
||||
return (TRUE);
|
||||
else
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
*
|
||||
* Function Name: _DtFreeDirVector
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function frees a database-directory string vector.
|
||||
*
|
||||
* Synoposis:
|
||||
*
|
||||
* FreeDatabaseDirs (dirs);
|
||||
*
|
||||
* char **dirs; The string vector to free.
|
||||
*
|
||||
********************************/
|
||||
|
||||
static void
|
||||
_DtFreeDirVector(
|
||||
char **dir_vector )
|
||||
{
|
||||
char **v;
|
||||
|
||||
if (dir_vector)
|
||||
{
|
||||
for (v = dir_vector; *v != NULL; v++)
|
||||
XtFree ((char *)*v);
|
||||
|
||||
XtFree ((char *)dir_vector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
*
|
||||
* Function Name: __swap
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function exchanges two elements in an array of DtDirPaths.
|
||||
*
|
||||
* Synoposis:
|
||||
*
|
||||
* __swap (i, data);
|
||||
*
|
||||
* int i; The base index to change.
|
||||
* DtDirPaths *data; The data to change.
|
||||
*
|
||||
********************************/
|
||||
|
||||
static void
|
||||
__swap(
|
||||
int i ,
|
||||
DtDirPaths *data )
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
/* The "names" field of the structure is not touched because
|
||||
* this field is "NULL" for all of the entries.
|
||||
*/
|
||||
tmp = data->dirs[i];
|
||||
data->dirs[i] = data->dirs[i+1]; data->dirs[i+1] = tmp;
|
||||
|
||||
tmp = data->paths[i];
|
||||
data->paths[i] = data->paths[i+1]; data->paths[i+1] = tmp;
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
*
|
||||
* Function Name: _DtSortFiles
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Given an index, an array of "char" data and the number of elements to
|
||||
* sort, this function sorts the data. The sorting algorithm is based
|
||||
* on a bubble sort because the number of elements is usually less than
|
||||
* ten.
|
||||
*
|
||||
* Synoposis:
|
||||
*
|
||||
* _DtSortFiles (index, n, data);
|
||||
*
|
||||
* int low; The base of the array to begin the sorting.
|
||||
* int n; The number of elements to sort.
|
||||
* DtDirPaths *data; The data to sort.
|
||||
*
|
||||
********************************/
|
||||
|
||||
static void
|
||||
_DtSortFiles(
|
||||
int low,
|
||||
int n,
|
||||
DtDirPaths *data )
|
||||
{
|
||||
int i, j;
|
||||
int high = low + n;
|
||||
|
||||
/*
|
||||
* This sorting routine needs to be able to sort any portion of
|
||||
* an array - it does not always start at element '0'.
|
||||
*/
|
||||
|
||||
for (i = low; i < (high - 1); i++)
|
||||
for (j = low; j < (high - 1); j++)
|
||||
#ifndef NO_MESSAGE_CATALOG
|
||||
if ((strcoll (data->paths[j], data->paths[j+1])) > 0)
|
||||
#else
|
||||
if ((strcmp (data->paths[j], data->paths[j+1])) > 0)
|
||||
#endif
|
||||
__swap (j, data);
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
*
|
||||
* Function Name: _DtFindMatchingFiles
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function takes a string vector of directory names (which
|
||||
* are in "host:/path/file" format) and a filename suffix and
|
||||
* finds all of the files in those directories with the specified
|
||||
* suffix. It returns a string vector of the filenames.
|
||||
*
|
||||
* You will typically first call _DtGetDatabaseDirPaths() to get the
|
||||
* 'dirs' info.
|
||||
*
|
||||
* Use _DtFreeDatabaseDirPaths() to free up the return structure.
|
||||
*
|
||||
* Synopsis:
|
||||
*
|
||||
* filev = _DtFindMatchingFiles (dirs, suffix, sort_files);
|
||||
*
|
||||
* DtDirPaths *filev; A structure containing the names
|
||||
* of all the files that were found.
|
||||
* DtDirPaths *dirs; A structure of directories to be
|
||||
* searched.
|
||||
* char *suffix; The suffix string which is compared
|
||||
* to the end of the filenames. This
|
||||
* string must contain a "." if it is
|
||||
* part of the suffix you want to match
|
||||
* on (e.g. ".c").
|
||||
* Boolean sort_files; Should the files within a directory be sorted.
|
||||
*
|
||||
*
|
||||
******************/
|
||||
|
||||
DtDirPaths *
|
||||
_DtFindMatchingFiles(
|
||||
DtDirPaths *dirs,
|
||||
char *suffix,
|
||||
Boolean sort_files )
|
||||
{
|
||||
/* LOCAL VARIABLES */
|
||||
|
||||
register DtDirPaths *files; /* An array of pointers to the filenames which
|
||||
have been found. */
|
||||
int max_files; /* The total number of filenames that can be
|
||||
stored in the "files" array before it must
|
||||
be reallocd. */
|
||||
int num_found; /* The number of files which have been found. */
|
||||
register DIR *dirp; /* Variables for walking through the directory
|
||||
entries. */
|
||||
char * next_file;
|
||||
struct dirent *dp = NULL;
|
||||
char *file_suffix;
|
||||
int suffixLen, nameLen;
|
||||
int nextIndex;
|
||||
register char * next_path;
|
||||
int files_in_this_directory;
|
||||
int base;
|
||||
|
||||
_Xreaddirparams dirEntryBuf;
|
||||
struct dirent *result;
|
||||
|
||||
/* CODE */
|
||||
if (dirs == NULL)
|
||||
return(NULL);
|
||||
|
||||
files = (DtDirPaths *) XtMalloc((Cardinal)(sizeof(DtDirPaths)));
|
||||
files->dirs = (char **) XtMalloc(sizeof(char *) * FILE_INCREMENT);
|
||||
files->paths = (char **) XtMalloc(sizeof(char *) * FILE_INCREMENT);
|
||||
max_files = FILE_INCREMENT;
|
||||
num_found = 0;
|
||||
nextIndex = 0;
|
||||
|
||||
/* Process each one of the directories in priority order. */
|
||||
while (dirs->paths[nextIndex] != NULL) {
|
||||
|
||||
next_path = dirs->paths[nextIndex];
|
||||
dirp = opendir (next_path);
|
||||
base = num_found;
|
||||
|
||||
files_in_this_directory = 0;
|
||||
while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL) {
|
||||
|
||||
/* Check the name to see if it matches the suffix and is
|
||||
a file. */
|
||||
if (strlen (result->d_name) >= strlen(suffix))
|
||||
{
|
||||
/* Find the end of the name and compare it to the suffix. */
|
||||
/* Get the number of chars (not bytes) in each string */
|
||||
suffixLen = DtCharCount(suffix);
|
||||
nameLen = DtCharCount(result->d_name);
|
||||
file_suffix = _DtGetNthChar(result->d_name, nameLen - suffixLen);
|
||||
if (file_suffix && (strcmp(file_suffix, suffix) == 0) &&
|
||||
!_DtIsDir((char *)next_path, (char *)result->d_name))
|
||||
{
|
||||
|
||||
/* The file is a match. See if there is room in the array
|
||||
or whether we need to realloc. The "-1" is to save room
|
||||
for the terminating NULL pointer. */
|
||||
if (num_found == max_files - 1) {
|
||||
files->dirs = (char **) XtRealloc ((char *)files->dirs,
|
||||
(Cardinal)(sizeof(char *) * (max_files + FILE_INCREMENT)));
|
||||
files->paths = (char **) XtRealloc ((char *)files->paths,
|
||||
(Cardinal)(sizeof(char *) * (max_files + FILE_INCREMENT)));
|
||||
max_files += FILE_INCREMENT;
|
||||
}
|
||||
|
||||
/* Get some memory and copy the filename to the array. */
|
||||
files->dirs[num_found] = next_file = (char *)
|
||||
XtMalloc((Cardinal)(strlen(dirs->dirs[nextIndex]) +
|
||||
strlen (result->d_name) + 2));
|
||||
(void)strcpy(next_file, dirs->dirs[nextIndex]);
|
||||
(void)strcat(next_file, "/");
|
||||
(void)strcat(next_file, result->d_name);
|
||||
|
||||
files->paths[num_found] = next_file = (char *)
|
||||
XtMalloc((Cardinal)(strlen(next_path) +
|
||||
strlen (result->d_name) + 2));
|
||||
(void)strcpy(next_file, next_path);
|
||||
(void)strcat(next_file, "/");
|
||||
(void)strcat(next_file, result->d_name);
|
||||
|
||||
num_found++;
|
||||
files_in_this_directory++;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir (dirp);
|
||||
if (sort_files && (files_in_this_directory > 1))
|
||||
_DtSortFiles (base, files_in_this_directory, files);
|
||||
nextIndex++;
|
||||
}
|
||||
files->dirs[num_found] = NULL;
|
||||
files->paths[num_found] = NULL;
|
||||
return (files);
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* _DtDbGetDataBaseEnv( )
|
||||
* ------------------------
|
||||
* This function provides a PRIVATE API for internal manipulation of the
|
||||
* DTDATABASEDIRPATH environment variable before loading the databases.
|
||||
* -- used by the front panel code in dtwm.
|
||||
*
|
||||
* If the environment variable it returns a default path.
|
||||
*
|
||||
* NOTE: This function returns a freshly malloc'ed string. It is up to
|
||||
* the caller to free it.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
char *
|
||||
_DtDbGetDataBaseEnv( void )
|
||||
{
|
||||
char *nwh_dir;
|
||||
char *temp_buf;
|
||||
char *temp_s;
|
||||
|
||||
nwh_dir = getenv ("HOME");
|
||||
/*
|
||||
* Get the DTDATABASESEARCHPATH environment variable. If it is not set,
|
||||
* create the default value.
|
||||
*/
|
||||
if ( temp_s = getenv ("DTDATABASESEARCHPATH"))
|
||||
if ( *temp_s != 0 ) return XtNewString(temp_s);
|
||||
|
||||
temp_buf =
|
||||
XtMalloc((2*strlen(nwh_dir)) + strlen(DTDATABASESEARCHPATH_DEFAULT) + 1);
|
||||
sprintf (temp_buf, DTDATABASESEARCHPATH_DEFAULT, nwh_dir, nwh_dir);
|
||||
return temp_buf;
|
||||
|
||||
}
|
||||
|
||||
/******************************
|
||||
*
|
||||
* Function Name: _DtGetDatabaseDirPaths
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function returns a structure containing the external
|
||||
* and internal forms for all of the database directories that must be
|
||||
* searched for Dt database files.
|
||||
* The structure is freed using _DtFreeDatabaseDirPaths().
|
||||
*
|
||||
* The directories are all guaranteed to be fully-specified names;
|
||||
* i.e. host:/path/dir.
|
||||
*
|
||||
* THIS IS TYPICALLY CALLED BEFORE USING ANY OF THE FOLLOWING:
|
||||
*
|
||||
* DtReadDatabases()
|
||||
* DtPrepareToolboxDirs()
|
||||
* _DtDbRead()
|
||||
* _DtFindMatchingFiles()
|
||||
*
|
||||
* Synoposis:
|
||||
*
|
||||
* DtDirPaths * _DtGetDatabaseDirPaths ();
|
||||
*
|
||||
********************************/
|
||||
|
||||
DtDirPaths *
|
||||
_DtGetDatabaseDirPaths( void )
|
||||
{
|
||||
XrmValue resource_value;
|
||||
char *rep_type;
|
||||
char *dir_string, *remote_hosts;
|
||||
char *nwh_host; /* Holds the host portion of the user's
|
||||
network-home. */
|
||||
char **dir_vector; /* The list of directories are turned into
|
||||
a vector of strings. This points to the
|
||||
start of the vector. */
|
||||
char **hosts_vector;
|
||||
char **next_dir; /* A pointer used to walk through dir_vector. */
|
||||
char **next_host;
|
||||
char *dir; /* Points to next dir being processed */
|
||||
int valid_dirs; /* A count of the number of valid directories
|
||||
found. */
|
||||
char *home;
|
||||
char *nextc;
|
||||
DtDirPaths * ret_paths;
|
||||
char * internal;
|
||||
int i;
|
||||
char *tmp_dir_string;
|
||||
|
||||
/* Get our host name, and the user's home directory */
|
||||
nwh_host = _DtGetLocalHostName ();
|
||||
tmp_dir_string = _DtDbGetDataBaseEnv();
|
||||
dir_string = _DtExpandLang (tmp_dir_string);
|
||||
XtFree (tmp_dir_string);
|
||||
|
||||
/* Prepare the input vector and the two output vectors. */
|
||||
dir_vector = _DtVectorizeInPlace (dir_string, ',');
|
||||
ret_paths = (DtDirPaths *)XtMalloc(sizeof(DtDirPaths));
|
||||
ret_paths->dirs = NULL;
|
||||
ret_paths->paths = NULL;
|
||||
valid_dirs = 0;
|
||||
|
||||
for (next_dir = dir_vector; *next_dir != NULL; next_dir++) {
|
||||
|
||||
if (DtStrchr (*next_dir, '/') == NULL){
|
||||
/* It must be a relative path. */
|
||||
/* Ignore relative paths */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the name is not a valid directory, get rid of it. */
|
||||
if (!_DtIsOpenableDirContext (*next_dir, &internal)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
/* If not already in the list, add it to the structure. */
|
||||
for (i = 0; i < valid_dirs; i++)
|
||||
{
|
||||
if (strcmp(ret_paths->paths[i], internal) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == valid_dirs)
|
||||
{
|
||||
valid_dirs++;
|
||||
ret_paths->dirs = (char **) XtRealloc ((char *)ret_paths->dirs,
|
||||
(Cardinal) (sizeof (char *) * valid_dirs));
|
||||
|
||||
/* Make sure the directory name is fully-qualified with a host
|
||||
component. */
|
||||
if (DtStrchr (*next_dir, ':') != NULL)
|
||||
dir = XtNewString(*next_dir);
|
||||
|
||||
/* If there is no host component, see if there is
|
||||
an absolute path. */
|
||||
else if (
|
||||
#ifdef NLS16
|
||||
(!is_multibyte || (mblen(*next_dir, MB_LEN_MAX) == 1)) &&
|
||||
#endif
|
||||
(**next_dir == '/')) {
|
||||
dir = XtMalloc ((Cardinal) (strlen (nwh_host) + 2 +
|
||||
strlen (*next_dir)));
|
||||
(void) sprintf (dir, "%s:%s", nwh_host, *next_dir);
|
||||
}
|
||||
else
|
||||
dir = XtNewString(*next_dir);
|
||||
|
||||
ret_paths->dirs[valid_dirs - 1] = dir;
|
||||
ret_paths->paths = (char **) XtRealloc ((char *)ret_paths->paths,
|
||||
(Cardinal) (sizeof (char *) * valid_dirs));
|
||||
ret_paths->paths[valid_dirs - 1] = internal;
|
||||
}
|
||||
else {
|
||||
XtFree(internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The three vectors must be NULL terminated. */
|
||||
ret_paths->dirs = (char **) XtRealloc ((char *)ret_paths->dirs,
|
||||
(Cardinal) (sizeof (char *) *
|
||||
(valid_dirs + 1)));
|
||||
ret_paths->dirs[valid_dirs] = NULL;
|
||||
ret_paths->paths = (char **) XtRealloc ((char *)ret_paths->paths,
|
||||
(Cardinal) (sizeof (char *) *
|
||||
(valid_dirs + 1)));
|
||||
ret_paths->paths[valid_dirs] = NULL;
|
||||
|
||||
XtFree ((char *) dir_string);
|
||||
XtFree ((char *) nwh_host);
|
||||
XtFree ((char *) dir_vector);
|
||||
return(ret_paths);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
* void _DtFreeDatabaseDirPaths (paths)
|
||||
*
|
||||
* DtDirPaths * paths;
|
||||
*
|
||||
* This function will free up each of the arrays within the directory
|
||||
* information structure, and will then free the structure itself.
|
||||
*
|
||||
**************************/
|
||||
|
||||
void
|
||||
_DtFreeDatabaseDirPaths(
|
||||
DtDirPaths *paths )
|
||||
{
|
||||
_DtFreeDirVector(paths->dirs);
|
||||
_DtFreeDirVector(paths->paths);
|
||||
XtFree((char *)paths);
|
||||
}
|
||||
|
||||
81
cde/lib/DtSvc/DtUtil1/DbUtil.h
Normal file
81
cde/lib/DtSvc/DtUtil1/DbUtil.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* File: DbUtil.h $XConsortium: DbUtil.h /main/4 1995/10/26 15:04:04 rswiston $
|
||||
* Language: C
|
||||
*
|
||||
* (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
|
||||
#ifndef _Dt_DbUtil_h
|
||||
#define _Dt_DbUtil_h
|
||||
|
||||
#include <X11/Intrinsic.h> /* Boolean */
|
||||
|
||||
/*
|
||||
* This structure is used by many of the database functions. It is used to
|
||||
* specify a collection of filenames or directory names. Each file/directory
|
||||
* name is returned in two forms:
|
||||
*
|
||||
* dirs[n] The fully host-qualified pathname for the file or directory,
|
||||
* in "host:/path" format.
|
||||
*
|
||||
* paths[n] The internal format of the file or directory anme, which
|
||||
* can be passed to any of the standard tools which expect a
|
||||
* valid filename; i.e. /nfs/host/path.
|
||||
*
|
||||
* Both of the arrays are NULL-terminated.
|
||||
*/
|
||||
typedef struct {
|
||||
char ** dirs;
|
||||
char ** paths;
|
||||
} DtDirPaths;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
extern DtDirPaths * _DtFindMatchingFiles( DtDirPaths * dirs,
|
||||
char * suffix,
|
||||
Boolean sortFiles );
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* _DtGetDatabaseDirPaths() returns a NULL-terminated array of directories,
|
||||
* which are to be searched for database files. The paths are obtained by
|
||||
* querying the DTDATABASESEARCHPATH environment variable, which specifies
|
||||
* a set of comma separated pathnames, int "host:/path" format. The
|
||||
* return structure should be freed up, when no longer needed, by invoking
|
||||
* _DtFreeDatabaseDirPaths().
|
||||
*
|
||||
* The returned directory names are represented in two formats:
|
||||
*
|
||||
* 1) Fully host qualified; i.e. "host:/path"
|
||||
* 2) Internal format; i.e. "/nfs/host/path"
|
||||
*
|
||||
****************************************************************************/
|
||||
extern DtDirPaths * _DtGetDatabaseDirPaths( void );
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* _DtFreeDatabaseDirPaths() is used to free the memory occupied by the
|
||||
* passed-in instance of the DtDirPaths structure. Typically, this
|
||||
* information was originally obtained by a call to DtGetDatabasePaths()
|
||||
* or _DtFindMatchingFiles().
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* dirs The structure which is to be freed up.
|
||||
*
|
||||
****************************************************************************/
|
||||
extern void _DtFreeDatabaseDirPaths( DtDirPaths * dirs );
|
||||
|
||||
#endif /* _Dt_DbUtil_h */
|
||||
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
467
cde/lib/DtSvc/DtUtil1/Dnd.c
Normal file
467
cde/lib/DtSvc/DtUtil1/Dnd.c
Normal file
@@ -0,0 +1,467 @@
|
||||
/* $TOG: Dnd.c /main/7 1998/10/23 13:47:10 mgreess $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: Dnd.c
|
||||
*
|
||||
* Description: Implemenation of DND Convenience API.
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* 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 documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/DragDrop.h>
|
||||
#include <Xm/DropTrans.h>
|
||||
#include <Dt/UserMsg.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Data Transfer Selection Targets
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
Atom XA_TARGETS;
|
||||
Atom XA_TIMESTAMP;
|
||||
Atom XA_MULTIPLE;
|
||||
Atom XA_DELETE;
|
||||
Atom XA_NULL;
|
||||
Atom XA_TEXT;
|
||||
Atom XA_HOST_NAME;
|
||||
Atom XA_SUN_FILE_HOST_NAME;
|
||||
Atom XA_SUN_ENUM_COUNT;
|
||||
Atom XA_SUN_DATA_LABEL;
|
||||
Atom XA_SUN_SELN_READONLY;
|
||||
Atom XA_SUN_ATM_FILE_NAME;
|
||||
Atom XA_SUN_ATM_METHODS;
|
||||
|
||||
static void
|
||||
dndInitTargets(
|
||||
Display *dpy)
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if (XA_TARGETS != 0) {
|
||||
_DtSvcProcessUnlock();
|
||||
return;
|
||||
}
|
||||
|
||||
XA_TARGETS = DtGetAtom(dpy,"TARGETS");
|
||||
XA_TIMESTAMP = DtGetAtom(dpy,"TIMESTAMP");
|
||||
XA_MULTIPLE = DtGetAtom(dpy,"MULTIPLE");
|
||||
XA_DELETE = DtGetAtom(dpy,"DELETE");
|
||||
XA_NULL = DtGetAtom(dpy,"NULL");
|
||||
XA_TEXT = DtGetAtom(dpy,"TEXT");
|
||||
XA_HOST_NAME = DtGetAtom(dpy,"HOST_NAME");
|
||||
XA_SUN_FILE_HOST_NAME = DtGetAtom(dpy,"_SUN_FILE_HOST_NAME");
|
||||
XA_SUN_ENUM_COUNT = DtGetAtom(dpy,"_SUN_ENUMERATION_COUNT");
|
||||
XA_SUN_DATA_LABEL = DtGetAtom(dpy,"_SUN_DATA_LABEL");
|
||||
XA_SUN_SELN_READONLY = DtGetAtom(dpy,"_SUN_SELN_IS_READONLY");
|
||||
XA_SUN_ATM_FILE_NAME = DtGetAtom(dpy,"_SUN_ATM_FILE_NAME");
|
||||
XA_SUN_ATM_METHODS = DtGetAtom(dpy,
|
||||
"_SUN_ALTERNATE_TRANSPORT_METHODS");
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Data Transfer Protocol Method Functions
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
static DtDndProtocol dndProtocolList[] = {
|
||||
DtDND_FILENAME_TRANSFER,
|
||||
DtDND_BUFFER_TRANSFER,
|
||||
DtDND_TEXT_TRANSFER,
|
||||
DtDND_NOOP_TRANSFER
|
||||
};
|
||||
|
||||
extern DtDndMethods *_DtDndBuffTransferProtocolInitialize(Display*);
|
||||
extern DtDndMethods *_DtDndFileTransferProtocolInitialize(Display*);
|
||||
extern DtDndMethods *_DtDndTextTransferProtocolInitialize(Display*);
|
||||
|
||||
/*
|
||||
* dndGetTransferMethods
|
||||
*
|
||||
* Return the transfer methods for a particular protocol
|
||||
*/
|
||||
static DtDndMethods *
|
||||
dndGetTransferMethods(
|
||||
Display * display,
|
||||
DtDndProtocol protocol)
|
||||
{
|
||||
DtDndMethods * methods = NULL;
|
||||
|
||||
switch (protocol) {
|
||||
case DtDND_BUFFER_TRANSFER:
|
||||
methods = _DtDndBuffTransferProtocolInitialize(display);
|
||||
break;
|
||||
case DtDND_FILENAME_TRANSFER:
|
||||
methods = _DtDndFileTransferProtocolInitialize(display);
|
||||
break;
|
||||
case DtDND_TEXT_TRANSFER:
|
||||
methods = _DtDndTextTransferProtocolInitialize(display);
|
||||
break;
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
/*
|
||||
* _DtDndCreateExportTransfer
|
||||
*
|
||||
* Returns a transfer suitable for use by a drag initiator
|
||||
*/
|
||||
DtDndTransfer *
|
||||
_DtDndCreateExportTransfer(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
Display * dpy = XtDisplayOfObject(dtDragInfo->dragInitiator);
|
||||
DtDndTransfer * transfer;
|
||||
|
||||
dndInitTargets(dpy);
|
||||
|
||||
transfer = (DtDndTransfer *)XtMalloc(sizeof(DtDndTransfer));
|
||||
|
||||
transfer->methods = dndGetTransferMethods(dpy,dtDragInfo->protocol);
|
||||
|
||||
(*transfer->methods->getExportTargets)(dtDragInfo,
|
||||
&(transfer->targets), &(transfer->numTargets));
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
/*
|
||||
* _DtDndCreateImportTransfers
|
||||
*
|
||||
* Create the list of transfers specified by the protocols.
|
||||
*/
|
||||
DtDndTransfer *
|
||||
_DtDndCreateImportTransfers(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Cardinal * numTransfers)
|
||||
{
|
||||
Display * dpy = XtDisplayOfObject(dtDropInfo->dropReceiver);
|
||||
DtDndTransfer * transfers;
|
||||
DtDndTransfer * transfer;
|
||||
Cardinal ii, jj;
|
||||
|
||||
dndInitTargets(dpy);
|
||||
|
||||
*numTransfers = 0;
|
||||
|
||||
for (ii = 0; dndProtocolList[ii] != DtDND_NOOP_TRANSFER; ii++) {
|
||||
if (dtDropInfo->protocols & dndProtocolList[ii]) {
|
||||
(*numTransfers)++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*numTransfers == 0)
|
||||
return (DtDndTransfer *)NULL;
|
||||
|
||||
transfers = (DtDndTransfer *)XtMalloc(
|
||||
*numTransfers * sizeof(DtDndTransfer));
|
||||
|
||||
for (ii = 0, jj = 0; dndProtocolList[ii] != DtDND_NOOP_TRANSFER; ii++) {
|
||||
if (dtDropInfo->protocols & dndProtocolList[ii]) {
|
||||
transfer = &transfers[jj++];
|
||||
transfer->methods =
|
||||
dndGetTransferMethods(dpy,dndProtocolList[ii]);
|
||||
(*transfer->methods->getImportTargets)(dtDropInfo,
|
||||
&(transfer->targets), &(transfer->numTargets));
|
||||
}
|
||||
}
|
||||
|
||||
return transfers;
|
||||
}
|
||||
|
||||
/*
|
||||
* _DtDndDestroyTransfers
|
||||
*
|
||||
* Destroy the transfer list created by
|
||||
* _DtDndCreateExportTransfer() or _DtDndCreateImportTransfers()
|
||||
*/
|
||||
void
|
||||
_DtDndDestroyTransfers(
|
||||
DtDndTransfer * transfers,
|
||||
Cardinal numTransfers)
|
||||
{
|
||||
Cardinal ii;
|
||||
|
||||
|
||||
for (ii = 0; ii < numTransfers; ii++) {
|
||||
XtFree((char *)transfers[ii].targets);
|
||||
}
|
||||
XtFree((char *)transfers);
|
||||
}
|
||||
|
||||
/*
|
||||
* _DtDndTransferFromTargets
|
||||
*
|
||||
* Returns the transfer method that matches the target list
|
||||
*/
|
||||
DtDndTransfer *
|
||||
_DtDndTransferFromTargets(
|
||||
DtDndTransfer * transfers,
|
||||
Cardinal numTransfers,
|
||||
Atom * targets,
|
||||
Cardinal numTargets)
|
||||
{
|
||||
Cardinal ii, jj, kk;
|
||||
|
||||
for (ii = 0; ii < numTransfers; ii++) {
|
||||
for (jj = 0; jj < transfers[ii].numTargets; jj++) {
|
||||
for (kk = 0; kk < numTargets; kk++) {
|
||||
if (transfers[ii].targets[jj] == targets[kk]) {
|
||||
return &transfers[ii];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (DtDndTransfer *)NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* _DtDndTransferAdd
|
||||
*
|
||||
* Add the targets to the requested transfer targets list
|
||||
* and call XmDropTransferAdd() to request them
|
||||
*/
|
||||
void
|
||||
_DtDndTransferAdd(
|
||||
Widget dropTransfer,
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * transferTargets,
|
||||
Cardinal numTransferTargets)
|
||||
{
|
||||
DtTransferInfo *transferInfo = dtDropInfo->transferInfo;
|
||||
XmDropTransferEntryRec * transferEntries;
|
||||
Cardinal numTransfers;
|
||||
int ii, jj;
|
||||
|
||||
transferEntries = (XmDropTransferEntryRec *)
|
||||
XtMalloc(numTransferTargets * sizeof(XmDropTransferEntryRec));
|
||||
|
||||
numTransfers = transferInfo->numTransferTargets + numTransferTargets;
|
||||
|
||||
transferInfo->transferTargets = (Atom *)XtRealloc(
|
||||
(char *)transferInfo->transferTargets,
|
||||
numTransfers * sizeof(Atom));
|
||||
|
||||
jj = transferInfo->numTransferTargets;
|
||||
|
||||
for (ii = 0; ii < numTransferTargets; ii++) {
|
||||
transferEntries[ii].target = transferTargets[ii];
|
||||
transferEntries[ii].client_data = (XtPointer)dtDropInfo;
|
||||
|
||||
transferInfo->transferTargets[ii+jj] = transferTargets[ii];
|
||||
}
|
||||
|
||||
transferInfo->numTransferTargets = numTransfers;
|
||||
|
||||
XmDropTransferAdd(dropTransfer, transferEntries, numTransferTargets);
|
||||
|
||||
XtFree((char *)transferEntries);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Misc Debugging Functions
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
_DtDndPrintTargets(
|
||||
Display *display,
|
||||
Atom *targets,
|
||||
Cardinal numTargets)
|
||||
{
|
||||
Cardinal ii;
|
||||
char *name;
|
||||
|
||||
for (ii = 0; ii < numTargets; ii++) {
|
||||
name = XGetAtomName(display, targets[ii]);
|
||||
if (name) {
|
||||
printf("%s ", name);
|
||||
XFree(name);
|
||||
} else {
|
||||
printf("(null) ");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
_DtDndPrintTransfers(
|
||||
Display *display,
|
||||
DtDndTransfer *transfers,
|
||||
Cardinal numTransfers)
|
||||
{
|
||||
Cardinal ii;
|
||||
|
||||
for (ii = 0; ii < numTransfers; ii++) {
|
||||
printf("%s\tTargets: ",transfers[ii].methods->name);
|
||||
_DtDndPrintTargets(display,
|
||||
transfers[ii].targets,transfers[ii].numTargets);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Misc Utility Functions
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/*
|
||||
* Copy CallbackList
|
||||
*/
|
||||
XtCallbackList
|
||||
_DtDndCopyCallbackList(
|
||||
XtCallbackList callbacks)
|
||||
{
|
||||
XtCallbackList cl;
|
||||
int ii, count;
|
||||
|
||||
if (callbacks == NULL)
|
||||
return NULL;
|
||||
|
||||
count = 1;
|
||||
for (cl = callbacks; cl->callback != NULL; cl++) {
|
||||
count++;
|
||||
}
|
||||
|
||||
cl = (XtCallbackList)XtMalloc(count * sizeof(XtCallbackRec));
|
||||
|
||||
for (ii = 0; ii < count; ii++) {
|
||||
cl[ii].callback = callbacks[ii].callback;
|
||||
cl[ii].closure = callbacks[ii].closure;
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call CallbackList
|
||||
*/
|
||||
void
|
||||
_DtDndCallCallbackList(
|
||||
Widget widget,
|
||||
XtCallbackList callbacks,
|
||||
XtPointer calldata)
|
||||
{
|
||||
XtCallbackList cl;
|
||||
|
||||
if (callbacks == NULL)
|
||||
return;
|
||||
|
||||
for (cl = callbacks; cl->callback != NULL; cl++) {
|
||||
(*cl->callback)(widget, cl->closure, calldata);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Misc Varargs Utility Functions
|
||||
*/
|
||||
|
||||
int
|
||||
_DtDndCountVarArgs(
|
||||
va_list vaList)
|
||||
{
|
||||
XtPointer argPtr;
|
||||
Cardinal argCount;
|
||||
|
||||
argCount = 0;
|
||||
for (argPtr = va_arg(vaList,String);
|
||||
argPtr != NULL;
|
||||
argPtr = va_arg(vaList,String)) {
|
||||
|
||||
va_arg(vaList, XtArgVal);
|
||||
argCount++;
|
||||
}
|
||||
|
||||
return argCount;
|
||||
}
|
||||
|
||||
void
|
||||
_DtDndArgListFromVarArgs(
|
||||
va_list vaList,
|
||||
Cardinal maxArgs,
|
||||
ArgList *argListReturn,
|
||||
Cardinal *argCountReturn)
|
||||
{
|
||||
ArgList argList;
|
||||
Cardinal argCount;
|
||||
XtPointer argPtr;
|
||||
|
||||
if (0 == maxArgs)
|
||||
{
|
||||
*argListReturn = NULL;
|
||||
*argCountReturn = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
argList = (ArgList)XtMalloc((unsigned)(maxArgs * sizeof(Arg)));
|
||||
|
||||
argCount = 0;
|
||||
for (argPtr = va_arg(vaList,String);
|
||||
argPtr != NULL;
|
||||
argPtr = va_arg(vaList,String)) {
|
||||
|
||||
XtSetArg(argList[argCount], argPtr, va_arg(vaList,XtArgVal));
|
||||
argCount++;
|
||||
}
|
||||
|
||||
*argListReturn = argList;
|
||||
*argCountReturn = argCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the network node/host name.
|
||||
*/
|
||||
String
|
||||
_DtDndGetHostName()
|
||||
{
|
||||
static char *nodename;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (nodename == NULL) {
|
||||
struct utsname un;
|
||||
|
||||
if (uname(&un) == -1) {
|
||||
_DtSimpleError(DtProgName,DtError, NULL, "uname", NULL);
|
||||
nodename = XtNewString("nodename");
|
||||
} else {
|
||||
nodename = XtNewString(un.nodename);
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return nodename;
|
||||
}
|
||||
|
||||
188
cde/lib/DtSvc/DtUtil1/Dnd.h
Normal file
188
cde/lib/DtSvc/DtUtil1/Dnd.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* $XConsortium: Dnd.h /main/3 1995/10/26 15:04:35 rswiston $ */
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _Dt_Dnd_h
|
||||
#define _Dt_Dnd_h
|
||||
|
||||
#include <Xm/DragIcon.h>
|
||||
#include <Xm/DragC.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
/* Dnd Callback Reasons */
|
||||
|
||||
enum {
|
||||
DtCR_DND_CONVERT_DATA,
|
||||
DtCR_DND_CONVERT_DELETE,
|
||||
DtCR_DND_DRAG_FINISH,
|
||||
DtCR_DND_TRANSFER_DATA,
|
||||
DtCR_DND_DROP_ANIMATE,
|
||||
DtCR_DND_ROOT_TRANSFER
|
||||
};
|
||||
#define DtCR_DND_TRANSFER DtCR_DND_TRANSFER_DATA
|
||||
|
||||
/*
|
||||
* Dnd Drag Start Resources
|
||||
* dropOnRootCallback is private and should not be used
|
||||
*/
|
||||
|
||||
#define DtNdropOnRootCallback "dropOnRootCallback"
|
||||
#define DtCDropOnRootCallback "DropOnRootCallback"
|
||||
#define DtNsourceIcon "sourceIcon"
|
||||
#define DtCSourceIcon "SourceIcon"
|
||||
#define DtNbufferIsText "bufferIsText"
|
||||
#define DtCBufferIsText "BufferIsText"
|
||||
|
||||
/*
|
||||
*Dnd Drop Register Resources
|
||||
*/
|
||||
|
||||
#define DtNdropAnimateCallback "dropAnimateCallback"
|
||||
#define DtCDropAnimateCallback "DropAnimateCallback"
|
||||
#define DtNpreserveRegistration "preserveRegistration"
|
||||
#define DtCPreserveRegistration "PreserveRegistration"
|
||||
#define DtNregisterChildren "registerChildren"
|
||||
#define DtCRegisterChildren "RegisterChildren"
|
||||
#define DtNtextIsBuffer "textIsBuffer"
|
||||
#define DtCTextIsBuffer "TextIsBuffer"
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
DtDND_SUCCESS,
|
||||
DtDND_FAILURE
|
||||
} DtDndStatus;
|
||||
|
||||
typedef unsigned long DtDndProtocol;
|
||||
|
||||
enum {
|
||||
DtDND_NOOP_TRANSFER = 0L,
|
||||
DtDND_TEXT_TRANSFER = (1L << 0),
|
||||
DtDND_FILENAME_TRANSFER = (1L << 1),
|
||||
DtDND_BUFFER_TRANSFER = (1L << 2)
|
||||
};
|
||||
|
||||
typedef struct _DtDndBuffer {
|
||||
void * bp;
|
||||
int size;
|
||||
String name;
|
||||
} DtDndBuffer;
|
||||
|
||||
typedef struct _DtDndContext {
|
||||
DtDndProtocol protocol;
|
||||
Cardinal numItems;
|
||||
union {
|
||||
XmString * strings;
|
||||
String * files;
|
||||
DtDndBuffer * buffers;
|
||||
} data;
|
||||
} DtDndContext;
|
||||
|
||||
|
||||
/*
|
||||
* Dnd Callback Structures
|
||||
*/
|
||||
|
||||
typedef struct _DtDndConvertCallbackStruct {
|
||||
int reason;
|
||||
XEvent * event;
|
||||
DtDndContext * dragData;
|
||||
DtDndStatus status;
|
||||
} DtDndConvertCallbackStruct, *DtDndConvertCallback;
|
||||
|
||||
typedef struct _DtDndDragFinishCallbackStruct {
|
||||
int reason;
|
||||
XEvent * event;
|
||||
DtDndContext * dragData;
|
||||
Widget sourceIcon;
|
||||
} DtDndDragFinishCallbackStruct, *DtDndDragFinishCallback;
|
||||
|
||||
typedef struct _DtDndTransferCallbackStruct {
|
||||
int reason;
|
||||
XEvent * event;
|
||||
Position x, y;
|
||||
unsigned char operation;
|
||||
DtDndContext * dropData;
|
||||
Widget dragContext;
|
||||
Boolean completeMove;
|
||||
DtDndStatus status;
|
||||
} DtDndTransferCallbackStruct, *DtDndTransferCallback;
|
||||
|
||||
typedef DtDndTransferCallbackStruct DtDndDropCallbackStruct, *DtDndDropCallback;
|
||||
|
||||
typedef struct _DtDndDropAnimateCallbackStruct {
|
||||
int reason;
|
||||
XEvent * event;
|
||||
Position x, y;
|
||||
unsigned char operation;
|
||||
DtDndContext * dropData;
|
||||
} DtDndDropAnimateCallbackStruct, *DtDndDropAnimateCallback;
|
||||
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern Widget DtDndCreateSourceIcon(
|
||||
Widget widget,
|
||||
Pixmap source,
|
||||
Pixmap mask);
|
||||
|
||||
extern Widget DtDndDragStart(
|
||||
Widget dragInitiator,
|
||||
XEvent* event,
|
||||
DtDndProtocol protocol,
|
||||
Cardinal numItems,
|
||||
unsigned char operations,
|
||||
XtCallbackList convertCallback,
|
||||
XtCallbackList dragFinishCallback,
|
||||
ArgList argList,
|
||||
Cardinal argCount);
|
||||
|
||||
extern Widget DtDndVaDragStart(
|
||||
Widget dragInitiator,
|
||||
XEvent* event,
|
||||
DtDndProtocol protocol,
|
||||
Cardinal numItems,
|
||||
unsigned char operations,
|
||||
XtCallbackList convertCallback,
|
||||
XtCallbackList dragFinishCallback,
|
||||
...);
|
||||
|
||||
extern void DtDndDropRegister(
|
||||
Widget dropSite,
|
||||
DtDndProtocol protocols,
|
||||
unsigned char operations,
|
||||
XtCallbackList transferCallback,
|
||||
ArgList argList,
|
||||
Cardinal argCount);
|
||||
|
||||
extern void DtDndVaDropRegister(
|
||||
Widget dropSite,
|
||||
DtDndProtocol protocols,
|
||||
unsigned char operations,
|
||||
XtCallbackList transferCallback,
|
||||
...);
|
||||
|
||||
extern void DtDndDropUnregister(
|
||||
Widget widget);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_Dnd_h */
|
||||
723
cde/lib/DtSvc/DtUtil1/DndBuff.c
Normal file
723
cde/lib/DtSvc/DtUtil1/DndBuff.c
Normal file
@@ -0,0 +1,723 @@
|
||||
/* $XConsortium: DndBuff.c /main/5 1996/06/21 17:30:55 ageorge $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndBuff.c
|
||||
*
|
||||
* Description: Implementation of the Buffer Transfer routines
|
||||
* FOR the DND Convenience API.
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement bertween
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/AtomMgr.h>
|
||||
#include <Xm/DragC.h>
|
||||
#include <Xm/DropSMgr.h>
|
||||
#include <Xm/DropTrans.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Buffer Transfer Protocol Function Prototypes
|
||||
*/
|
||||
|
||||
static void dndBuffGetTargets(Boolean, Boolean, Atom**, Cardinal*);
|
||||
static void dndBuffGetAvailTargets(DtDragInfo*, Atom**, Cardinal*);
|
||||
static void dndBuffGetExportTargets(DtDragInfo*, Atom**, Cardinal*);
|
||||
static void dndBuffGetImportTargets(DtDropInfo*, Atom**, Cardinal*);
|
||||
static void dndBuffConvertInit(DtDragInfo*);
|
||||
static Boolean dndBuffConvert(Widget, DtDragInfo*, Atom*, Atom*,
|
||||
Atom*, XtPointer*, unsigned long*, int*,
|
||||
XSelectionRequestEvent*);
|
||||
static void dndBuffConvertFinish(DtDragInfo*);
|
||||
static void dndBuffTransferTargets(DtDropInfo*,
|
||||
Atom*, Cardinal, Atom**, Cardinal*);
|
||||
static void dndBuffTransfer(Widget, DtDropInfo*, Atom*, Atom*, Atom*,
|
||||
XtPointer, unsigned long*, int*);
|
||||
static void dndBuffTransferFinish(DtDropInfo*);
|
||||
|
||||
/*
|
||||
* Buffer Transfer Support Functions
|
||||
*/
|
||||
|
||||
static void dndBufferDataToSelectionValue(DtDndBuffer *, Cardinal,
|
||||
XtPointer *, unsigned long *, Boolean);
|
||||
static void dndBufferLengthsToSelectionValue(DtDndBuffer *, Cardinal,
|
||||
XtPointer *, unsigned long *);
|
||||
static void dndBufferNamesToSelectionValue(DtDndBuffer *, Cardinal,
|
||||
XtPointer *, unsigned long *);
|
||||
static void dndTextSelectionValueToBuffer(Display *,
|
||||
Atom *, XtPointer, unsigned long *, int *, String,
|
||||
XtPointer *, unsigned long *,
|
||||
DtDndBuffer **, Cardinal *);
|
||||
static void dndSelectionValueToBuffer(XtPointer, unsigned long,
|
||||
XtPointer, unsigned long, XtPointer, unsigned long,
|
||||
DtDndBuffer **, Cardinal *);
|
||||
|
||||
/*
|
||||
* Buffer Transfer Selection Targets
|
||||
*/
|
||||
|
||||
static Atom XA_DT_BUFFER_DATA;
|
||||
static Atom XA_DT_BUFFER_LENGTHS;
|
||||
static Atom XA_DT_BUFFER_NAMES;
|
||||
|
||||
/*
|
||||
* Buffer Transfer Protocol Methods
|
||||
*/
|
||||
|
||||
static DtDndMethods dndBuffTransferProtocol = {
|
||||
"DtDndBufferTransfer", /* name */
|
||||
(DtDndProtocol)DtDND_BUFFER_TRANSFER, /* protocol */
|
||||
DtDND_DRAG_SOURCE_DATA, /* sourceType */
|
||||
dndBuffGetAvailTargets, /* getAvailTargets */
|
||||
dndBuffGetExportTargets, /* getExportTargets */
|
||||
dndBuffGetImportTargets, /* getImportTargets */
|
||||
dndBuffConvertInit, /* convertInit */
|
||||
dndBuffConvert, /* convert */
|
||||
dndBuffConvertFinish, /* convertFinish */
|
||||
dndBuffTransferTargets, /* transferTargets */
|
||||
dndBuffTransfer, /* transfer */
|
||||
dndBuffTransferFinish, /* transferFinish */
|
||||
};
|
||||
|
||||
typedef struct _TransferState {
|
||||
XtPointer dataValue;
|
||||
unsigned long dataLength;
|
||||
XtPointer lengthsValue;
|
||||
unsigned long lengthsLength;
|
||||
XtPointer namesValue;
|
||||
unsigned long namesLength;
|
||||
String dataLabel;
|
||||
Atom textTarget;
|
||||
} TransferState;
|
||||
|
||||
/*
|
||||
* Buffer transfer protocol initialization
|
||||
*/
|
||||
DtDndMethods *
|
||||
_DtDndBuffTransferProtocolInitialize(
|
||||
Display * dpy)
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if (XA_DT_BUFFER_DATA == 0) {
|
||||
XA_DT_BUFFER_DATA = DtGetAtom(dpy,"_DT_BUFFER_DATA");
|
||||
XA_DT_BUFFER_LENGTHS = DtGetAtom(dpy,"_DT_BUFFER_LENGTHS");
|
||||
XA_DT_BUFFER_NAMES = DtGetAtom(dpy,"_DT_BUFFER_NAMES");
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return &dndBuffTransferProtocol;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns export/import targets for buffer transfers
|
||||
*/
|
||||
static void
|
||||
dndBuffGetTargets(
|
||||
Boolean includeText,
|
||||
Boolean owCompat,
|
||||
Atom ** targets,
|
||||
Cardinal * numTargets)
|
||||
{
|
||||
int ii = 0;
|
||||
|
||||
*numTargets = 3 + (includeText ? 2 : 0) + (owCompat ? 1 : 0);
|
||||
|
||||
*targets = (Atom *)XtMalloc(*numTargets * sizeof(Atom));
|
||||
|
||||
(*targets)[ii++] = XA_DT_BUFFER_DATA;
|
||||
(*targets)[ii++] = XA_DT_BUFFER_LENGTHS;
|
||||
(*targets)[ii++] = XA_DT_BUFFER_NAMES;
|
||||
|
||||
if (includeText) {
|
||||
(*targets)[ii++] = XA_TEXT;
|
||||
(*targets)[ii++] = XA_STRING;
|
||||
}
|
||||
|
||||
if (owCompat) {
|
||||
(*targets)[ii++] = XA_SUN_DATA_LABEL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns available targets for buffer transfers
|
||||
*/
|
||||
static void
|
||||
dndBuffGetAvailTargets(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** availTargets,
|
||||
Cardinal * numAvailTargets)
|
||||
{
|
||||
dndBuffGetTargets(True, True, availTargets, numAvailTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns export targets for buffer transfers
|
||||
*/
|
||||
static void
|
||||
dndBuffGetExportTargets(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** exportTargets,
|
||||
Cardinal * numExportTargets)
|
||||
{
|
||||
dndBuffGetTargets(dtDragInfo->bufferIsText, True,
|
||||
exportTargets, numExportTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns import targets for buffer transfers
|
||||
*/
|
||||
static void
|
||||
dndBuffGetImportTargets(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom ** importTargets,
|
||||
Cardinal * numImportTargets)
|
||||
{
|
||||
dndBuffGetTargets(dtDropInfo->textIsBuffer, True,
|
||||
importTargets, numImportTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize protocol specific part of drag data
|
||||
*/
|
||||
static void
|
||||
dndBuffConvertInit(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
|
||||
dragData->data.buffers = (DtDndBuffer *)
|
||||
XtCalloc(dragData->numItems, sizeof(DtDndBuffer));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the buffers into selection data
|
||||
*/
|
||||
static Boolean
|
||||
dndBuffConvert(
|
||||
Widget dragContext,
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * returnType,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
int * returnFormat,
|
||||
XSelectionRequestEvent * selectionRequestEvent)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
|
||||
/*
|
||||
* TEXT or STRING
|
||||
* Convert the buffer data to a text selection
|
||||
*/
|
||||
if (*target == XA_TEXT || *target == XA_STRING) {
|
||||
*returnType = XA_STRING;
|
||||
*returnFormat = 8;
|
||||
dndBufferDataToSelectionValue(
|
||||
dragData->data.buffers, dragData->numItems,
|
||||
returnValue, returnLength, True);
|
||||
/*
|
||||
* _SUN_DATA_LABEL
|
||||
* Convert the first buffer name to a selection
|
||||
*/
|
||||
} else if (*target == XA_SUN_DATA_LABEL) {
|
||||
*returnType = XA_STRING;
|
||||
*returnFormat = 8;
|
||||
*returnValue = XtNewString(dragData->data.buffers[0].name);
|
||||
*returnLength = strlen(*returnValue)+1;
|
||||
/*
|
||||
* _DT_BUFFER_DATA
|
||||
* Convert the buffer data to a selection
|
||||
*/
|
||||
} else if (*target == XA_DT_BUFFER_DATA) {
|
||||
*returnType = XA_DT_BUFFER_DATA;
|
||||
*returnFormat = 8;
|
||||
dndBufferDataToSelectionValue(
|
||||
dragData->data.buffers, dragData->numItems,
|
||||
returnValue, returnLength, False);
|
||||
/*
|
||||
* _DT_BUFFER_LENGTHS
|
||||
* Convert the buffer lengths to a selection
|
||||
*/
|
||||
} else if (*target == XA_DT_BUFFER_LENGTHS) {
|
||||
*returnType = XA_INTEGER;
|
||||
*returnFormat = 32;
|
||||
dndBufferLengthsToSelectionValue(
|
||||
dragData->data.buffers, dragData->numItems,
|
||||
returnValue, returnLength);
|
||||
/*
|
||||
* _DT_BUFFER_NAMES
|
||||
* Convert the buffer names to a selection
|
||||
*/
|
||||
} else if (*target == XA_DT_BUFFER_NAMES) {
|
||||
*returnType = XA_STRING;
|
||||
*returnFormat = 8;
|
||||
dndBufferNamesToSelectionValue(
|
||||
dragData->data.buffers, dragData->numItems,
|
||||
returnValue, returnLength);
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up from the convert init proc
|
||||
*/
|
||||
static void
|
||||
dndBuffConvertFinish(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
|
||||
if (dragData->data.buffers) {
|
||||
XtFree((char *)dragData->data.buffers);
|
||||
dragData->data.buffers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the transfer targets selected from the export targets
|
||||
* Prefer buffers over TEXT/STRING
|
||||
*/
|
||||
static void
|
||||
dndBuffTransferTargets(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * exportTargets,
|
||||
Cardinal numExportTargets,
|
||||
Atom ** transferTargets,
|
||||
Cardinal * numTransferTargets)
|
||||
{
|
||||
Boolean foundData, foundLengths, foundNames,
|
||||
foundDataLabel, foundText, foundString;
|
||||
int ii;
|
||||
TransferState * xferState;
|
||||
|
||||
xferState = (TransferState *)XtCalloc(1,sizeof(TransferState));
|
||||
dtDropInfo->transferInfo->clientData = (XtPointer)xferState;
|
||||
|
||||
|
||||
foundData = foundLengths = foundNames = False;
|
||||
foundDataLabel = foundText = foundString = False;
|
||||
|
||||
for (ii = 0; ii < numExportTargets; ii++) {
|
||||
if (exportTargets[ii] == XA_DT_BUFFER_DATA) {
|
||||
foundData = True;
|
||||
} else if (exportTargets[ii] == XA_DT_BUFFER_LENGTHS) {
|
||||
foundLengths = True;
|
||||
} else if (exportTargets[ii] == XA_DT_BUFFER_NAMES) {
|
||||
foundNames = True;
|
||||
} else if (exportTargets[ii] == XA_SUN_DATA_LABEL) {
|
||||
foundDataLabel = True;
|
||||
} else if (exportTargets[ii] == XA_TEXT) {
|
||||
foundText = True;
|
||||
} else if (exportTargets[ii] == XA_STRING) {
|
||||
foundString = True;
|
||||
}
|
||||
}
|
||||
|
||||
*numTransferTargets = 2; /* max number of transfer targets */
|
||||
|
||||
*transferTargets = (Atom *)XtMalloc(*numTransferTargets * sizeof(Atom));
|
||||
|
||||
ii = 0;
|
||||
|
||||
if (foundData && foundLengths && foundNames) {
|
||||
*numTransferTargets = 2;
|
||||
(*transferTargets)[ii++] = XA_DT_BUFFER_NAMES;
|
||||
(*transferTargets)[ii++] = XA_DT_BUFFER_LENGTHS;
|
||||
} else if (foundDataLabel && (foundText || foundString)) {
|
||||
*numTransferTargets = 2;
|
||||
(*transferTargets)[ii++] = XA_SUN_DATA_LABEL;
|
||||
(*transferTargets)[ii++] = foundText ? XA_TEXT : XA_STRING;
|
||||
xferState->textTarget = foundText ? XA_TEXT : XA_STRING;
|
||||
} else if (foundText || foundString) {
|
||||
*numTransferTargets = 1;
|
||||
(*transferTargets)[ii++] = foundText ? XA_TEXT : XA_STRING;
|
||||
} else {
|
||||
*numTransferTargets = 0;
|
||||
*transferTargets = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the selection data into buffers
|
||||
*/
|
||||
static void
|
||||
dndBuffTransfer(
|
||||
Widget dropTransfer,
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * type,
|
||||
XtPointer value,
|
||||
unsigned long * length,
|
||||
int * format)
|
||||
{
|
||||
Display * display = XtDisplayOfObject(dropTransfer);
|
||||
DtDndContext * dropData = dtDropInfo->dropData;
|
||||
TransferState * xferState =
|
||||
(TransferState *)dtDropInfo->transferInfo->clientData;
|
||||
|
||||
/*
|
||||
* Ignore if we've already transferred
|
||||
*/
|
||||
if (dropData->data.buffers) {
|
||||
XtFree(value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* TEXT or STRING
|
||||
*
|
||||
* Convert the text selection into buffers
|
||||
*/
|
||||
if (*target == XA_TEXT || *target == XA_STRING) {
|
||||
|
||||
dndTextSelectionValueToBuffer(display,
|
||||
type, value, length, format, xferState->dataLabel,
|
||||
&(xferState->dataValue), &(xferState->dataLength),
|
||||
&(dropData->data.buffers), &(dropData->numItems));
|
||||
|
||||
/*
|
||||
* _SUN_DATA_LABEL
|
||||
*
|
||||
* Save the buffer name selection for later conversion
|
||||
* Request the text data transfer
|
||||
*/
|
||||
} else if (*target == XA_SUN_DATA_LABEL &&
|
||||
*type == XA_STRING &&
|
||||
*format == 8) {
|
||||
|
||||
xferState->dataLabel = (String)value;
|
||||
|
||||
_DtDndTransferAdd(dropTransfer, dtDropInfo,
|
||||
&(xferState->textTarget), 1);
|
||||
/*
|
||||
* _DT_BUFFER_DATA
|
||||
*
|
||||
* Save the buffer data selection for later conversion
|
||||
*/
|
||||
} else if (*target == XA_DT_BUFFER_DATA &&
|
||||
*type == XA_DT_BUFFER_DATA &&
|
||||
*format == 8) {
|
||||
|
||||
xferState->dataValue = value;
|
||||
xferState->dataLength = *length;
|
||||
|
||||
dndSelectionValueToBuffer(
|
||||
xferState->dataValue, xferState->dataLength,
|
||||
xferState->lengthsValue, xferState->lengthsLength,
|
||||
xferState->namesValue, xferState->namesLength,
|
||||
&(dropData->data.buffers), &(dropData->numItems));
|
||||
|
||||
|
||||
/*
|
||||
* _DT_BUFFER_LENGTHS
|
||||
*
|
||||
* Save the buffer lengths selection for later conversion
|
||||
* Request the buffer data transfer
|
||||
*/
|
||||
} else if (*target == XA_DT_BUFFER_LENGTHS &&
|
||||
*type == XA_INTEGER &&
|
||||
*format == 32) {
|
||||
|
||||
xferState->lengthsValue = value;
|
||||
xferState->lengthsLength = *length;
|
||||
|
||||
_DtDndTransferAdd(dropTransfer, dtDropInfo,
|
||||
&XA_DT_BUFFER_DATA, 1);
|
||||
/*
|
||||
* _DT_BUFFER_NAMES
|
||||
*
|
||||
* Save the buffer names selection for later conversion
|
||||
*/
|
||||
} else if (*target == XA_DT_BUFFER_NAMES &&
|
||||
*type == XA_STRING &&
|
||||
*format == 8) {
|
||||
|
||||
xferState->namesValue = value;
|
||||
xferState->namesLength = *length;
|
||||
|
||||
/*
|
||||
* Ignore transfers we don't understand
|
||||
*/
|
||||
} else {
|
||||
XtFree(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up from the transfer proc
|
||||
*/
|
||||
static void
|
||||
dndBuffTransferFinish(
|
||||
DtDropInfo * dtDropInfo)
|
||||
{
|
||||
DtDndContext * dropData = dtDropInfo->dropData;
|
||||
TransferState * xferState =
|
||||
(TransferState *)dtDropInfo->transferInfo->clientData;
|
||||
|
||||
dtDropInfo->transferInfo->clientData = NULL;
|
||||
|
||||
if (xferState->dataValue)
|
||||
XtFree(xferState->dataValue);
|
||||
if (xferState->lengthsValue)
|
||||
XtFree(xferState->lengthsValue);
|
||||
if (xferState->namesValue)
|
||||
XtFree(xferState->namesValue);
|
||||
if (xferState->dataLabel)
|
||||
XtFree(xferState->dataLabel);
|
||||
XtFree((char *)xferState);
|
||||
XtFree((char *)dropData->data.buffers);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert buffer data into a single chunk of memory
|
||||
*/
|
||||
static void
|
||||
dndBufferDataToSelectionValue(
|
||||
DtDndBuffer * buffers,
|
||||
Cardinal numBuffers,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
Boolean isText)
|
||||
{
|
||||
int ii;
|
||||
char *bufferPtr;
|
||||
|
||||
*returnLength = 0;
|
||||
|
||||
for (ii = 0; ii < numBuffers; ii++) {
|
||||
*returnLength += buffers[ii].size;
|
||||
if (isText) {
|
||||
*returnLength += 1;
|
||||
}
|
||||
}
|
||||
|
||||
*returnValue = (XtPointer) XtMalloc(*returnLength);
|
||||
|
||||
bufferPtr = (XtPointer)*returnValue;
|
||||
|
||||
for (ii = 0; ii < numBuffers; ii++) {
|
||||
memcpy(bufferPtr, buffers[ii].bp, buffers[ii].size);
|
||||
bufferPtr += buffers[ii].size;
|
||||
if (isText) {
|
||||
*bufferPtr = '\0';
|
||||
bufferPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (isText) {
|
||||
*returnLength -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert buffer lengths into a list of integers
|
||||
*/
|
||||
static void
|
||||
dndBufferLengthsToSelectionValue(
|
||||
DtDndBuffer * buffers,
|
||||
Cardinal numBuffers,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength)
|
||||
{
|
||||
int ii;
|
||||
unsigned long * lengths;
|
||||
|
||||
*returnLength = numBuffers;
|
||||
|
||||
*returnValue = (XtPointer) XtMalloc(*returnLength * sizeof(long));
|
||||
|
||||
lengths = (unsigned long *)*returnValue;
|
||||
|
||||
for (ii = 0; ii < numBuffers; ii++) {
|
||||
lengths[ii] = buffers[ii].size;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert buffer names into a single chunk of memory
|
||||
*/
|
||||
static void
|
||||
dndBufferNamesToSelectionValue(
|
||||
DtDndBuffer * buffers,
|
||||
Cardinal numBuffers,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength)
|
||||
{
|
||||
int ii, len;
|
||||
char * namePtr;
|
||||
|
||||
*returnLength = 0;
|
||||
|
||||
for (ii = 0; ii < numBuffers; ii++) {
|
||||
if (buffers[ii].name != NULL) {
|
||||
*returnLength += strlen(buffers[ii].name) + 1;
|
||||
} else {
|
||||
*returnLength += 1;
|
||||
}
|
||||
}
|
||||
|
||||
*returnValue = (XtPointer) XtMalloc(*returnLength);
|
||||
|
||||
namePtr = (char *)*returnValue;
|
||||
|
||||
for (ii = 0; ii < numBuffers; ii++) {
|
||||
if (buffers[ii].name == NULL) {
|
||||
*namePtr = '\0';
|
||||
namePtr++;
|
||||
} else {
|
||||
len = strlen(buffers[ii].name) + 1;
|
||||
memcpy(namePtr, buffers[ii].name, len);
|
||||
namePtr += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Split text selection data into multiple buffers
|
||||
*/
|
||||
static void
|
||||
dndTextSelectionValueToBuffer(
|
||||
Display * display,
|
||||
Atom * type,
|
||||
XtPointer value,
|
||||
unsigned long * length,
|
||||
int * format,
|
||||
String dataLabel,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
DtDndBuffer ** buffers,
|
||||
Cardinal * numBuffers)
|
||||
{
|
||||
XTextProperty textProp;
|
||||
char ** text;
|
||||
char * bufPtr;
|
||||
int ii, status, textCount, textLen;
|
||||
|
||||
textProp.value = (unsigned char *)value;
|
||||
textProp.encoding = *type;
|
||||
textProp.format = *format;
|
||||
textProp.nitems = *length;
|
||||
|
||||
status = XmbTextPropertyToTextList(display, &textProp,
|
||||
&text, &textCount);
|
||||
|
||||
if (status != Success) {
|
||||
*numBuffers = 1;
|
||||
(*buffers) = (DtDndBuffer *)XtMalloc(sizeof(DtDndBuffer));
|
||||
|
||||
(*buffers)[0].bp = value;
|
||||
(*buffers)[0].size = *length;
|
||||
(*buffers)[0].name = dataLabel ? dataLabel : (String)NULL;
|
||||
|
||||
*returnValue = value;
|
||||
*returnLength = *length;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
*numBuffers = textCount;
|
||||
|
||||
(*buffers) = (DtDndBuffer *)XtMalloc(*numBuffers * sizeof(DtDndBuffer));
|
||||
|
||||
textLen = 0;
|
||||
for (ii = 0; ii < *numBuffers; ii++) {
|
||||
(*buffers)[ii].size = strlen(text[ii]);
|
||||
(*buffers)[ii].name = (String)NULL;
|
||||
textLen += (*buffers)[ii].size+1;
|
||||
}
|
||||
|
||||
(*returnValue) = XtMalloc(textLen * sizeof(char));
|
||||
(*returnLength) = textLen;
|
||||
|
||||
bufPtr = (*returnValue);
|
||||
for (ii = 0; ii < *numBuffers; ii++) {
|
||||
(*buffers)[ii].bp = bufPtr;
|
||||
memcpy(bufPtr,text[ii],(*buffers)[ii].size+1);
|
||||
bufPtr += (*buffers)[ii].size+1;
|
||||
}
|
||||
|
||||
if (dataLabel)
|
||||
(*buffers)[0].name = dataLabel;
|
||||
|
||||
XtFree(value);
|
||||
XFreeStringList(text);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split data/lengths/names selection data into multiple buffers
|
||||
*/
|
||||
static void
|
||||
dndSelectionValueToBuffer(
|
||||
XtPointer dataValue,
|
||||
unsigned long dataLength,
|
||||
XtPointer lengthsValue,
|
||||
unsigned long lengthsLength,
|
||||
XtPointer namesValue,
|
||||
unsigned long namesLength,
|
||||
DtDndBuffer ** buffers,
|
||||
Cardinal * numBuffers)
|
||||
{
|
||||
int ii;
|
||||
char * bufPtr;
|
||||
char * namePtr;
|
||||
unsigned long * lenList;
|
||||
|
||||
if (lengthsLength == 0 || lengthsValue == NULL) {
|
||||
|
||||
*numBuffers = 1;
|
||||
|
||||
(*buffers) = (DtDndBuffer *)XtMalloc(sizeof(DtDndBuffer));
|
||||
|
||||
(*buffers)[0].bp = dataValue;
|
||||
(*buffers)[0].size = dataLength;
|
||||
(*buffers)[0].name = (String)NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
*numBuffers = lengthsLength;
|
||||
|
||||
(*buffers) = (DtDndBuffer *)XtMalloc(*numBuffers * sizeof(DtDndBuffer));
|
||||
|
||||
lenList = (unsigned long *)lengthsValue;
|
||||
bufPtr = dataValue;
|
||||
namePtr = namesValue;
|
||||
|
||||
for (ii = 0; ii < *numBuffers; ii++) {
|
||||
(*buffers)[ii].bp = bufPtr;
|
||||
(*buffers)[ii].size = lenList[ii];
|
||||
(*buffers)[ii].name = namePtr;
|
||||
bufPtr += lenList[ii];
|
||||
namePtr = strchr(namePtr, '\0');
|
||||
namePtr++;
|
||||
}
|
||||
}
|
||||
819
cde/lib/DtSvc/DtUtil1/DndDrag.c
Normal file
819
cde/lib/DtSvc/DtUtil1/DndDrag.c
Normal file
@@ -0,0 +1,819 @@
|
||||
/* $XConsortium: DndDrag.c /main/5 1996/09/27 19:00:40 drk $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndDrag.c
|
||||
*
|
||||
* Description: Implemenation of DND Drag Initator
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* 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 documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/AtomMgr.h>
|
||||
#include <Xm/DragDrop.h>
|
||||
#include <Xm/DragC.h>
|
||||
#include <Xm/DragCP.h>
|
||||
#include <Xm/DragOverSP.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Drag Initiator Callbacks
|
||||
*/
|
||||
static Boolean dndConvertProc(Widget, Atom*, Atom*, Atom*, XtPointer *,
|
||||
unsigned long*, int*);
|
||||
static void dndAppConvert(Widget, int, XEvent*, DtDragInfo*);
|
||||
static void dndDropStartCallback(Widget, XtPointer, XtPointer);
|
||||
static void dndDropFinishCallback(Widget, XtPointer, XtPointer);
|
||||
static void dndDragDropFinishCallback(Widget, XtPointer, XtPointer);
|
||||
static void dndTopLevelEnterCallback(Widget, XtPointer, XtPointer);
|
||||
static void dndTopLevelLeaveCallback(Widget, XtPointer, XtPointer);
|
||||
|
||||
/*
|
||||
* Drag Initiator Resources
|
||||
*/
|
||||
typedef struct {
|
||||
XtCallbackList dropOnRootCallback;
|
||||
Widget sourceIcon;
|
||||
Boolean bufferIsText;
|
||||
} DragSettings;
|
||||
|
||||
#define Offset(field) XtOffsetOf(DragSettings, field)
|
||||
|
||||
static XtResource dragResources[] = {
|
||||
{ DtNdropOnRootCallback, DtCDropOnRootCallback,
|
||||
XtRCallback, sizeof(XtCallbackList), Offset(dropOnRootCallback),
|
||||
XtRImmediate, (XtPointer)NULL},
|
||||
{ DtNsourceIcon, DtCSourceIcon,
|
||||
XtRWidget, sizeof(Widget), Offset(sourceIcon),
|
||||
XtRImmediate, (XtPointer)NULL },
|
||||
{ DtNbufferIsText, DtCBufferIsText,
|
||||
XtRBoolean, sizeof(Boolean), Offset(bufferIsText),
|
||||
XtRImmediate, (XtPointer)False },
|
||||
};
|
||||
|
||||
#undef Offset
|
||||
|
||||
/*
|
||||
* DtDndVaDragStart
|
||||
*
|
||||
* Drag Start - varargs version
|
||||
*/
|
||||
|
||||
Widget
|
||||
DtDndVaDragStart(
|
||||
Widget dragInitiator,
|
||||
XEvent* event,
|
||||
DtDndProtocol protocol,
|
||||
Cardinal numItems,
|
||||
unsigned char operations,
|
||||
XtCallbackList dragConvertCallback,
|
||||
XtCallbackList dragFinishCallback,
|
||||
...)
|
||||
{
|
||||
Widget dragContext;
|
||||
va_list vaList;
|
||||
ArgList argList;
|
||||
Cardinal argCount;
|
||||
_DtSvcWidgetToAppContext(dragInitiator);
|
||||
|
||||
_DtSvcAppLock(app);
|
||||
|
||||
va_start(vaList, dragFinishCallback);
|
||||
argCount = _DtDndCountVarArgs(vaList);
|
||||
va_end(vaList);
|
||||
|
||||
va_start(vaList, dragFinishCallback);
|
||||
_DtDndArgListFromVarArgs(vaList, argCount, &argList, &argCount);
|
||||
va_end(vaList);
|
||||
|
||||
dragContext = DtDndDragStart(dragInitiator, event, protocol,
|
||||
numItems, operations,
|
||||
dragConvertCallback, dragFinishCallback,
|
||||
argList, argCount);
|
||||
|
||||
XtFree((char *)argList);
|
||||
|
||||
_DtSvcAppUnlock(app);
|
||||
return dragContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* DtDndVaDragStart
|
||||
*
|
||||
* Drag Start - arglist version
|
||||
*/
|
||||
|
||||
Widget
|
||||
DtDndDragStart(
|
||||
Widget dragInitiator,
|
||||
XEvent* event,
|
||||
DtDndProtocol protocol,
|
||||
Cardinal numItems,
|
||||
unsigned char operations,
|
||||
XtCallbackList dragConvertCallback,
|
||||
XtCallbackList dragFinishCallback,
|
||||
ArgList argList,
|
||||
Cardinal argCount)
|
||||
{
|
||||
XtCallbackRec dragDropFinishCbRec[] = { {dndDragDropFinishCallback,
|
||||
NULL}, {NULL, NULL} };
|
||||
XtCallbackRec topLevelEnterCbRec[] = { {dndTopLevelEnterCallback,
|
||||
NULL}, {NULL, NULL} };
|
||||
XtCallbackRec topLevelLeaveCbRec[] = { {dndTopLevelLeaveCallback,
|
||||
NULL}, {NULL, NULL} };
|
||||
XtCallbackRec dropStartCbRec[] = { {dndDropStartCallback,
|
||||
NULL}, {NULL, NULL} };
|
||||
XtCallbackRec dropFinishCbRec[] = { {dndDropFinishCallback,
|
||||
NULL}, {NULL, NULL} };
|
||||
Display * display = XtDisplayOfObject(dragInitiator);
|
||||
Screen * screen = XtScreenOfObject(dragInitiator);
|
||||
Window rootWindow = RootWindowOfScreen(screen);
|
||||
DtDragInfo * dtDragInfo;
|
||||
DragSettings settings;
|
||||
DtDndDragSource sourceType;
|
||||
DtDndTransfer * transfer;
|
||||
Arg * args;
|
||||
int ii, nn, savedEventType;
|
||||
Atom * exportTargets;
|
||||
Cardinal numExportTargets;
|
||||
_DtSvcWidgetToAppContext(dragInitiator);
|
||||
|
||||
_DtSvcAppLock(app);
|
||||
/*
|
||||
* Reject the drag if noop or multiple protocols specified
|
||||
*/
|
||||
|
||||
switch (protocol) {
|
||||
case DtDND_BUFFER_TRANSFER:
|
||||
case DtDND_FILENAME_TRANSFER:
|
||||
case DtDND_TEXT_TRANSFER:
|
||||
break;
|
||||
case DtDND_NOOP_TRANSFER:
|
||||
default:
|
||||
_DtSvcAppUnlock(app);
|
||||
return (Widget)NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse resources into dragResources
|
||||
*/
|
||||
|
||||
XtGetSubresources(dragInitiator, &settings,
|
||||
(String)NULL, (String)NULL,
|
||||
dragResources, XtNumber(dragResources),
|
||||
argList, argCount);
|
||||
|
||||
/*
|
||||
* Initialize DragInfo
|
||||
*/
|
||||
|
||||
dtDragInfo = (DtDragInfo *) XtMalloc(sizeof(DtDragInfo));
|
||||
|
||||
dtDragInfo->dragInitiator = dragInitiator;
|
||||
dtDragInfo->dragContext = NULL;
|
||||
dtDragInfo->protocol = protocol;
|
||||
dtDragInfo->numItems = numItems;
|
||||
dtDragInfo->operations = operations;
|
||||
dtDragInfo->sourceIcon = settings.sourceIcon;
|
||||
dtDragInfo->bufferIsText = settings.bufferIsText;
|
||||
dtDragInfo->dragData = NULL;
|
||||
dtDragInfo->inRoot = False;
|
||||
dtDragInfo->status = DtDND_SUCCESS;
|
||||
dtDragInfo->clientData = NULL;
|
||||
dtDragInfo->backdropWindow
|
||||
= DtWsmGetCurrentBackdropWindow(display, rootWindow);
|
||||
|
||||
dtDragInfo->dragConvertCallback
|
||||
= _DtDndCopyCallbackList(dragConvertCallback);
|
||||
dtDragInfo->dragFinishCallback
|
||||
= _DtDndCopyCallbackList(dragFinishCallback);
|
||||
dtDragInfo->dropOnRootCallback
|
||||
= _DtDndCopyCallbackList(settings.dropOnRootCallback);
|
||||
|
||||
dtDragInfo->dragData = (DtDndContext *)XtCalloc(1,sizeof(DtDndContext));
|
||||
dtDragInfo->dragData->protocol = dtDragInfo->protocol;
|
||||
dtDragInfo->dragData->numItems = 0;
|
||||
|
||||
/*
|
||||
* Get data transfer method
|
||||
* Use the transfer targets as export targets
|
||||
*/
|
||||
|
||||
dtDragInfo->transfer = _DtDndCreateExportTransfer(dtDragInfo);
|
||||
|
||||
exportTargets = dtDragInfo->transfer->targets;
|
||||
numExportTargets = dtDragInfo->transfer->numTargets;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("DtDndDragStart: drag from widget 0x%p\n", dragInitiator);
|
||||
_DtDndPrintTransfers(display,dtDragInfo->transfer,1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up drag icon
|
||||
*/
|
||||
|
||||
if (numItems > 1) {
|
||||
sourceType = DtDND_DRAG_SOURCE_MULTIPLE;
|
||||
} else {
|
||||
sourceType = dtDragInfo->transfer->methods->sourceType;
|
||||
}
|
||||
|
||||
_DtDndSelectDragSource(dragInitiator, sourceType,
|
||||
dtDragInfo->sourceIcon);
|
||||
|
||||
/*
|
||||
* Construct argument list
|
||||
*/
|
||||
|
||||
#define NUM_DRAG_ARGS 30
|
||||
args = (Arg *) XtMalloc(sizeof(Arg) * (NUM_DRAG_ARGS + argCount));
|
||||
#undef NUM_DRAG_ARGS
|
||||
|
||||
/*
|
||||
* Copy in passed arguments
|
||||
*/
|
||||
nn = 0;
|
||||
|
||||
for (ii = 0; ii < argCount; ii++) {
|
||||
XtSetArg(args[nn], argList[ii].name, argList[ii].value); nn++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set basic drag start arguments
|
||||
*/
|
||||
|
||||
XtSetArg(args[nn], XmNexportTargets, exportTargets);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNnumExportTargets, numExportTargets);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNdragOperations, operations);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNblendModel, XmBLEND_ALL);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNcursorBackground, WhitePixelOfScreen(screen));
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNcursorForeground, BlackPixelOfScreen(screen));
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNclientData, dtDragInfo);
|
||||
nn++;
|
||||
|
||||
if (dtDragInfo->sourceIcon != NULL) {
|
||||
XtSetArg(args[nn],XmNsourcePixmapIcon, dtDragInfo->sourceIcon);
|
||||
nn++;
|
||||
XtSetArg(args[nn],XmNsourceCursorIcon, dtDragInfo->sourceIcon);
|
||||
nn++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up DnD callbacks for Motif
|
||||
*/
|
||||
|
||||
XtSetArg(args[nn], XmNconvertProc, dndConvertProc);
|
||||
nn++;
|
||||
|
||||
dragDropFinishCbRec[0].closure = (XtPointer) dtDragInfo;
|
||||
dropFinishCbRec[0].closure = (XtPointer) dtDragInfo;
|
||||
dtDragInfo->dragDropFinishCallback
|
||||
= _DtDndCopyCallbackList(dragDropFinishCbRec);
|
||||
dtDragInfo->dropFinishCallback
|
||||
= _DtDndCopyCallbackList(dropFinishCbRec);
|
||||
|
||||
XtSetArg(args[nn], XmNdragDropFinishCallback, dtDragInfo->dragDropFinishCallback);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNdropFinishCallback, dtDragInfo->dropFinishCallback);
|
||||
nn++;
|
||||
|
||||
/*
|
||||
* Only use top-level-enter/leave callbacks if also doing drop-on-root
|
||||
*/
|
||||
|
||||
if (dtDragInfo->dropOnRootCallback != NULL) {
|
||||
|
||||
topLevelEnterCbRec[0].closure = (XtPointer) dtDragInfo;
|
||||
topLevelLeaveCbRec[0].closure = (XtPointer) dtDragInfo;
|
||||
dropStartCbRec[0].closure = (XtPointer) dtDragInfo;
|
||||
dtDragInfo->topLevelEnterCallback
|
||||
= _DtDndCopyCallbackList(topLevelEnterCbRec);
|
||||
dtDragInfo->topLevelLeaveCallback
|
||||
= _DtDndCopyCallbackList(topLevelLeaveCbRec);
|
||||
dtDragInfo->dropStartCallback
|
||||
= _DtDndCopyCallbackList(dropStartCbRec);
|
||||
|
||||
XtSetArg(args[nn], XmNtopLevelEnterCallback, dtDragInfo->topLevelEnterCallback);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNtopLevelLeaveCallback, dtDragInfo->topLevelLeaveCallback);
|
||||
nn++;
|
||||
XtSetArg(args[nn], XmNdropStartCallback, dtDragInfo->dropStartCallback);
|
||||
nn++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fake a button press. This is necessary because Motif requires
|
||||
* a drag to start on a button press. We need to be able to start
|
||||
* a drag on a mouse motion event when Bselect is held down. Since
|
||||
* the motion event has the fields necessary for Motif this works.
|
||||
*/
|
||||
|
||||
savedEventType = event->type;
|
||||
|
||||
if (event->type == MotionNotify) {
|
||||
event->type = ButtonPress;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the drag
|
||||
*/
|
||||
|
||||
dtDragInfo->dragContext = XmDragStart(dragInitiator, event, args, nn);
|
||||
|
||||
XtFree((char *)args);
|
||||
|
||||
event->type = savedEventType;
|
||||
|
||||
_DtSvcAppUnlock(app);
|
||||
return (dtDragInfo->dragContext);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Drag Initiator Callbacks
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/*
|
||||
* dndDropStartCallback
|
||||
*
|
||||
*
|
||||
*/
|
||||
static void
|
||||
dndDropStartCallback(
|
||||
Widget dragContext,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
|
||||
DtDndContext *dragData;
|
||||
XmDragContext xmDragContext = (XmDragContext)dtDragInfo->dragContext;
|
||||
XmDropStartCallbackStruct *xmDropInfo = (XmDropStartCallback) callData;
|
||||
DtDndTransferCallbackStruct dropCallData;
|
||||
int posOffsetX, posOffsetY;
|
||||
|
||||
/*
|
||||
* If the user has cancelled the drop, or the drop isn't on the
|
||||
* root, or there are no dropOnRoot or convert callbacks
|
||||
* then reject the drop.
|
||||
*/
|
||||
|
||||
if (xmDragContext->drag.dragCompletionStatus == XmDROP_CANCEL ||
|
||||
dtDragInfo->inRoot == False ||
|
||||
dtDragInfo->dropOnRootCallback == NULL ||
|
||||
dtDragInfo->dragConvertCallback == NULL ) {
|
||||
|
||||
xmDropInfo->dropSiteStatus = XmINVALID_DROP_SITE;
|
||||
xmDropInfo->dropAction = XmDROP_CANCEL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is to handle the dropOnRoot situation.
|
||||
* We handle both the convert and transfer sides of the
|
||||
* transaction here. First we get the application drag data
|
||||
* and then we call the application dropOnRoot callback.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize protocol specific dragData
|
||||
*/
|
||||
|
||||
dtDragInfo->dragData->numItems = dtDragInfo->numItems;
|
||||
|
||||
(*dtDragInfo->transfer->methods->convertInit)(dtDragInfo);
|
||||
|
||||
/*
|
||||
* Invoke the application convert callback
|
||||
*/
|
||||
|
||||
dndAppConvert(dragContext, DtCR_DND_CONVERT_DATA,
|
||||
xmDropInfo->event, dtDragInfo);
|
||||
|
||||
if (dtDragInfo->status == DtDND_FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup dropOnRootcall data and invoke the dropOnroot callback
|
||||
*/
|
||||
|
||||
_DtDndGetIconOffset(dtDragInfo->dragContext,
|
||||
dtDragInfo->transfer->methods->sourceType,
|
||||
&posOffsetX, &posOffsetY);
|
||||
|
||||
dropCallData.reason = DtCR_DND_ROOT_TRANSFER;
|
||||
dropCallData.event = xmDropInfo->event;
|
||||
dropCallData.x = xmDropInfo->x + posOffsetX;
|
||||
dropCallData.y = xmDropInfo->y + posOffsetY;
|
||||
dropCallData.operation = xmDropInfo->operation;
|
||||
dropCallData.dropData = dtDragInfo->dragData;
|
||||
dropCallData.completeMove = False;
|
||||
dropCallData.status = DtDND_SUCCESS;
|
||||
|
||||
_DtDndCallCallbackList(dragContext, dtDragInfo->dropOnRootCallback,
|
||||
(XtPointer)&dropCallData);
|
||||
|
||||
/*
|
||||
* Tell Motif that the root is a valid drop site
|
||||
*/
|
||||
|
||||
xmDropInfo->dropSiteStatus = XmVALID_DROP_SITE;
|
||||
xmDropInfo->dropAction = XmDROP;
|
||||
}
|
||||
|
||||
/*
|
||||
* dndConvertProc
|
||||
*
|
||||
*
|
||||
*/
|
||||
static Boolean
|
||||
dndConvertProc(
|
||||
Widget dragContext,
|
||||
Atom *selection,
|
||||
Atom *target,
|
||||
Atom *returnType,
|
||||
XtPointer *returnValue,
|
||||
unsigned long *returnLength,
|
||||
int *returnFormat)
|
||||
{
|
||||
Atom realSelectionAtom; /* Motif hides the selection atom */
|
||||
DtDragInfo *dtDragInfo = NULL;
|
||||
XSelectionRequestEvent *selectionRequestEvent;
|
||||
Boolean status;
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
Display *display = XtDisplayOfObject(dragContext);
|
||||
char *atomname = XGetAtomName(display,*target);
|
||||
printf("dndConvertProc: target = %s\n",(atomname ? atomname : "Null"));
|
||||
if (atomname) XFree(atomname);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Get the DtDragInfo
|
||||
*/
|
||||
|
||||
XtVaGetValues(dragContext, XmNclientData, &dtDragInfo, NULL);
|
||||
|
||||
if (dtDragInfo == NULL || dtDragInfo->status == DtDND_FAILURE) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get selection request event
|
||||
*/
|
||||
|
||||
XtVaGetValues(dragContext, XmNiccHandle, &realSelectionAtom, NULL);
|
||||
selectionRequestEvent = XtGetSelectionRequest(dragContext,
|
||||
realSelectionAtom, NULL); /* REMIND: NULL for atomic transfer */
|
||||
|
||||
/*
|
||||
* Get the application drag data if necessary
|
||||
*/
|
||||
|
||||
if (dtDragInfo->dragData->numItems == 0) {
|
||||
|
||||
dtDragInfo->dragData->numItems = dtDragInfo->numItems;
|
||||
|
||||
(*dtDragInfo->transfer->methods->convertInit)(dtDragInfo);
|
||||
|
||||
dndAppConvert(dragContext, DtCR_DND_CONVERT_DATA,
|
||||
(XEvent *)selectionRequestEvent, dtDragInfo);
|
||||
|
||||
if (dtDragInfo->status == DtDND_FAILURE) {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle transfer protocol independent target conversions
|
||||
*/
|
||||
|
||||
if (*target == XA_TARGETS) {
|
||||
/*
|
||||
* TARGETS Construct a list of targets consisting of those
|
||||
* the dnd library supports plus those supported by
|
||||
* the drag initiator.
|
||||
*/
|
||||
int ii, LIBRARY_TARGETS = 6;
|
||||
Atom * availTargets;
|
||||
Atom * allTargets;
|
||||
Cardinal numAvailTargets;
|
||||
Cardinal numAllTargets;
|
||||
|
||||
(*dtDragInfo->transfer->methods->getAvailTargets)(dtDragInfo,
|
||||
&availTargets, &numAvailTargets);
|
||||
|
||||
numAllTargets = numAvailTargets + LIBRARY_TARGETS;
|
||||
allTargets = (Atom *)XtMalloc(sizeof(Atom) * numAllTargets);
|
||||
|
||||
for (ii = 0; ii < numAvailTargets; ii++) {
|
||||
allTargets[ii] = availTargets[ii];
|
||||
}
|
||||
|
||||
XtFree((char *)availTargets);
|
||||
|
||||
ii = numAvailTargets;
|
||||
|
||||
allTargets[ii++] = XA_TARGETS;
|
||||
allTargets[ii++] = XA_TIMESTAMP;
|
||||
allTargets[ii++] = XA_MULTIPLE;
|
||||
allTargets[ii++] = XA_HOST_NAME;
|
||||
allTargets[ii++] = XA_SUN_FILE_HOST_NAME;
|
||||
allTargets[ii++] = XA_DELETE;
|
||||
|
||||
*returnType = XA_ATOM;
|
||||
*returnFormat = 32;
|
||||
*returnValue = (XtPointer)allTargets;
|
||||
*returnLength = numAllTargets * sizeof(Atom)/4;
|
||||
|
||||
status = True;
|
||||
|
||||
} else if (*target == XA_TIMESTAMP || *target == XA_MULTIPLE) {
|
||||
/*
|
||||
* TIMESTAMP and MULTIPLE are handled by the Intrinsics
|
||||
*/
|
||||
status = True;
|
||||
|
||||
} else if (*target == XA_HOST_NAME ||
|
||||
*target == XA_SUN_FILE_HOST_NAME) {
|
||||
/*
|
||||
* HOST_NAME, _SUN_FILE_HOST_NAME The name of this host
|
||||
*/
|
||||
*returnType = XA_STRING;
|
||||
*returnValue = (XtPointer)XtNewString(_DtDndGetHostName());
|
||||
*returnLength = strlen((char *)*returnValue) + 1;
|
||||
*returnFormat = 8;
|
||||
|
||||
status = True;
|
||||
|
||||
} else if (*target == XA_DELETE) {
|
||||
/*
|
||||
* DELETE Set up convert callback data to specify
|
||||
* deletion and invoke the application-defined
|
||||
* convertCallback() to perform the delete.
|
||||
*/
|
||||
|
||||
*returnType = XA_NULL;
|
||||
*returnFormat = 32;
|
||||
*returnValue = (XtPointer) NULL;
|
||||
*returnLength = 0;
|
||||
|
||||
dndAppConvert(dragContext, DtCR_DND_CONVERT_DELETE,
|
||||
(XEvent *)selectionRequestEvent, dtDragInfo);
|
||||
|
||||
status = True;
|
||||
|
||||
} else if (*target == XA_SUN_ENUM_COUNT) {
|
||||
/*
|
||||
* _SUN_ENUMERATION_COUNT The number of items available
|
||||
*/
|
||||
int *count = XtNew(int);
|
||||
|
||||
if (dtDragInfo->dragData->numItems == 1) {
|
||||
count[0] = 1;
|
||||
} else {
|
||||
count[0] = 0;
|
||||
dtDragInfo->status = DtDND_FAILURE;
|
||||
}
|
||||
|
||||
*returnType = XA_INTEGER;
|
||||
*returnValue = (XtPointer)count;
|
||||
*returnLength = 1;
|
||||
*returnFormat = 32;
|
||||
|
||||
status = True;
|
||||
} else {
|
||||
/*
|
||||
* Invoke protocol specific convert method
|
||||
*/
|
||||
status = (*dtDragInfo->transfer->methods->convert)(
|
||||
dragContext, dtDragInfo,
|
||||
selection, target,
|
||||
returnType, returnValue,
|
||||
returnLength, returnFormat,
|
||||
selectionRequestEvent);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* dndAppConvert
|
||||
*
|
||||
* Call the application convert callback
|
||||
*/
|
||||
static void
|
||||
dndAppConvert(
|
||||
Widget dragContext,
|
||||
int reason,
|
||||
XEvent * event,
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndConvertCallbackStruct convertCallData;
|
||||
|
||||
convertCallData.reason = reason;
|
||||
convertCallData.event = event;
|
||||
convertCallData.dragData = dtDragInfo->dragData;
|
||||
convertCallData.status = DtDND_SUCCESS;
|
||||
|
||||
_DtDndCallCallbackList(dragContext, dtDragInfo->dragConvertCallback,
|
||||
(XtPointer)&convertCallData);
|
||||
|
||||
dtDragInfo->status = convertCallData.status;
|
||||
|
||||
if (reason == DtCR_DND_CONVERT_DATA &&
|
||||
dtDragInfo->dragData->numItems <= 0) {
|
||||
dtDragInfo->status = DtDND_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* dndDropFinishCallback
|
||||
*
|
||||
* Handle drop-on-root case
|
||||
*/
|
||||
static void
|
||||
dndDropFinishCallback(
|
||||
Widget dragContext,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
|
||||
XmDropFinishCallbackStruct *xmDropFinishCallData =
|
||||
(XmDropFinishCallbackStruct *) callData;
|
||||
|
||||
if (dtDragInfo->dropOnRootCallback != NULL &&
|
||||
dtDragInfo->inRoot &&
|
||||
xmDropFinishCallData->dropSiteStatus == XmVALID_DROP_SITE) {
|
||||
|
||||
xmDropFinishCallData->completionStatus = XmDROP_SUCCESS;
|
||||
|
||||
XtVaSetValues(dtDragInfo->dragContext,
|
||||
XmNblendModel, XmBLEND_NONE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dndDragDropFinishCallback
|
||||
*
|
||||
* Call the application dragFinishCallback
|
||||
*/
|
||||
static void
|
||||
dndDragDropFinishCallback(
|
||||
Widget dragContext,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
XmDragDropFinishCallbackStruct *xmDndFinishInfo =
|
||||
(XmDragDropFinishCallbackStruct *)callData;
|
||||
DtDragInfo *dtDragInfo = (DtDragInfo *)clientData;
|
||||
DtDndDragFinishCallbackStruct dragFinishCallData;
|
||||
|
||||
/*
|
||||
* Invoke application dragFinishCallback
|
||||
*/
|
||||
|
||||
dragFinishCallData.reason = DtCR_DND_DRAG_FINISH;
|
||||
dragFinishCallData.event = xmDndFinishInfo->event;
|
||||
dragFinishCallData.sourceIcon = dtDragInfo->sourceIcon;
|
||||
dragFinishCallData.dragData = dtDragInfo->dragData;
|
||||
|
||||
_DtDndCallCallbackList(dragContext, dtDragInfo->dragFinishCallback,
|
||||
(XtPointer)&dragFinishCallData);
|
||||
|
||||
/*
|
||||
* Restore motif default drag cursors
|
||||
*/
|
||||
|
||||
_DtDndSelectDragSource(dragContext, DtDND_DRAG_SOURCE_DEFAULT, NULL);
|
||||
|
||||
/*
|
||||
* Invoke protocol specific convertFinish
|
||||
*/
|
||||
|
||||
(*dtDragInfo->transfer->methods->convertFinish)(dtDragInfo);
|
||||
|
||||
/*
|
||||
* Free data structures allocated during the drag
|
||||
*/
|
||||
|
||||
XtFree((char *)dtDragInfo->transfer->targets);
|
||||
XtFree((char *)dtDragInfo->transfer);
|
||||
XtFree((char *)dtDragInfo->dragConvertCallback);
|
||||
XtFree((char *)dtDragInfo->dragFinishCallback);
|
||||
XtFree((char *)dtDragInfo->dragDropFinishCallback);
|
||||
XtFree((char *)dtDragInfo->dropFinishCallback);
|
||||
if (dtDragInfo->dropOnRootCallback != NULL) {
|
||||
XtFree((char *)dtDragInfo->topLevelEnterCallback);
|
||||
XtFree((char *)dtDragInfo->topLevelLeaveCallback);
|
||||
XtFree((char *)dtDragInfo->dropStartCallback);
|
||||
}
|
||||
XtFree((char *)dtDragInfo->dropOnRootCallback);
|
||||
XtFree((char *)dtDragInfo->dragData);
|
||||
XtFree((char *)dtDragInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* dndTopLevelEnterCallback -- Support for drop-on-root callback.
|
||||
* When a drop-on-root callback has been set, determines if
|
||||
* the drag has entered the root window (or equivalents)
|
||||
* and sneakily changes Motif's idea that the root is an
|
||||
* invalid drop site to think that it's really a valid one.
|
||||
* Also updates dtDragInfo.inRoot as needed.
|
||||
*/
|
||||
static void
|
||||
dndTopLevelEnterCallback(
|
||||
Widget dragContext,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
XmTopLevelEnterCallbackStruct *xmEnterInfo =
|
||||
(XmTopLevelEnterCallbackStruct *) callData;
|
||||
DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
|
||||
XmDragContext xmDragContext = (XmDragContext) dragContext;
|
||||
XmDragOverShellWidget dragOverShell = xmDragContext->drag.curDragOver;
|
||||
|
||||
|
||||
if (xmEnterInfo->window == RootWindowOfScreen(xmEnterInfo->screen) ||
|
||||
dtDragInfo->backdropWindow == xmEnterInfo->window ) {
|
||||
|
||||
dragOverShell->drag.cursorState = XmVALID_DROP_SITE;
|
||||
_XmDragOverChange((Widget)dragOverShell,
|
||||
dragOverShell->drag.cursorState);
|
||||
|
||||
dtDragInfo->inRoot = True;
|
||||
|
||||
} else {
|
||||
dtDragInfo->inRoot = False;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dndTopLevelLeaveCallback -- Support for drop-on-root callback.
|
||||
* When a drop-on-root callback has been set, determines if
|
||||
* the drag is exiting the root window and restores Motif's
|
||||
* internal state back to thinking that the root window is
|
||||
* an invalid drop site. We don't update dtDragInfo->inRoot
|
||||
* here since the top-level-leave callback is called before
|
||||
* the drop callback which needs to know if we're in the root
|
||||
* or not.
|
||||
*/
|
||||
static void
|
||||
dndTopLevelLeaveCallback(
|
||||
Widget dragContext,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
XmTopLevelLeaveCallbackStruct *xmLeaveInfo =
|
||||
(XmTopLevelLeaveCallbackStruct *) callData;
|
||||
DtDragInfo *dtDragInfo = (DtDragInfo *) clientData;
|
||||
XmDragContext xmDragContext = (XmDragContext) dragContext;
|
||||
XmDragOverShellWidget dragOverShell = xmDragContext->drag.curDragOver;
|
||||
|
||||
|
||||
if (xmLeaveInfo->window == RootWindowOfScreen(xmLeaveInfo->screen) ||
|
||||
dtDragInfo->backdropWindow == xmLeaveInfo->window ) {
|
||||
|
||||
dragOverShell->drag.cursorState = XmINVALID_DROP_SITE;
|
||||
|
||||
_XmDragOverChange((Widget)dragOverShell,
|
||||
dragOverShell->drag.cursorState);
|
||||
}
|
||||
}
|
||||
1066
cde/lib/DtSvc/DtUtil1/DndDrop.c
Normal file
1066
cde/lib/DtSvc/DtUtil1/DndDrop.c
Normal file
File diff suppressed because it is too large
Load Diff
644
cde/lib/DtSvc/DtUtil1/DndFile.c
Normal file
644
cde/lib/DtSvc/DtUtil1/DndFile.c
Normal file
@@ -0,0 +1,644 @@
|
||||
/* $TOG: DndFile.c /main/5 1998/04/09 17:48:19 mgreess $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndFile.c
|
||||
*
|
||||
* Description: Implementation of the File Transfer routines
|
||||
* for the DND Convenience API.
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*
|
||||
* 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 documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/AtomMgr.h>
|
||||
#include <Xm/DragC.h>
|
||||
#include <Xm/DropSMgr.h>
|
||||
#include <Xm/DropTrans.h>
|
||||
#include <Tt/tt_c.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* File Transfer Protocol Function Prototypes
|
||||
*/
|
||||
|
||||
static void dndFileGetTargets(Boolean, Boolean, Atom**, Cardinal*);
|
||||
static void dndFileGetAvailTargets(DtDragInfo*, Atom**, Cardinal*);
|
||||
static void dndFileGetExportTargets(DtDragInfo*, Atom**, Cardinal*);
|
||||
static void dndFileGetImportTargets(DtDropInfo*, Atom**, Cardinal*);
|
||||
static void dndFileConvertInit(DtDragInfo*);
|
||||
static Boolean dndFileConvert(Widget, DtDragInfo*, Atom*, Atom*,
|
||||
Atom*, XtPointer*, unsigned long*, int*,
|
||||
XSelectionRequestEvent*);
|
||||
static void dndFileConvertFinish(DtDragInfo*);
|
||||
static void dndFileTransferTargets(DtDropInfo*,
|
||||
Atom*, Cardinal, Atom**, Cardinal*);
|
||||
static void dndFileTransfer(Widget, DtDropInfo*, Atom*, Atom*, Atom*,
|
||||
XtPointer, unsigned long*, int*);
|
||||
static void dndFileTransferFinish(DtDropInfo*);
|
||||
|
||||
/*
|
||||
* File Transfer Support Functions
|
||||
*/
|
||||
|
||||
static Boolean dndFileContentsToSelectionValue(String,
|
||||
Atom*, XtPointer*, unsigned long*, int*);
|
||||
static Boolean dndFileListToSelectionValue(String*, Cardinal, Boolean,
|
||||
Atom*, XtPointer*, unsigned long*, int*);
|
||||
static Boolean dndSelectionValueToFileList(Atom, XtPointer, unsigned long, int,
|
||||
Boolean, String**, Cardinal*);
|
||||
static String dndFileEncode(String, Boolean);
|
||||
static String dndFileDecode(String, Boolean);
|
||||
|
||||
/*
|
||||
* File Transfer Selection Targets
|
||||
*/
|
||||
|
||||
static Atom XA_FILE_NAME;
|
||||
static Atom XA_DT_NETFILE;
|
||||
|
||||
/*
|
||||
* File Transfer Protocol Methods
|
||||
*/
|
||||
|
||||
static DtDndMethods dndFileTransferProtocol = {
|
||||
"DtDndFileNameTransfer", /* name */
|
||||
(DtDndProtocol)DtDND_FILENAME_TRANSFER, /* protocol */
|
||||
DtDND_DRAG_SOURCE_DATA, /* sourceType */
|
||||
dndFileGetAvailTargets, /* getAvailTargets */
|
||||
dndFileGetExportTargets, /* getExportTargets */
|
||||
dndFileGetImportTargets, /* getImportTargets */
|
||||
dndFileConvertInit, /* convertInit */
|
||||
dndFileConvert, /* convert */
|
||||
dndFileConvertFinish, /* convertFinish */
|
||||
dndFileTransferTargets, /* transferTargets */
|
||||
dndFileTransfer, /* transfer */
|
||||
dndFileTransferFinish, /* transferFinish */
|
||||
};
|
||||
|
||||
typedef struct _ConvertState {
|
||||
Boolean owCompat;
|
||||
} ConvertState;
|
||||
|
||||
/*
|
||||
* File transfer protocol initialization
|
||||
*/
|
||||
DtDndMethods *
|
||||
_DtDndFileTransferProtocolInitialize(
|
||||
Display * dpy)
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if (XA_FILE_NAME == 0) {
|
||||
XA_FILE_NAME = DtGetAtom(dpy,"FILE_NAME");
|
||||
XA_DT_NETFILE = DtGetAtom(dpy,"_DT_NETFILE");
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return &dndFileTransferProtocol;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns generic export/import targets for filename transfers
|
||||
*/
|
||||
static void
|
||||
dndFileGetTargets(
|
||||
Boolean doHost,
|
||||
Boolean owCompat,
|
||||
Atom ** targets,
|
||||
Cardinal * numTargets)
|
||||
{
|
||||
int ii = 0;
|
||||
|
||||
*numTargets = 2 + (doHost ? 1 : 0) + (owCompat ? 4 : 0);
|
||||
|
||||
*targets = (Atom *)XtMalloc(*numTargets * sizeof(Atom));
|
||||
|
||||
(*targets)[ii++] = XA_DT_NETFILE;
|
||||
(*targets)[ii++] = XA_FILE_NAME;
|
||||
|
||||
if (doHost) {
|
||||
(*targets)[ii++] = XA_HOST_NAME;
|
||||
}
|
||||
|
||||
if (owCompat) {
|
||||
(*targets)[ii++] = XA_TEXT;
|
||||
(*targets)[ii++] = XA_STRING;
|
||||
(*targets)[ii++] = XA_SUN_DATA_LABEL;
|
||||
(*targets)[ii++] = XA_SUN_ATM_METHODS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns available targets for filename transfers
|
||||
*/
|
||||
static void
|
||||
dndFileGetAvailTargets(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** availTargets,
|
||||
Cardinal * numAvailTargets)
|
||||
{
|
||||
dndFileGetTargets(True, True, availTargets, numAvailTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns export targets for filename transfers
|
||||
*/
|
||||
static void
|
||||
dndFileGetExportTargets(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** exportTargets,
|
||||
Cardinal * numExportTargets)
|
||||
{
|
||||
dndFileGetTargets(True, False, exportTargets, numExportTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns import targets for filename transfers
|
||||
*/
|
||||
static void
|
||||
dndFileGetImportTargets(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom ** importTargets,
|
||||
Cardinal * numImportTargets)
|
||||
{
|
||||
dndFileGetTargets(False, False, importTargets, numImportTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize protocol specific part of drag data
|
||||
*/
|
||||
static void
|
||||
dndFileConvertInit(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
ConvertState * cvtState;
|
||||
|
||||
dragData->data.files = (String *)
|
||||
XtMalloc(dragData->numItems * sizeof(String));
|
||||
|
||||
cvtState = (ConvertState *)XtCalloc(1,sizeof(ConvertState));
|
||||
dtDragInfo->clientData = (XtPointer)cvtState;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the file names into selection data
|
||||
*/
|
||||
static Boolean
|
||||
dndFileConvert(
|
||||
Widget dragContext,
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * returnType,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
int * returnFormat,
|
||||
XSelectionRequestEvent * selectionRequestEvent)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
ConvertState * cvtState = (ConvertState *)dtDragInfo->clientData;
|
||||
|
||||
*returnType = XA_NULL;
|
||||
*returnValue = (XtPointer)NULL;
|
||||
*returnLength = 0;
|
||||
*returnFormat = 8;
|
||||
|
||||
/*
|
||||
* Determine file encoding style.
|
||||
* Handle Sun ATM file name.
|
||||
* Reject unknown targets.
|
||||
*/
|
||||
|
||||
if (*target == XA_FILE_NAME || *target == XA_DT_NETFILE) {
|
||||
|
||||
if (!dndFileListToSelectionValue(
|
||||
dragData->data.files, dragData->numItems,
|
||||
(*target == XA_DT_NETFILE),
|
||||
returnType, returnValue,
|
||||
returnLength, returnFormat)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
} else if (*target == XA_TEXT || *target == XA_STRING) {
|
||||
|
||||
if (dragData->numItems > 1 || !cvtState->owCompat)
|
||||
return False;
|
||||
|
||||
if (!dndFileContentsToSelectionValue(dragData->data.files[0],
|
||||
returnType, returnValue,
|
||||
returnLength, returnFormat)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
} else if (*target == XA_SUN_SELN_READONLY) {
|
||||
|
||||
cvtState->owCompat = True;
|
||||
|
||||
} else if (*target == XA_SUN_DATA_LABEL) {
|
||||
String name;
|
||||
|
||||
if (dragData->numItems > 1)
|
||||
return False;
|
||||
|
||||
if ((name = strrchr(dragData->data.files[0],'/')) != NULL)
|
||||
name++;
|
||||
else
|
||||
name = dragData->data.files[0];
|
||||
|
||||
*returnType = XA_STRING;
|
||||
*returnValue = (XtPointer)XtNewString(name);
|
||||
*returnLength = strlen(*returnValue);
|
||||
*returnFormat = 8;
|
||||
|
||||
cvtState->owCompat = True;
|
||||
|
||||
} else if (*target == XA_SUN_ATM_METHODS) {
|
||||
|
||||
Atom *atmAtom = XtNew(Atom);
|
||||
|
||||
atmAtom[0] = XA_SUN_ATM_FILE_NAME;
|
||||
|
||||
*returnType = XA_ATOM;
|
||||
*returnValue = (XtPointer)atmAtom;
|
||||
*returnLength = 1;
|
||||
*returnFormat = 32;
|
||||
|
||||
cvtState->owCompat = True;
|
||||
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up from the convert init proc
|
||||
*/
|
||||
static void
|
||||
dndFileConvertFinish(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
|
||||
if (dragData->data.files) {
|
||||
XtFree((char *)dragData->data.files);
|
||||
dragData->data.files = NULL;
|
||||
}
|
||||
if (dtDragInfo->clientData)
|
||||
XtFree((char *)dtDragInfo->clientData);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the transfer targets selected from the export targets
|
||||
* Prefer _DT_NETFILE over FILE_NAME; prefer local host file names
|
||||
*/
|
||||
static void
|
||||
dndFileTransferTargets(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * exportTargets,
|
||||
Cardinal numExportTargets,
|
||||
Atom ** transferTargets,
|
||||
Cardinal * numTransferTargets)
|
||||
{
|
||||
Boolean foundNetFile, foundFileName, foundHostName;
|
||||
Atom target;
|
||||
int ii;
|
||||
|
||||
foundNetFile = foundFileName = foundHostName = False;
|
||||
|
||||
for (ii = 0; ii < numExportTargets; ii++) {
|
||||
if (exportTargets[ii] == XA_DT_NETFILE) {
|
||||
foundNetFile = True;
|
||||
} else if (exportTargets[ii] == XA_FILE_NAME) {
|
||||
foundFileName = True;
|
||||
} else if (exportTargets[ii] == XA_HOST_NAME) {
|
||||
foundHostName = True;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundNetFile && foundFileName && foundHostName) {
|
||||
target = XA_HOST_NAME;
|
||||
} else if (foundNetFile) {
|
||||
target = XA_DT_NETFILE;
|
||||
} else if (foundFileName) {
|
||||
target = XA_FILE_NAME;
|
||||
} else {
|
||||
*numTransferTargets = 0;
|
||||
*transferTargets = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
*numTransferTargets = 1;
|
||||
|
||||
*transferTargets = (Atom *)XtMalloc(*numTransferTargets * sizeof(Atom));
|
||||
|
||||
(*transferTargets)[0] = target;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the selection data into file names
|
||||
*/
|
||||
static void
|
||||
dndFileTransfer(
|
||||
Widget dropTransfer,
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * type,
|
||||
XtPointer value,
|
||||
unsigned long * length,
|
||||
int * format)
|
||||
{
|
||||
DtDndContext * dropData = dtDropInfo->dropData;
|
||||
|
||||
/*
|
||||
* Ignore if we've already transferred
|
||||
*/
|
||||
|
||||
if (dropData->data.files) {
|
||||
XtFree(value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If hosts are the same then request FILE_NAME else request NETFILE
|
||||
*/
|
||||
if (*target == XA_HOST_NAME) {
|
||||
Atom target;
|
||||
|
||||
if (strcmp(_DtDndGetHostName(),(char *)value) == 0)
|
||||
target = XA_FILE_NAME;
|
||||
else
|
||||
target = XA_DT_NETFILE;
|
||||
|
||||
_DtDndTransferAdd(dropTransfer, dtDropInfo, &target, 1);
|
||||
|
||||
/*
|
||||
* Convert NETFILE or FILE_NAME selection to file list
|
||||
*/
|
||||
} else if (*target == XA_DT_NETFILE || *target == XA_FILE_NAME) {
|
||||
|
||||
if (!dndSelectionValueToFileList(*type, value,
|
||||
*length, *format, (*target == XA_DT_NETFILE),
|
||||
&(dropData->data.files), &(dropData->numItems))) {
|
||||
|
||||
dtDropInfo->status = DtDND_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (value != NULL)
|
||||
XtFree(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up from the transfer proc
|
||||
*/
|
||||
static void
|
||||
dndFileTransferFinish(
|
||||
DtDropInfo * dtDropInfo)
|
||||
{
|
||||
DtDndContext * dropData = dtDropInfo->dropData;
|
||||
int ii;
|
||||
|
||||
for (ii = 0; ii < dropData->numItems; ii++) {
|
||||
XtFree((char *)dropData->data.files[ii]);
|
||||
}
|
||||
XtFree((char *)dropData->data.files);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the file contents into a STRING selection
|
||||
*/
|
||||
static Boolean
|
||||
dndFileContentsToSelectionValue(
|
||||
String fileName,
|
||||
Atom * returnType,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
int * returnFormat)
|
||||
{
|
||||
String fullPath;
|
||||
struct stat stBuf;
|
||||
int fd;
|
||||
unsigned long bufLen, bytesRead;
|
||||
char * buf;
|
||||
|
||||
fullPath = dndFileEncode(fileName, False);
|
||||
|
||||
if (stat(fullPath,&stBuf) == -1)
|
||||
return False;
|
||||
|
||||
if ((fd = open(fullPath, O_RDONLY)) == -1)
|
||||
return False;
|
||||
|
||||
bufLen = stBuf.st_size;
|
||||
buf = (void *)XtMalloc(bufLen + 1);
|
||||
|
||||
bytesRead = read(fd, buf, bufLen);
|
||||
|
||||
if (bytesRead == -1 || bytesRead != bufLen) {
|
||||
XtFree((char *)buf);
|
||||
return False;
|
||||
}
|
||||
|
||||
buf[bufLen] = '\0';
|
||||
|
||||
*returnType = XA_STRING;
|
||||
*returnValue = (XtPointer)buf;
|
||||
*returnLength = bufLen;
|
||||
*returnFormat = 8;
|
||||
|
||||
XtFree(fullPath);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the filename list into a STRING selection
|
||||
*/
|
||||
static Boolean
|
||||
dndFileListToSelectionValue(
|
||||
String * fileList,
|
||||
Cardinal numFiles,
|
||||
Boolean doNetFile,
|
||||
Atom * returnType,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
int * returnFormat)
|
||||
{
|
||||
XTextProperty textProp;
|
||||
Status status;
|
||||
String * tmpList;
|
||||
Cardinal ii;
|
||||
|
||||
/*
|
||||
* Encode the file list
|
||||
*/
|
||||
|
||||
tmpList = (String *)XtMalloc(numFiles * sizeof(String));
|
||||
|
||||
for (ii = 0; ii < numFiles; ii++) {
|
||||
tmpList[ii] = dndFileEncode(fileList[ii], doNetFile);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the encoded file list into a string property
|
||||
*/
|
||||
|
||||
status = XStringListToTextProperty(tmpList, numFiles, &textProp);
|
||||
|
||||
for (ii = 0; ii < numFiles; ii++) {
|
||||
XtFree(tmpList[ii]);
|
||||
}
|
||||
|
||||
XtFree((char *)tmpList);
|
||||
|
||||
if (status == 0)
|
||||
return False;
|
||||
|
||||
*returnType = textProp.encoding;
|
||||
*returnValue = (XtPointer)textProp.value;
|
||||
*returnLength = textProp.nitems;
|
||||
*returnFormat = textProp.format;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the STRING selection into a filename list
|
||||
*/
|
||||
static Boolean
|
||||
dndSelectionValueToFileList(
|
||||
Atom type,
|
||||
XtPointer value,
|
||||
unsigned long length,
|
||||
int format,
|
||||
Boolean doNetFile,
|
||||
String ** returnFileList,
|
||||
Cardinal * returnNumFiles)
|
||||
{
|
||||
XTextProperty textProp;
|
||||
Status status;
|
||||
String * tmpList;
|
||||
String * fileList;
|
||||
int ii, numFiles;
|
||||
|
||||
/*
|
||||
* Convert text prop to file list
|
||||
*/
|
||||
|
||||
textProp.encoding = type;
|
||||
textProp.value = (unsigned char *)value;
|
||||
textProp.nitems = length;
|
||||
textProp.format = format;
|
||||
|
||||
status = XTextPropertyToStringList(&textProp, &tmpList, &numFiles);
|
||||
|
||||
if (status == 0)
|
||||
return False;
|
||||
|
||||
/*
|
||||
* Decode the file list
|
||||
*/
|
||||
|
||||
fileList = (String *)XtMalloc(numFiles * sizeof(String));
|
||||
|
||||
for (ii = 0; ii < numFiles; ii++) {
|
||||
fileList[ii] = dndFileDecode(tmpList[ii], doNetFile);
|
||||
}
|
||||
|
||||
XFreeStringList(tmpList);
|
||||
|
||||
*returnFileList = fileList;
|
||||
*returnNumFiles = numFiles;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes a file name
|
||||
* Either into ToolTalk NetFile or into a full path if needed
|
||||
*/
|
||||
static String
|
||||
dndFileEncode(
|
||||
String fileName,
|
||||
Boolean doNetFile)
|
||||
{
|
||||
String netFile;
|
||||
String retFile;
|
||||
|
||||
if (doNetFile) {
|
||||
netFile = tt_file_netfile(fileName);
|
||||
if (tt_ptr_error(netFile) == TT_OK) {
|
||||
retFile = XtNewString(netFile);
|
||||
} else {
|
||||
retFile = XtNewString(fileName);
|
||||
}
|
||||
tt_free(netFile);
|
||||
} else if (fileName[0] != '/') {
|
||||
char cwd[MAXPATHLEN];
|
||||
char *realPath;
|
||||
|
||||
if (getcwd(cwd,MAXPATHLEN) == NULL) {
|
||||
strcpy(cwd,"/");
|
||||
}
|
||||
realPath = XtMalloc(strlen(cwd) + strlen(fileName) + 2);
|
||||
sprintf(realPath,"%s/%s",cwd,fileName);
|
||||
retFile = realPath;
|
||||
} else {
|
||||
retFile = XtNewString(fileName);
|
||||
}
|
||||
return retFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes a file name; possibly from a ToolTalk NetFile
|
||||
*/
|
||||
static String
|
||||
dndFileDecode(
|
||||
String fileName,
|
||||
Boolean doNetFile)
|
||||
{
|
||||
String file;
|
||||
String retFile;
|
||||
|
||||
if (doNetFile) {
|
||||
file = tt_netfile_file(fileName);
|
||||
if (tt_ptr_error(file) == TT_OK) {
|
||||
retFile = XtNewString(file);
|
||||
} else {
|
||||
retFile = XtNewString(fileName);
|
||||
}
|
||||
tt_free(file);
|
||||
} else {
|
||||
retFile = XtNewString(fileName);
|
||||
}
|
||||
return retFile;
|
||||
}
|
||||
548
cde/lib/DtSvc/DtUtil1/DndIcon.c
Normal file
548
cde/lib/DtSvc/DtUtil1/DndIcon.c
Normal file
@@ -0,0 +1,548 @@
|
||||
/* $XConsortium: DndIcon.c /main/5 1996/06/21 17:28:34 ageorge $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndIcon.c
|
||||
*
|
||||
* Description: Implemenation of DND drag icons
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* 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 documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/Screen.h>
|
||||
#include <Xm/DragIcon.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DndIconI.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Component types of a drag icon (source/state/operation)
|
||||
*/
|
||||
|
||||
enum {
|
||||
DtDND_DRAG_SOURCE,
|
||||
DtDND_DRAG_STATE,
|
||||
DtDND_DRAG_OPERATION
|
||||
};
|
||||
|
||||
/*
|
||||
* The XmDragIcon widgets for the state & operation components
|
||||
* of a Drag Icon
|
||||
*/
|
||||
|
||||
typedef struct _DragIcons {
|
||||
Widget validIcon, invalidIcon, noneIcon;
|
||||
Widget moveIcon, copyIcon, linkIcon;
|
||||
} DragIcons;
|
||||
|
||||
/*
|
||||
* Collection of drag icons for text & data drags
|
||||
*/
|
||||
|
||||
typedef struct _DragCollection {
|
||||
DtDndDragSource sourceType;
|
||||
DragIcons text;
|
||||
DragIcons data;
|
||||
Widget textSource;
|
||||
Widget dataSource;
|
||||
Widget multipleSource;
|
||||
} DragCollection;
|
||||
|
||||
/*
|
||||
* The context that the DragCollection is stored against.
|
||||
* Used in getDragCollection() and destroyDragCollection().
|
||||
*/
|
||||
|
||||
static XContext dragCollectionContext;
|
||||
|
||||
/*
|
||||
* Creates an XmDragIcon for use as the source component of the drag icon.
|
||||
*/
|
||||
Widget
|
||||
DtDndCreateSourceIcon(
|
||||
Widget widget,
|
||||
Pixmap pixmap,
|
||||
Pixmap mask)
|
||||
{
|
||||
Widget dragIcon;
|
||||
Window rootWindow;
|
||||
int pixmapX, pixmapY;
|
||||
unsigned int pixmapWidth, pixmapHeight, pixmapBorder, pixmapDepth;
|
||||
Arg args[20];
|
||||
Cardinal nn = 0;
|
||||
_DtSvcWidgetToAppContext(widget);
|
||||
|
||||
_DtSvcAppLock(app);
|
||||
|
||||
while (XmIsGadget(widget)) {
|
||||
widget = XtParent(widget);
|
||||
}
|
||||
|
||||
XGetGeometry (XtDisplayOfObject(widget), pixmap, &rootWindow,
|
||||
&pixmapX, &pixmapY, &pixmapWidth, &pixmapHeight,
|
||||
&pixmapBorder, &pixmapDepth);
|
||||
|
||||
XtSetArg(args[nn], XmNwidth, pixmapWidth); nn++;
|
||||
XtSetArg(args[nn], XmNheight, pixmapHeight); nn++;
|
||||
XtSetArg(args[nn], XmNmaxWidth, pixmapWidth); nn++;
|
||||
XtSetArg(args[nn], XmNmaxHeight, pixmapHeight); nn++;
|
||||
XtSetArg(args[nn], XmNpixmap, pixmap); nn++;
|
||||
XtSetArg(args[nn], XmNmask, mask); nn++;
|
||||
XtSetArg(args[nn], XmNdepth, pixmapDepth); nn++;
|
||||
dragIcon = XmCreateDragIcon(widget, "sourceIcon", args, nn);
|
||||
|
||||
_DtSvcAppUnlock(app);
|
||||
return(dragIcon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the x,y offsets for the state cursor relative to the source
|
||||
*/
|
||||
static void
|
||||
calcStateIconOffset(
|
||||
Widget sourceIcon,
|
||||
int *stateOffsetX,
|
||||
int *stateOffsetY)
|
||||
{
|
||||
Display *dpy = XtDisplayOfObject(sourceIcon);
|
||||
Pixmap pixmap;
|
||||
Window root;
|
||||
int pixmapX, pixmapY;
|
||||
unsigned int pixmapW, pixmapH, junk;
|
||||
|
||||
XtVaGetValues(sourceIcon, XmNpixmap, &pixmap, NULL);
|
||||
|
||||
if (pixmap == None)
|
||||
return;
|
||||
|
||||
XGetGeometry(dpy, pixmap, &root,
|
||||
&pixmapX, &pixmapY, &pixmapW, &pixmapH,
|
||||
&junk, &junk);
|
||||
|
||||
if (pixmapH == 16) {
|
||||
*stateOffsetX = *stateOffsetY = 8;
|
||||
} else {
|
||||
*stateOffsetX = *stateOffsetY = 16;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects or activates the request type of source by setting
|
||||
* the default drag icon resources on the XmScreen widget.
|
||||
*/
|
||||
static void
|
||||
selectDragSource(
|
||||
DragCollection *dc,
|
||||
Widget xmScreen,
|
||||
DtDndDragSource sourceType,
|
||||
Widget sourceIcon)
|
||||
{
|
||||
Display *dpy = XtDisplayOfObject(xmScreen);
|
||||
Widget validIcon, invalidIcon, noneIcon,
|
||||
moveIcon, copyIcon, linkIcon,
|
||||
defSourceIcon;
|
||||
int hotX, hotY,
|
||||
stateOffsetX, stateOffsetY,
|
||||
offsetDeltaX, offsetDeltaY;
|
||||
Arg args[30];
|
||||
Cardinal nn = 0;
|
||||
|
||||
/*
|
||||
* Choose the state/operation/default-source drag icons based
|
||||
* on the requested drag-source-type
|
||||
*/
|
||||
switch (sourceType) {
|
||||
case DtDND_DRAG_SOURCE_TEXT:
|
||||
validIcon = dc->text.validIcon;
|
||||
invalidIcon = dc->text.invalidIcon;
|
||||
noneIcon = dc->text.noneIcon;
|
||||
moveIcon = dc->text.moveIcon;
|
||||
copyIcon = dc->text.copyIcon;
|
||||
linkIcon = dc->text.linkIcon;
|
||||
defSourceIcon = dc->textSource;
|
||||
hotX = text_x_hot;
|
||||
hotY = text_y_hot;
|
||||
stateOffsetX = text_x_offset_state;
|
||||
stateOffsetY = text_y_offset_state;
|
||||
offsetDeltaX = text_x_offset_delta;
|
||||
offsetDeltaY = text_y_offset_delta;
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_DATA:
|
||||
validIcon = dc->data.validIcon;
|
||||
invalidIcon = dc->data.invalidIcon;
|
||||
noneIcon = dc->data.noneIcon;
|
||||
moveIcon = dc->data.moveIcon;
|
||||
copyIcon = dc->data.copyIcon;
|
||||
linkIcon = dc->data.linkIcon;
|
||||
defSourceIcon = dc->dataSource;
|
||||
hotX = data_x_hot;
|
||||
hotY = data_y_hot;
|
||||
stateOffsetX = data_x_offset_state;
|
||||
stateOffsetY = data_y_offset_state;
|
||||
offsetDeltaX = data_x_offset_delta;
|
||||
offsetDeltaY = data_y_offset_delta;
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_MULTIPLE:
|
||||
validIcon = dc->data.validIcon;
|
||||
invalidIcon = dc->data.invalidIcon;
|
||||
noneIcon = dc->data.noneIcon;
|
||||
moveIcon = dc->data.moveIcon;
|
||||
copyIcon = dc->data.copyIcon;
|
||||
linkIcon = dc->data.linkIcon;
|
||||
defSourceIcon = dc->multipleSource;
|
||||
hotX = data_x_hot;
|
||||
hotY = data_y_hot;
|
||||
stateOffsetX = data_x_offset_state;
|
||||
stateOffsetY = data_y_offset_state;
|
||||
offsetDeltaX = data_x_offset_delta;
|
||||
offsetDeltaY = data_y_offset_delta;
|
||||
break;
|
||||
default:
|
||||
case DtDND_DRAG_SOURCE_DEFAULT:
|
||||
validIcon = NULL;
|
||||
invalidIcon = NULL;
|
||||
noneIcon = NULL;
|
||||
moveIcon = NULL;
|
||||
copyIcon = NULL;
|
||||
linkIcon = NULL;
|
||||
defSourceIcon = NULL;
|
||||
hotX = motif_x_hot;
|
||||
hotY = motif_y_hot;
|
||||
stateOffsetX = motif_x_offset_state;
|
||||
stateOffsetY = motif_y_offset_state;
|
||||
offsetDeltaX = motif_x_offset_delta;
|
||||
offsetDeltaY = motif_y_offset_delta;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the offsets of the state icon from the
|
||||
* DtDND_DRAG_SOURCE_DATA source icon if specified
|
||||
*/
|
||||
if (sourceIcon && sourceType == DtDND_DRAG_SOURCE_DATA) {
|
||||
calcStateIconOffset(sourceIcon, &stateOffsetX, &stateOffsetY);
|
||||
}
|
||||
|
||||
nn = 0;
|
||||
XtSetArg(args[nn], XmNhotX, hotX); nn++;
|
||||
XtSetArg(args[nn], XmNhotY, hotY); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetX, stateOffsetX); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, stateOffsetY); nn++;
|
||||
|
||||
if (validIcon)
|
||||
XtSetValues(validIcon, args, nn);
|
||||
if (invalidIcon)
|
||||
XtSetValues(invalidIcon, args, nn);
|
||||
if (noneIcon)
|
||||
XtSetValues(noneIcon, args, nn);
|
||||
|
||||
nn = 0;
|
||||
XtSetArg(args[nn], XmNoffsetX, stateOffsetX + offsetDeltaX); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, stateOffsetY + offsetDeltaY); nn++;
|
||||
|
||||
if (moveIcon)
|
||||
XtSetValues(moveIcon, args, nn);
|
||||
if (copyIcon)
|
||||
XtSetValues(copyIcon, args, nn);
|
||||
if (linkIcon)
|
||||
XtSetValues(linkIcon, args, nn);
|
||||
|
||||
/*
|
||||
* Set the default drag cursor icons for the XmScreen widget
|
||||
*/
|
||||
XtVaSetValues(xmScreen,
|
||||
XmNdefaultValidCursorIcon, validIcon,
|
||||
XmNdefaultInvalidCursorIcon, invalidIcon,
|
||||
XmNdefaultNoneCursorIcon, noneIcon,
|
||||
XmNdefaultMoveCursorIcon, moveIcon,
|
||||
XmNdefaultCopyCursorIcon, copyIcon,
|
||||
XmNdefaultLinkCursorIcon, linkIcon,
|
||||
XmNdefaultSourceCursorIcon, defSourceIcon,
|
||||
NULL);
|
||||
|
||||
dc->sourceType = sourceType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a drag icon widget from the passed bits
|
||||
*/
|
||||
static Widget
|
||||
makeDragIconFromData(
|
||||
Widget widget,
|
||||
unsigned char *bits,
|
||||
unsigned char *maskbits,
|
||||
int width,
|
||||
int height,
|
||||
int component)
|
||||
{
|
||||
Widget icon;
|
||||
Pixmap pixmap, mask;
|
||||
Display *dpy = XtDisplayOfObject(widget);
|
||||
Screen *screen = XtScreenOfObject(widget);
|
||||
Window root = RootWindowOfScreen(screen);
|
||||
String name;
|
||||
Arg args[30];
|
||||
Cardinal nn = 0;
|
||||
|
||||
pixmap = XCreatePixmapFromBitmapData(dpy, root,
|
||||
(char *)bits, width, height,
|
||||
1, 0, 1);
|
||||
|
||||
mask = XCreatePixmapFromBitmapData(dpy, root,
|
||||
(char *)maskbits, width, height,
|
||||
1, 0, 1);
|
||||
|
||||
switch (component) {
|
||||
case DtDND_DRAG_SOURCE:
|
||||
name = "sourceIcon";
|
||||
break;
|
||||
case DtDND_DRAG_STATE:
|
||||
name = "stateIcon";
|
||||
XtSetArg(args[nn], XmNattachment, XmATTACH_NORTH_WEST); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetX, -6); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, -6); nn++;
|
||||
XtSetArg(args[nn], XmNhotX, 3); nn++;
|
||||
XtSetArg(args[nn], XmNhotY, 3); nn++;
|
||||
break;
|
||||
case DtDND_DRAG_OPERATION:
|
||||
name = "operationIcon";
|
||||
XtSetArg(args[nn], XmNattachment, XmATTACH_NORTH_WEST); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetX, 1); nn++;
|
||||
XtSetArg(args[nn], XmNoffsetY, 1); nn++;
|
||||
break;
|
||||
}
|
||||
|
||||
XtSetArg(args[nn], XmNwidth, width); nn++;
|
||||
XtSetArg(args[nn], XmNheight, height); nn++;
|
||||
XtSetArg(args[nn], XmNmaxWidth, width); nn++;
|
||||
XtSetArg(args[nn], XmNmaxHeight, height); nn++;
|
||||
XtSetArg(args[nn], XmNpixmap, pixmap); nn++;
|
||||
XtSetArg(args[nn], XmNmask, mask); nn++;
|
||||
XtSetArg(args[nn], XmNdepth, 1); nn++;
|
||||
|
||||
icon = XmCreateDragIcon(widget, name, args, nn);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the collection of text & data drag icons; state/operation
|
||||
* cursors and source icons.
|
||||
*/
|
||||
static DragCollection *
|
||||
makeDragCollection(
|
||||
Widget widget)
|
||||
{
|
||||
DragCollection *dc = XtNew(DragCollection);
|
||||
Display *dpy = XtDisplayOfObject(widget);
|
||||
Screen *screen = XtScreenOfObject(widget);
|
||||
Window root = RootWindowOfScreen(screen);
|
||||
Widget xmScreen = XmGetXmScreen(screen);
|
||||
|
||||
/*
|
||||
* Text & Data State Cursors
|
||||
*/
|
||||
|
||||
dc->text.invalidIcon = makeDragIconFromData(widget,
|
||||
text_invalid_bits, text_invalid_m_bits,
|
||||
text_invalid_width, text_invalid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->text.validIcon = makeDragIconFromData(widget,
|
||||
text_valid_bits, text_valid_m_bits,
|
||||
text_valid_width, text_valid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->text.noneIcon = makeDragIconFromData(widget,
|
||||
text_none_bits, text_none_m_bits,
|
||||
text_none_width, text_none_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->data.invalidIcon = makeDragIconFromData(widget,
|
||||
data_invalid_bits, data_invalid_m_bits,
|
||||
data_invalid_width, data_invalid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->data.validIcon = makeDragIconFromData(widget,
|
||||
data_valid_bits, data_valid_m_bits,
|
||||
data_valid_width, data_valid_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
dc->data.noneIcon = makeDragIconFromData(widget,
|
||||
data_none_bits, data_none_m_bits,
|
||||
data_none_width, data_none_height,
|
||||
DtDND_DRAG_STATE);
|
||||
|
||||
/*
|
||||
* Text & Data Operation Cursors
|
||||
*/
|
||||
|
||||
dc->data.moveIcon = makeDragIconFromData(widget,
|
||||
data_move_bits, data_move_m_bits,
|
||||
data_move_width, data_move_height,
|
||||
DtDND_DRAG_OPERATION);
|
||||
|
||||
dc->data.copyIcon = makeDragIconFromData(widget,
|
||||
data_copy_bits, data_copy_m_bits,
|
||||
data_copy_width, data_copy_height,
|
||||
DtDND_DRAG_OPERATION);
|
||||
|
||||
dc->data.linkIcon = makeDragIconFromData(widget,
|
||||
data_link_bits, data_link_m_bits,
|
||||
data_link_width, data_link_height,
|
||||
DtDND_DRAG_OPERATION);
|
||||
|
||||
dc->text.moveIcon = dc->data.moveIcon;
|
||||
dc->text.copyIcon = dc->data.copyIcon;
|
||||
dc->text.linkIcon = dc->data.linkIcon;
|
||||
|
||||
/*
|
||||
* Text & Data Source Cursors
|
||||
*/
|
||||
|
||||
dc->textSource = makeDragIconFromData(widget,
|
||||
text_source_bits, text_source_m_bits,
|
||||
text_source_width, text_source_height,
|
||||
DtDND_DRAG_SOURCE);
|
||||
|
||||
dc->dataSource = makeDragIconFromData(widget,
|
||||
data_single_bits, data_single_m_bits,
|
||||
data_single_width, data_single_height,
|
||||
DtDND_DRAG_SOURCE);
|
||||
|
||||
dc->multipleSource = makeDragIconFromData(widget,
|
||||
data_multiple_bits, data_multiple_m_bits,
|
||||
data_multiple_width, data_multiple_height,
|
||||
DtDND_DRAG_SOURCE);
|
||||
|
||||
dc->sourceType = DtDND_DRAG_SOURCE_DEFAULT;
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the cached DragCollection and context for it
|
||||
*/
|
||||
static void
|
||||
destroyDragCollection(
|
||||
Widget widget,
|
||||
XtPointer clientData,
|
||||
XtPointer callData)
|
||||
{
|
||||
DragCollection *dc = (DragCollection *)clientData;
|
||||
|
||||
XtFree((char *)dc);
|
||||
|
||||
XDeleteContext(XtDisplayOfObject(widget),
|
||||
RootWindowOfScreen(XtScreenOfObject(widget)),
|
||||
dragCollectionContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the cached DragCollection; will create one if needed
|
||||
*/
|
||||
static DragCollection *
|
||||
getDragCollection(
|
||||
Widget xmScreen)
|
||||
{
|
||||
DragCollection *dc = NULL;
|
||||
Display *dpy = XtDisplayOfObject(xmScreen);
|
||||
Screen *screen = XtScreenOfObject(xmScreen);
|
||||
Window root = RootWindowOfScreen(screen);
|
||||
int status;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (dragCollectionContext == (XContext)NULL) {
|
||||
dragCollectionContext = XUniqueContext();
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
status = XFindContext(dpy, root, dragCollectionContext, (XtPointer)&dc);
|
||||
|
||||
if (status != 0) {
|
||||
dc = makeDragCollection(xmScreen);
|
||||
XSaveContext(dpy, root, dragCollectionContext, (XtPointer)dc);
|
||||
XtAddCallback(xmScreen, XmNdestroyCallback,
|
||||
destroyDragCollection, (XtPointer)dc);
|
||||
}
|
||||
|
||||
return dc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Module-public function to select/activate a source type drag icon
|
||||
*/
|
||||
void
|
||||
_DtDndSelectDragSource(
|
||||
Widget widget,
|
||||
DtDndDragSource sourceType,
|
||||
Widget sourceIcon)
|
||||
{
|
||||
Widget xmScreen = XmGetXmScreen(XtScreenOfObject(widget));
|
||||
DragCollection *dc = getDragCollection(xmScreen);
|
||||
|
||||
selectDragSource(dc, xmScreen, sourceType, sourceIcon);
|
||||
}
|
||||
|
||||
void
|
||||
_DtDndGetIconOffset(
|
||||
Widget dragContext,
|
||||
DtDndDragSource sourceType,
|
||||
int * offsetX,
|
||||
int * offsetY)
|
||||
{
|
||||
Widget sourceIcon;
|
||||
int stateOffsetX, stateOffsetY;
|
||||
|
||||
switch (sourceType) {
|
||||
default:
|
||||
case DtDND_DRAG_SOURCE_DEFAULT:
|
||||
*offsetX = -(motif_x_hot + motif_x_offset_state);
|
||||
*offsetY = -(motif_y_hot + motif_y_offset_state);
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_TEXT:
|
||||
*offsetX = -(text_x_hot + text_x_offset_state);
|
||||
*offsetY = -(text_y_hot + text_y_offset_state);
|
||||
break;
|
||||
case DtDND_DRAG_SOURCE_DATA:
|
||||
case DtDND_DRAG_SOURCE_MULTIPLE:
|
||||
*offsetX = -(data_x_hot + data_x_offset_state);
|
||||
*offsetY = -(data_y_hot + data_y_offset_state);
|
||||
|
||||
XtVaGetValues(dragContext,
|
||||
XmNsourcePixmapIcon, &sourceIcon,
|
||||
NULL);
|
||||
|
||||
if (sourceIcon != NULL) {
|
||||
calcStateIconOffset(sourceIcon,
|
||||
&stateOffsetX, &stateOffsetY);
|
||||
*offsetX = -(data_x_hot + stateOffsetX);
|
||||
*offsetY = -(data_y_hot + stateOffsetY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
401
cde/lib/DtSvc/DtUtil1/DndIconI.h
Normal file
401
cde/lib/DtSvc/DtUtil1/DndIconI.h
Normal file
@@ -0,0 +1,401 @@
|
||||
/* $XConsortium: DndIconI.h /main/3 1995/10/26 15:05:58 rswiston $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndIconI.h
|
||||
*
|
||||
* Description: Private include file containing DND drag icons bitmaps
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* 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 documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#ifndef _Dt_DndIconI_h
|
||||
#define _Dt_DndIconI_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Motif Defaults
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define motif_x_hot 1
|
||||
#define motif_y_hot 1
|
||||
|
||||
#define motif_x_offset_state -8
|
||||
#define motif_y_offset_state -2
|
||||
|
||||
#define motif_x_offset_delta 0
|
||||
#define motif_y_offset_delta 0
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Text Drags: Cursors
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define text_x_hot 1
|
||||
#define text_y_hot 1
|
||||
|
||||
#define text_x_offset_state 1
|
||||
#define text_y_offset_state 1
|
||||
|
||||
#define text_x_offset_delta 7
|
||||
#define text_y_offset_delta 3
|
||||
|
||||
/*
|
||||
* Text: State Valid
|
||||
*/
|
||||
|
||||
#define text_valid_width 16
|
||||
#define text_valid_height 16
|
||||
|
||||
static unsigned char text_valid_bits[] = {
|
||||
#ifdef OLDTEXTVALID
|
||||
0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e, 0x00,
|
||||
0x7e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#else
|
||||
0x00, 0x00, 0xfe, 0x01, 0xfe, 0x00, 0x7e, 0x00, 0x3e, 0x00, 0x1e, 0x00,
|
||||
0x0e, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#endif
|
||||
|
||||
static unsigned char text_valid_m_bits[] = {
|
||||
#ifdef OLDTEXTVALID
|
||||
0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f, 0x00,
|
||||
0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#else
|
||||
0xff, 0x07, 0xff, 0x03, 0xff, 0x01, 0xff, 0x00, 0x7f, 0x00, 0x3f, 0x00,
|
||||
0x1f, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Text: State Invalid
|
||||
*/
|
||||
|
||||
#define text_invalid_width 16
|
||||
#define text_invalid_height 16
|
||||
|
||||
static unsigned char text_invalid_bits[] = {
|
||||
0x00, 0x00, 0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0x0c, 0x1e, 0x06, 0x37,
|
||||
0x86, 0x33, 0xc6, 0x31, 0xe6, 0x30, 0x76, 0x30, 0x3c, 0x18, 0x1c, 0x1c,
|
||||
0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char text_invalid_m_bits[] = {
|
||||
0xe0, 0x03, 0xf8, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0x1e, 0x3f, 0x8f, 0x7f,
|
||||
0xcf, 0x7f, 0xef, 0x7b, 0xff, 0x79, 0xff, 0x78, 0x7e, 0x3c, 0xfe, 0x3f,
|
||||
0xfc, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00};
|
||||
|
||||
/*
|
||||
* Text: None
|
||||
*/
|
||||
|
||||
#define text_none_width 16
|
||||
#define text_none_height 16
|
||||
|
||||
static unsigned char text_none_bits[] = {
|
||||
0x00, 0x00, 0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0x0c, 0x1e, 0x06, 0x37,
|
||||
0x86, 0x33, 0xc6, 0x31, 0xe6, 0x30, 0x76, 0x30, 0x3c, 0x18, 0x1c, 0x1c,
|
||||
0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char text_none_m_bits[] = {
|
||||
0xe0, 0x03, 0xf8, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0x1e, 0x3f, 0x8f, 0x7f,
|
||||
0xcf, 0x7f, 0xef, 0x7b, 0xff, 0x79, 0xff, 0x78, 0x7e, 0x3c, 0xfe, 0x3f,
|
||||
0xfc, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00};
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Text Drags: Operation Cursors
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
/* Use Data Operation Cursors */
|
||||
|
||||
/*
|
||||
* Text: Operation Move
|
||||
*/
|
||||
|
||||
/*
|
||||
* Text: Operation Copy
|
||||
*/
|
||||
|
||||
/*
|
||||
* Text: Operation Link
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Text Drags: Source Cursor
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
#define text_source_width 32
|
||||
#define text_source_height 32
|
||||
|
||||
static unsigned char text_source_bits[] = {
|
||||
#ifdef OLDTEXTSOURCE
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xd8, 0xdb, 0xcd, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbe, 0x7f, 0x1f,
|
||||
0x00, 0x00, 0x00, 0x00, 0xb8, 0xf6, 0xfd, 0x16, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe8, 0x7b, 0x76, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xbb, 0xff, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0xd8, 0xde, 0x7b, 0x1d, 0x00, 0x00, 0x00, 0x00,
|
||||
0x78, 0xd7, 0xb4, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xad, 0xd5, 0x0f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#else
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xcd, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x7f, 0x1f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfd, 0x16, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7b, 0x76, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xbb, 0xff, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0xf0, 0xde, 0x7b, 0x1d, 0x00, 0x00, 0x00, 0x00,
|
||||
0x78, 0x77, 0xb7, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbd, 0xdd, 0x0f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#endif
|
||||
|
||||
static unsigned char text_source_m_bits[] = {
|
||||
#ifdef OLDTEXTSOURCE
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#else
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x3f,
|
||||
0x00, 0xf0, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x3f,
|
||||
0x00, 0xfe, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x3f, 0x80, 0xff, 0xff, 0x3f,
|
||||
0xc0, 0xff, 0xff, 0x3f, 0xe0, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f,
|
||||
0xf8, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Data Drags: Cursors
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#define data_x_hot 3
|
||||
#define data_y_hot 3
|
||||
|
||||
#define data_x_offset_state 11
|
||||
#define data_y_offset_state 11
|
||||
|
||||
#define data_x_offset_delta 7
|
||||
#define data_y_offset_delta 7
|
||||
|
||||
/*
|
||||
* Data: State Valid
|
||||
*/
|
||||
|
||||
#define data_valid_width 16
|
||||
#define data_valid_height 16
|
||||
|
||||
static unsigned char data_valid_bits[] = {
|
||||
0x00, 0x00, 0x06, 0x00, 0x1e, 0x00, 0x7c, 0x00, 0xfc, 0x01, 0xf8, 0x07,
|
||||
0xf8, 0x07, 0xf0, 0x01, 0xf0, 0x03, 0x60, 0x07, 0x60, 0x0e, 0x00, 0x1c,
|
||||
0x00, 0x38, 0x00, 0x70, 0x00, 0x60, 0x00, 0x00};
|
||||
|
||||
static unsigned char data_valid_m_bits[] = {
|
||||
0x07, 0x00, 0x1f, 0x00, 0x7f, 0x00, 0xfe, 0x01, 0xfe, 0x07, 0xfc, 0x0f,
|
||||
0xfc, 0x0f, 0xf8, 0x07, 0xf8, 0x07, 0xf0, 0x0f, 0xf0, 0x1f, 0x60, 0x3e,
|
||||
0x00, 0x7c, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0x60};
|
||||
|
||||
/*
|
||||
* Data: State Invalid
|
||||
*/
|
||||
|
||||
#define data_invalid_width 16
|
||||
#define data_invalid_height 16
|
||||
|
||||
static unsigned char data_invalid_bits[] = {
|
||||
0x00, 0x00, 0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0x0c, 0x1e, 0x06, 0x37,
|
||||
0x86, 0x33, 0xc6, 0x31, 0xe6, 0x30, 0x76, 0x30, 0x3c, 0x18, 0x1c, 0x1c,
|
||||
0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char data_invalid_m_bits[] = {
|
||||
0xe0, 0x03, 0xf8, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0x1e, 0x3f, 0x8f, 0x7f,
|
||||
0xcf, 0x7f, 0xef, 0x7b, 0xff, 0x79, 0xff, 0x78, 0x7e, 0x3c, 0xfe, 0x3f,
|
||||
0xfc, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00};
|
||||
|
||||
/*
|
||||
* Data: State None
|
||||
*/
|
||||
|
||||
#define data_none_width 16
|
||||
#define data_none_height 16
|
||||
|
||||
static unsigned char data_none_bits[] = {
|
||||
0x00, 0x00, 0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0x0c, 0x1e, 0x06, 0x37,
|
||||
0x86, 0x33, 0xc6, 0x31, 0xe6, 0x30, 0x76, 0x30, 0x3c, 0x18, 0x1c, 0x1c,
|
||||
0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char data_none_m_bits[] = {
|
||||
0xe0, 0x03, 0xf8, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0x1e, 0x3f, 0x8f, 0x7f,
|
||||
0xcf, 0x7f, 0xef, 0x7b, 0xff, 0x79, 0xff, 0x78, 0x7e, 0x3c, 0xfe, 0x3f,
|
||||
0xfc, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00};
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Data Drags: Operation Cursors
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Data: Operation Move
|
||||
*/
|
||||
|
||||
#define data_move_width 16
|
||||
#define data_move_height 16
|
||||
|
||||
static unsigned char data_move_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char data_move_m_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/*
|
||||
* Data: Operation Copy
|
||||
*/
|
||||
|
||||
#define data_copy_width 16
|
||||
#define data_copy_height 16
|
||||
|
||||
static unsigned char data_copy_bits[] = {
|
||||
0x00, 0x00, 0xfe, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x1f, 0x02, 0x11,
|
||||
0x02, 0x11, 0x02, 0x11, 0x02, 0x11, 0x02, 0x11, 0xfe, 0x11, 0x20, 0x10,
|
||||
0x20, 0x10, 0xe0, 0x1f, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char data_copy_m_bits[] = {
|
||||
0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f,
|
||||
0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f,
|
||||
0xf0, 0x3f, 0xf0, 0x3f, 0xf0, 0x3f, 0x00, 0x00};
|
||||
|
||||
/*
|
||||
* Data: Operation Link
|
||||
*/
|
||||
|
||||
#define data_link_width 16
|
||||
#define data_link_height 16
|
||||
|
||||
static unsigned char data_link_bits[] = {
|
||||
0x00, 0x00, 0xfe, 0x03, 0x02, 0x02, 0x02, 0x02, 0x32, 0x02, 0x32, 0x3e,
|
||||
0x42, 0x20, 0x82, 0x20, 0x02, 0x21, 0x3e, 0x26, 0x20, 0x26, 0x20, 0x20,
|
||||
0x20, 0x20, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static unsigned char data_link_m_bits[] = {
|
||||
0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x7f, 0xff, 0x7f,
|
||||
0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xf0, 0x7f,
|
||||
0xf0, 0x7f, 0xf0, 0x7f, 0xf0, 0x7f, 0x00, 0x00};
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Data Drags: Source Icons
|
||||
*-------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Data Source: Single
|
||||
*/
|
||||
|
||||
#define data_single_width 32
|
||||
#define data_single_height 32
|
||||
|
||||
static unsigned char data_single_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x10, 0x00, 0xc0, 0x00,
|
||||
0x10, 0x00, 0x40, 0x01, 0x10, 0x00, 0x40, 0x02, 0x10, 0x00, 0x40, 0x04,
|
||||
0x10, 0x00, 0xc0, 0x0f, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x08,
|
||||
0x10, 0x00, 0x00, 0x08, 0xf0, 0xff, 0xff, 0x0f};
|
||||
|
||||
static unsigned char data_single_m_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0xff, 0x00,
|
||||
0xf0, 0xff, 0xff, 0x01, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x07,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x0f};
|
||||
|
||||
/*
|
||||
* Data Source: Multiple
|
||||
*/
|
||||
|
||||
#define data_multiple_width 32
|
||||
#define data_multiple_height 32
|
||||
|
||||
static unsigned char data_multiple_bits[] = {
|
||||
0xfc, 0xff, 0x0f, 0x00, 0x04, 0x00, 0x30, 0x00, 0x04, 0x00, 0xd0, 0x1f,
|
||||
0x04, 0x00, 0x90, 0x10, 0x04, 0x00, 0x10, 0xf1, 0x04, 0x00, 0xf0, 0x93,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00, 0x92,
|
||||
0xfc, 0xff, 0xff, 0x93, 0x20, 0x00, 0x00, 0x90, 0xe0, 0xff, 0xff, 0x9f,
|
||||
0x00, 0x01, 0x00, 0x80, 0x00, 0xff, 0xff, 0xff};
|
||||
|
||||
static unsigned char data_multiple_m_bits[] = {
|
||||
0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0xff, 0x1f,
|
||||
0xfc, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_DndIconI_h */
|
||||
310
cde/lib/DtSvc/DtUtil1/DndP.h
Normal file
310
cde/lib/DtSvc/DtUtil1/DndP.h
Normal file
@@ -0,0 +1,310 @@
|
||||
/* $XConsortium: DndP.h /main/4 1996/06/21 17:28:31 ageorge $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndP.h
|
||||
*
|
||||
* Description: Private include file for DND Convenience API.
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement bertween
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#ifndef _Dt_DndP_h
|
||||
#define _Dt_DndP_h
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Drag and Drop selection targets
|
||||
*/
|
||||
|
||||
extern Atom XA_TARGETS;
|
||||
extern Atom XA_TIMESTAMP;
|
||||
extern Atom XA_MULTIPLE;
|
||||
extern Atom XA_DELETE;
|
||||
extern Atom XA_NULL;
|
||||
extern Atom XA_TEXT;
|
||||
extern Atom XA_HOST_NAME;
|
||||
extern Atom XA_SUN_FILE_HOST_NAME;
|
||||
extern Atom XA_SUN_ENUM_COUNT;
|
||||
extern Atom XA_SUN_DATA_LABEL;
|
||||
extern Atom XA_SUN_SELN_READONLY;
|
||||
extern Atom XA_SUN_ATM_FILE_NAME;
|
||||
extern Atom XA_SUN_ATM_METHODS;
|
||||
|
||||
#define DtGetAtom(display, atomname) \
|
||||
XmInternAtom((display),(atomname),False)
|
||||
|
||||
|
||||
/*
|
||||
* Drag Icon Styles
|
||||
*/
|
||||
typedef enum {
|
||||
DtDND_DRAG_SOURCE_DEFAULT,
|
||||
DtDND_DRAG_SOURCE_TEXT,
|
||||
DtDND_DRAG_SOURCE_DATA,
|
||||
DtDND_DRAG_SOURCE_MULTIPLE
|
||||
} DtDndDragSource;
|
||||
|
||||
/*
|
||||
* Drag-n-Drop Data Transfer Protocol
|
||||
*/
|
||||
typedef struct _DtDndTransfer {
|
||||
Atom * targets;
|
||||
Cardinal numTargets;
|
||||
struct _DtDndMethods * methods;
|
||||
} DtDndTransfer;
|
||||
|
||||
/*
|
||||
* Drag Initiator Structure
|
||||
*/
|
||||
|
||||
typedef struct _DtDragInfo {
|
||||
Widget dragInitiator;
|
||||
Widget dragContext;
|
||||
DtDndProtocol protocol;
|
||||
Cardinal numItems;
|
||||
unsigned char operations;
|
||||
XtCallbackList dragConvertCallback;
|
||||
XtCallbackList dragFinishCallback;
|
||||
XtCallbackList dropOnRootCallback;
|
||||
XtCallbackList dragDropFinishCallback;
|
||||
XtCallbackList dropFinishCallback;
|
||||
XtCallbackList topLevelEnterCallback;
|
||||
XtCallbackList topLevelLeaveCallback;
|
||||
XtCallbackList dropStartCallback;
|
||||
Widget sourceIcon;
|
||||
Boolean bufferIsText;
|
||||
DtDndTransfer * transfer;
|
||||
DtDndContext * dragData;
|
||||
Boolean inRoot;
|
||||
Window backdropWindow;
|
||||
DtDndStatus status;
|
||||
XtPointer clientData;
|
||||
} DtDragInfo;
|
||||
|
||||
/*
|
||||
* Drop Receiver Existing Registration Structure
|
||||
*/
|
||||
|
||||
typedef struct _DtDropSiteInfo {
|
||||
XtCallbackProc dropProc;
|
||||
unsigned char operations;
|
||||
Atom * importTargets;
|
||||
int numImportTargets;
|
||||
} DtDropSiteInfo;
|
||||
|
||||
/*
|
||||
* Drop Receiver Data Transfer Structure
|
||||
*/
|
||||
|
||||
typedef struct _DtTransferInfo {
|
||||
Widget dragContext;
|
||||
DtDndProtocol protocol;
|
||||
unsigned char operation;
|
||||
struct _DtDndMethods * methods;
|
||||
Atom * transferTargets;
|
||||
Cardinal numTransferTargets;
|
||||
Cardinal currentTransfer;
|
||||
Boolean appTransferCalled;
|
||||
XEvent * event;
|
||||
Position x, y;
|
||||
XtPointer clientData;
|
||||
XtCallbackList dropAnimateCallback;
|
||||
} DtTransferInfo;
|
||||
|
||||
/*
|
||||
* Drop Receiver Registration Structure
|
||||
*/
|
||||
|
||||
typedef struct _DtDropInfo {
|
||||
Widget dropReceiver;
|
||||
DtDndProtocol protocols;
|
||||
unsigned char operations;
|
||||
XtCallbackList dropTransferCallback;
|
||||
XtCallbackList dropAnimateCallback;
|
||||
Boolean textIsBuffer;
|
||||
DtDropSiteInfo * dropSiteInfo;
|
||||
DtDndTransfer * transfers;
|
||||
Cardinal numTransfers;
|
||||
DtTransferInfo * transferInfo;
|
||||
DtDndContext * dropData;
|
||||
DtDndStatus status;
|
||||
} DtDropInfo;
|
||||
|
||||
/*
|
||||
* Drag-n-Drop Data Transfer Protocol Function Prototypes
|
||||
*/
|
||||
|
||||
typedef void
|
||||
(*DtDndGetAvailTargetsProc)(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** returnAvailTargetsList,
|
||||
Cardinal * returnNumAvailTargets);
|
||||
|
||||
typedef void
|
||||
(*DtDndGetExportTargetsProc)(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** returnExportTargetsList,
|
||||
Cardinal * returnNumExportTargets);
|
||||
|
||||
typedef void
|
||||
(*DtDndGetImportTargetsProc)(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom ** returnImportTargetsList,
|
||||
Cardinal * returnNumImportTargets);
|
||||
|
||||
typedef void
|
||||
(*DtDndConvertInitProc)(
|
||||
DtDragInfo * dtDragInfo);
|
||||
|
||||
typedef Boolean
|
||||
(*DtDndConvertProc)(
|
||||
Widget dragContext,
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * returnType,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
int * returnFormat,
|
||||
XSelectionRequestEvent *selectionRequestEvent);
|
||||
|
||||
typedef void
|
||||
(*DtDndConvertFinishProc)(
|
||||
DtDragInfo * dtDragInfo);
|
||||
|
||||
typedef void
|
||||
(*DtDndTransferTargetsProc)(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * exportTargets,
|
||||
Cardinal numExportTargets,
|
||||
Atom ** returnTransferTargetsList,
|
||||
Cardinal * returnNumTransferTargets);
|
||||
|
||||
typedef void
|
||||
(*DtDndTransferProc)(
|
||||
Widget dropTransfer,
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * type,
|
||||
XtPointer value,
|
||||
unsigned long * length,
|
||||
int * format);
|
||||
|
||||
typedef void
|
||||
(*DtDndTransferFinishProc)(
|
||||
DtDropInfo * dtDropInfo);
|
||||
|
||||
/*
|
||||
* Drag-n-Drop Data Transfer Methods
|
||||
*/
|
||||
|
||||
typedef struct _DtDndMethods {
|
||||
String name;
|
||||
DtDndProtocol protocol;
|
||||
DtDndDragSource sourceType;
|
||||
DtDndGetAvailTargetsProc getAvailTargets;
|
||||
DtDndGetExportTargetsProc getExportTargets;
|
||||
DtDndGetImportTargetsProc getImportTargets;
|
||||
DtDndConvertInitProc convertInit;
|
||||
DtDndConvertProc convert;
|
||||
DtDndConvertFinishProc convertFinish;
|
||||
DtDndTransferTargetsProc transferTargets;
|
||||
DtDndTransferProc transfer;
|
||||
DtDndTransferFinishProc transferFinish;
|
||||
} DtDndMethods;
|
||||
|
||||
/*
|
||||
* Drag-n-Drop Private Utility Functions
|
||||
*/
|
||||
|
||||
extern DtDndTransfer *
|
||||
_DtDndCreateExportTransfer(
|
||||
DtDragInfo * dtDragInfo);
|
||||
|
||||
extern DtDndTransfer *
|
||||
_DtDndCreateImportTransfers(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Cardinal * numTransfers);
|
||||
|
||||
extern void
|
||||
_DtDndDestroyTransfers(
|
||||
DtDndTransfer * transfers,
|
||||
Cardinal numTransfers);
|
||||
|
||||
extern DtDndTransfer *
|
||||
_DtDndTransferFromTargets(
|
||||
DtDndTransfer * transfers,
|
||||
Cardinal numTransfers,
|
||||
Atom * targets,
|
||||
Cardinal numTargets);
|
||||
|
||||
extern void
|
||||
_DtDndTransferAdd(
|
||||
Widget dropTransfer,
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * transferTargets,
|
||||
Cardinal numTransferTargets);
|
||||
|
||||
extern XtCallbackList
|
||||
_DtDndCopyCallbackList(
|
||||
XtCallbackList callbacks);
|
||||
|
||||
extern void
|
||||
_DtDndCallCallbackList(
|
||||
Widget widget,
|
||||
XtCallbackList callbacks,
|
||||
XtPointer calldata);
|
||||
|
||||
extern void
|
||||
_DtDndSelectDragSource(
|
||||
Widget anyWidget,
|
||||
DtDndDragSource sourceType,
|
||||
Widget sourceIcon);
|
||||
|
||||
extern void
|
||||
_DtDndGetIconOffset(
|
||||
Widget dragContext,
|
||||
DtDndDragSource sourceType,
|
||||
int * offsetXReturn,
|
||||
int * offsetYReturn);
|
||||
|
||||
extern String
|
||||
_DtDndGetHostName(void);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void _DtDndPrintTargets(Display*,Atom*,Cardinal);
|
||||
extern void _DtDndPrintTransfers(Display*,DtDndTransfer*,Cardinal);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_DndP_h */
|
||||
385
cde/lib/DtSvc/DtUtil1/DndText.c
Normal file
385
cde/lib/DtSvc/DtUtil1/DndText.c
Normal file
@@ -0,0 +1,385 @@
|
||||
/* $XConsortium: DndText.c /main/5 1996/08/28 17:46:27 drk $ */
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: DndText.c
|
||||
*
|
||||
* Description: Implementation of the Text Transfer routines
|
||||
* for the DND Convenience API.
|
||||
*
|
||||
*********************************************************************
|
||||
*
|
||||
*+SNOTICE
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement bertween
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Xm/AtomMgr.h>
|
||||
#include <Xm/DragC.h>
|
||||
#include <Xm/DropSMgr.h>
|
||||
#include <Xm/DropTrans.h>
|
||||
#include "Dnd.h"
|
||||
#include "DndP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Text Transfer Function Prototypes
|
||||
*/
|
||||
|
||||
static void dndTextGetTargets(Atom**, Cardinal*);
|
||||
static void dndTextGetAvailTargets(DtDragInfo*, Atom**, Cardinal*);
|
||||
static void dndTextGetExportTargets(DtDragInfo*, Atom**, Cardinal*);
|
||||
static void dndTextGetImportTargets(DtDropInfo*, Atom**, Cardinal*);
|
||||
static void dndTextConvertInit(DtDragInfo*);
|
||||
static Boolean dndTextConvert(Widget, DtDragInfo*, Atom*, Atom*,
|
||||
Atom*, XtPointer*, unsigned long*, int*,
|
||||
XSelectionRequestEvent*);
|
||||
static void dndTextConvertFinish(DtDragInfo*);
|
||||
static void dndTextTransferTargets(DtDropInfo*,
|
||||
Atom*, Cardinal, Atom**, Cardinal*);
|
||||
static void dndTextTransfer(Widget, DtDropInfo*, Atom*, Atom*,
|
||||
Atom*, XtPointer, unsigned long*, int*);
|
||||
static void dndTextTransferFinish(DtDropInfo*);
|
||||
|
||||
/*
|
||||
* Text Transfer Selection Target
|
||||
*/
|
||||
|
||||
static Atom XA_COMPOUND_TEXT;
|
||||
static Boolean dndPreferString;
|
||||
|
||||
/*
|
||||
* Text Transfer ProtocolInfo
|
||||
*/
|
||||
|
||||
static DtDndMethods dndTextTransferProtocol = {
|
||||
"DtDndTextTransfer", /* name */
|
||||
(DtDndProtocol)DtDND_TEXT_TRANSFER, /* protocol */
|
||||
DtDND_DRAG_SOURCE_TEXT, /* sourceType */
|
||||
dndTextGetAvailTargets, /* getAvailTargets */
|
||||
dndTextGetExportTargets, /* getExportTargets */
|
||||
dndTextGetImportTargets, /* getImportTargets */
|
||||
dndTextConvertInit, /* convertInit */
|
||||
dndTextConvert, /* convert */
|
||||
dndTextConvertFinish, /* convertFinish */
|
||||
dndTextTransferTargets, /* transferTargets */
|
||||
dndTextTransfer, /* transfer */
|
||||
dndTextTransferFinish, /* transferFinish */
|
||||
};
|
||||
|
||||
/*
|
||||
* Text transfer protocol initialization
|
||||
*/
|
||||
DtDndMethods *
|
||||
_DtDndTextTransferProtocolInitialize(
|
||||
Display * display)
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if (XA_COMPOUND_TEXT == 0) {
|
||||
XA_COMPOUND_TEXT = DtGetAtom(display, "COMPOUND_TEXT");
|
||||
dndPreferString = (strcmp(setlocale(LC_CTYPE,NULL),"C") == 0);
|
||||
#ifdef DEBUG
|
||||
printf("locale = %s, dndPreferString = %d\n",
|
||||
setlocale(LC_CTYPE,NULL), dndPreferString);
|
||||
#endif
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return &dndTextTransferProtocol;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns generic export/import targets for text transfers
|
||||
*/
|
||||
static void
|
||||
dndTextGetTargets(
|
||||
Atom ** targets,
|
||||
Cardinal * numTargets)
|
||||
{
|
||||
int ii = 0;
|
||||
|
||||
*numTargets = 3;
|
||||
|
||||
*targets = (Atom *)XtMalloc(*numTargets * sizeof(Atom));
|
||||
|
||||
(*targets)[ii++] = XA_COMPOUND_TEXT;
|
||||
(*targets)[ii++] = XA_TEXT;
|
||||
(*targets)[ii++] = XA_STRING;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns available targets for text transfers
|
||||
*/
|
||||
static void
|
||||
dndTextGetAvailTargets(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** availTargets,
|
||||
Cardinal * numAvailTargets)
|
||||
{
|
||||
dndTextGetTargets(availTargets, numAvailTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns export targets for text transfers
|
||||
*/
|
||||
static void
|
||||
dndTextGetExportTargets(
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom ** exportTargets,
|
||||
Cardinal * numExportTargets)
|
||||
{
|
||||
dndTextGetTargets(exportTargets, numExportTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns import targets for text transfers
|
||||
*/
|
||||
static void
|
||||
dndTextGetImportTargets(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom ** importTargets,
|
||||
Cardinal * numImportTargets)
|
||||
{
|
||||
dndTextGetTargets(importTargets, numImportTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize protocol specific part of drag data
|
||||
*/
|
||||
static void
|
||||
dndTextConvertInit(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
|
||||
dragData->data.strings = (XmString *)
|
||||
XtMalloc(dragData->numItems * sizeof(XmString));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the motif strings into selection data
|
||||
*/
|
||||
static Boolean
|
||||
dndTextConvert(
|
||||
Widget dragContext,
|
||||
DtDragInfo * dtDragInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * returnType,
|
||||
XtPointer * returnValue,
|
||||
unsigned long * returnLength,
|
||||
int * returnFormat,
|
||||
XSelectionRequestEvent * selectionRequestEvent)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
Display * dpy = XtDisplayOfObject(dragContext);
|
||||
XmString * stringList;
|
||||
Cardinal numStrings;
|
||||
XTextProperty textProp;
|
||||
XmICCEncodingStyle encStyle;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Select the text encoding style; reject unknown targets
|
||||
*/
|
||||
|
||||
if (*target == XA_COMPOUND_TEXT) {
|
||||
encStyle = XmSTYLE_COMPOUND_TEXT;
|
||||
} else if (*target == XA_STRING) {
|
||||
encStyle = XmSTYLE_STRING;
|
||||
} else if (*target == XA_TEXT) {
|
||||
encStyle = XmSTYLE_TEXT;
|
||||
} else {
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the XmString list into a string list
|
||||
*/
|
||||
|
||||
numStrings = dragData->numItems;
|
||||
stringList = dragData->data.strings;
|
||||
|
||||
status = XmCvtXmStringTableToTextProperty(dpy, stringList, numStrings,
|
||||
encStyle, &textProp);
|
||||
if (status != Success)
|
||||
return False;
|
||||
|
||||
/*
|
||||
* Return the text property
|
||||
*/
|
||||
|
||||
*returnType = textProp.encoding;
|
||||
*returnValue = (XtPointer)textProp.value;
|
||||
*returnLength = textProp.nitems;
|
||||
*returnFormat = textProp.format;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up from the convert init proc
|
||||
*/
|
||||
static void
|
||||
dndTextConvertFinish(
|
||||
DtDragInfo * dtDragInfo)
|
||||
{
|
||||
DtDndContext * dragData = dtDragInfo->dragData;
|
||||
|
||||
if (dragData->data.strings) {
|
||||
XtFree((char *)dragData->data.strings);
|
||||
dragData->data.strings = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the transfer targets selected from the export targets
|
||||
*/
|
||||
static void
|
||||
dndTextTransferTargets(
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * exportTargets,
|
||||
Cardinal numExportTargets,
|
||||
Atom ** transferTargets,
|
||||
Cardinal * numTransferTargets)
|
||||
{
|
||||
Boolean foundCT, foundText, foundString;
|
||||
Atom target;
|
||||
int ii;
|
||||
|
||||
foundCT = foundText = foundString = False;
|
||||
|
||||
for (ii = 0; ii < numExportTargets; ii++) {
|
||||
if (exportTargets[ii] == XA_COMPOUND_TEXT) {
|
||||
foundCT = True;
|
||||
} else if (exportTargets[ii] == XA_TEXT) {
|
||||
foundText = True;
|
||||
} else if (exportTargets[ii] == XA_STRING) {
|
||||
foundString = True;
|
||||
}
|
||||
}
|
||||
|
||||
if (dndPreferString && foundString) {
|
||||
target = XA_STRING;
|
||||
} else if (foundCT) {
|
||||
target = XA_COMPOUND_TEXT;
|
||||
} else if (foundText) {
|
||||
target = XA_TEXT;
|
||||
} else if (foundString) {
|
||||
target = XA_STRING;
|
||||
} else {
|
||||
*numTransferTargets = 0;
|
||||
*transferTargets = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
*numTransferTargets = 1;
|
||||
|
||||
*transferTargets = (Atom *)XtMalloc(*numTransferTargets * sizeof(Atom));
|
||||
|
||||
(*transferTargets)[0] = target;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transfer the selection data into motif strings
|
||||
*/
|
||||
static void
|
||||
dndTextTransfer(
|
||||
Widget dropTransfer,
|
||||
DtDropInfo * dtDropInfo,
|
||||
Atom * selection,
|
||||
Atom * target,
|
||||
Atom * type,
|
||||
XtPointer value,
|
||||
unsigned long * length,
|
||||
int * format)
|
||||
{
|
||||
Display * display = XtDisplayOfObject(dropTransfer);
|
||||
DtDndContext * dropData = dtDropInfo->dropData;
|
||||
XmString * stringList;
|
||||
XTextProperty textProp;
|
||||
char ** text;
|
||||
int ii, status, textCount;
|
||||
|
||||
/*
|
||||
* Ignore transfers we don't understand or if we've already transferred
|
||||
*/
|
||||
|
||||
if (value == NULL || dropData->data.strings ||
|
||||
(*target != XA_COMPOUND_TEXT &&
|
||||
*target != XA_TEXT &&
|
||||
*target != XA_STRING) ) {
|
||||
if (value != NULL)
|
||||
XtFree(value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the text property to a text list
|
||||
*/
|
||||
|
||||
textProp.value = (unsigned char *)value;
|
||||
textProp.encoding = *type;
|
||||
textProp.format = *format;
|
||||
textProp.nitems = *length;
|
||||
|
||||
status = XmbTextPropertyToTextList(display, &textProp,
|
||||
&text, &textCount);
|
||||
|
||||
XtFree((char *)value);
|
||||
|
||||
if (status != Success) {
|
||||
dtDropInfo->status = DtDND_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the text list into a XmString list
|
||||
*/
|
||||
|
||||
stringList = (XmString *)XtMalloc(textCount * sizeof(XmString));
|
||||
|
||||
for (ii = 0; ii < textCount; ii++) {
|
||||
stringList[ii] = XmStringCreateLocalized(text[ii]);
|
||||
}
|
||||
|
||||
XFreeStringList(text);
|
||||
|
||||
dropData->numItems = textCount;
|
||||
dropData->data.strings = stringList;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up from the transfer proc
|
||||
*/
|
||||
static void
|
||||
dndTextTransferFinish(
|
||||
DtDropInfo * dtDropInfo)
|
||||
{
|
||||
DtDndContext * dropData = dtDropInfo->dropData;
|
||||
int ii;
|
||||
|
||||
for (ii = 0; ii < dropData->numItems; ii++) {
|
||||
XmStringFree(dropData->data.strings[ii]);
|
||||
}
|
||||
XtFree((char *)dropData->data.strings);
|
||||
}
|
||||
23
cde/lib/DtSvc/DtUtil1/Dt.c
Normal file
23
cde/lib/DtSvc/DtUtil1/Dt.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/* $XConsortium: Dt.c /main/4 1995/12/04 10:04:04 rswiston $ */
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* File: Dt.c
|
||||
*
|
||||
* Description: Repository for libDtSvc-wide information.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#include <Dt/Dt.h>
|
||||
|
||||
/* CDE Version information */
|
||||
|
||||
externaldef(dtversion) const int DtVersion = DtVERSION_NUMBER;
|
||||
externaldef(dtversionstring) const char* DtVersionString = DtVERSION_STRING;
|
||||
|
||||
|
||||
71
cde/lib/DtSvc/DtUtil1/Dt.h
Normal file
71
cde/lib/DtSvc/DtUtil1/Dt.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* $TOG: Dt.h /main/12 1999/10/18 14:49:57 samborn $ */
|
||||
/*
|
||||
* (c) Copyright 1997, The Open Group
|
||||
*/
|
||||
/*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993-1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
#ifndef _Dt_Dt_h
|
||||
#define _Dt_Dt_h
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
/* CDE Version information */
|
||||
|
||||
#define DtVERSION 2
|
||||
#define DtREVISION 1
|
||||
#define DtUPDATE_LEVEL 30
|
||||
|
||||
#define DtVERSION_NUMBER (DtVERSION * 10000 + \
|
||||
DtREVISION * 100 + \
|
||||
DtUPDATE_LEVEL)
|
||||
|
||||
#define DtVERSION_STRING "CDE Version 2.1.30"
|
||||
|
||||
|
||||
/*
|
||||
* CDE Version information
|
||||
*/
|
||||
|
||||
externalref const int DtVersion;
|
||||
externalref const char *DtVersionString;
|
||||
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern Boolean DtInitialize(
|
||||
Display *display,
|
||||
Widget widget,
|
||||
char *name,
|
||||
char *tool_class);
|
||||
|
||||
extern Boolean DtAppInitialize(
|
||||
XtAppContext app_context,
|
||||
Display *display,
|
||||
Widget widget,
|
||||
char *name,
|
||||
char *tool_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_Dt_h */
|
||||
299
cde/lib/DtSvc/DtUtil1/DtHash.c
Normal file
299
cde/lib/DtSvc/DtUtil1/DtHash.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/* $XConsortium: DtHash.c /main/4 1996/05/09 04:21:56 drk $ */
|
||||
/*
|
||||
|
||||
Name: hash.c
|
||||
|
||||
Synopsis:
|
||||
|
||||
#include "DtHash.h"
|
||||
|
||||
void * _DtUtilMakeHash(int size)
|
||||
|
||||
void * _DtUtilMakeIHash(int size)
|
||||
|
||||
void ** _DtUtilGetHash(void * tbl, unsigned char * key)
|
||||
|
||||
void ** _DtUtilFindHash(void * tbl,unsigned char * key)
|
||||
|
||||
void ** _DtUtilDelHash(void * tbl, unsigned char * key)
|
||||
|
||||
int _DtUtilOperateHash(void * tbl, void (*op_func)(), void * usr_arg)
|
||||
|
||||
void _DtUtilDestroyHash(void * tbl, int (*des_func)(), void * usr_arg)
|
||||
|
||||
|
||||
Description:
|
||||
|
||||
These routines provide a general purpose hash table facility that
|
||||
supports multiple open hash tables. Each entry in the table consists of a
|
||||
key and a data ptr. The key is a null terminated character string, while
|
||||
the data ptr is opaque. Since all the entries are maintained in a doubly
|
||||
linked lists, deletions and operations on entire table execute very quickly.
|
||||
This make these routines suitable for use when the tables may be very ephemeral.
|
||||
|
||||
DtUtilMakeHash returns a pointer to the created table. The size argument
|
||||
indicate the number of buckets the routine is to allocate. This should be ~
|
||||
the max number of items expected in the table for maximum performance....
|
||||
but /2 or /3 should still be ok. Note that for maximum efficiency the hash
|
||||
table size should be a prime number (a side effect of the hash alorithm).
|
||||
|
||||
DtUtilMakeIHash performs the same function as DtUtilMakeHash, except that the hash
|
||||
routines will use the key arguments as arbitrary integers rather than strings.
|
||||
|
||||
DtUtilGetHash searches the specified hash table tbl for an entry with the
|
||||
specified key. If the entry does not exist, it is created with a NULL data
|
||||
ptr. The routine returns a ptr to the area where the data ptr is (can be)
|
||||
stored.
|
||||
|
||||
DtUtilFindHash searchs the table for an entry with the specified key. If the
|
||||
entry is found, the address of the data pointer associated with the key is
|
||||
returned. If no such entry exists, the routine returns NULL.
|
||||
|
||||
DtUtilDelHash deletes the specified table entry and returns the associated data
|
||||
ptr. If the entry did not exist ( or the data ptr was NULL), the routine
|
||||
returns NULL.
|
||||
|
||||
DtUtilOperateHash calls the routine pointed to by op_func once for each entry
|
||||
in tbl, with three arguments: the data ptr, the usr_arg ptr and a ptr to the
|
||||
key for that entry (which should NOT be altered). This is useful for
|
||||
transversing a hash table quickly and operating on the entries. Note that
|
||||
the order of the traversal of the hash table is the reverse order of
|
||||
insertion.
|
||||
|
||||
DtUtilDestroyHash destroys the specified hash table after operating on it
|
||||
with the specified des_func function as described for DtUtilOperateHash. All storage
|
||||
allocated by the hash routines is reclaimed.
|
||||
|
||||
Author: Bart Smaalders 1/89
|
||||
|
||||
|
||||
*/
|
||||
#include <stdio.h> /* grab NULL define */
|
||||
#include "DtHash.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int hash_string(const unsigned char * s, int modulo);
|
||||
|
||||
typedef struct hash_entry {
|
||||
struct hash_entry
|
||||
* next_entry,
|
||||
* right_entry,
|
||||
* left_entry;
|
||||
unsigned char * key;
|
||||
void * data;
|
||||
} hash_entry;
|
||||
|
||||
typedef struct hash {
|
||||
int size;
|
||||
hash_entry ** table;
|
||||
hash_entry * start;
|
||||
enum hash_type { String_Key = 0 , Integer_Key = 1} hash_type;
|
||||
} hash;
|
||||
|
||||
|
||||
DtHashTbl _DtUtilMakeHash(int size)
|
||||
{
|
||||
hash * ptr;
|
||||
|
||||
ptr = (hash *) malloc(sizeof(*ptr));
|
||||
ptr->size = size;
|
||||
ptr->table = (hash_entry **) malloc( (unsigned) (sizeof(hash_entry *) * size) );
|
||||
(void)memset((char *) ptr->table, (char) 0, sizeof(hash_entry *)*size);
|
||||
ptr->start = NULL;
|
||||
ptr->hash_type = String_Key;
|
||||
return((DtHashTbl)ptr);
|
||||
}
|
||||
|
||||
DtHashTbl _DtUtilMakeIHash(int size)
|
||||
{
|
||||
hash * ptr;
|
||||
|
||||
ptr = (hash *) malloc(sizeof(*ptr));
|
||||
ptr->size = size;
|
||||
ptr->table = (hash_entry **) malloc( (unsigned) (sizeof(hash_entry *) * size) );
|
||||
(void)memset((char *) ptr->table, (char) 0, sizeof(hash_entry *)*size);
|
||||
ptr->start = NULL;
|
||||
ptr->hash_type = Integer_Key;
|
||||
return((DtHashTbl) ptr);
|
||||
}
|
||||
|
||||
|
||||
void ** _DtUtilGetHash(DtHashTbl t, const unsigned char * key)
|
||||
{
|
||||
hash * tbl = (hash *) t;
|
||||
register int bucket;
|
||||
register hash_entry * tmp;
|
||||
hash_entry * new;
|
||||
|
||||
if(tbl->hash_type == String_Key)
|
||||
tmp = tbl->table[bucket = hash_string(key, tbl->size)];
|
||||
else
|
||||
tmp = tbl->table[bucket = abs((int)key) % tbl->size];
|
||||
|
||||
if(tbl->hash_type == String_Key)
|
||||
while(tmp!=NULL)
|
||||
{
|
||||
if(strcmp((char *)tmp->key, (char*)key)==0)
|
||||
return(&tmp->data);
|
||||
tmp = tmp->next_entry;
|
||||
}
|
||||
else
|
||||
while(tmp!=NULL)
|
||||
{
|
||||
if(tmp->key == key)
|
||||
return(&tmp->data);
|
||||
tmp = tmp->next_entry;
|
||||
}
|
||||
|
||||
/*
|
||||
not found....
|
||||
insert new entry into bucket...
|
||||
*/
|
||||
|
||||
new = (hash_entry *) malloc(sizeof(*new));
|
||||
new->key = (unsigned char *)((tbl->hash_type == String_Key)?(unsigned char *)strdup((char*)key):key);
|
||||
/*
|
||||
hook into chain from tbl...
|
||||
*/
|
||||
new->right_entry = NULL;
|
||||
new->left_entry = tbl->start;
|
||||
tbl->start = new;
|
||||
/*
|
||||
hook into bucket chain
|
||||
*/
|
||||
new->next_entry = tbl->table[bucket];
|
||||
tbl->table[bucket] = new;
|
||||
new->data = NULL; /* so we know that it is new */
|
||||
return((void*)& new->data);
|
||||
}
|
||||
|
||||
void ** _DtUtilFindHash(DtHashTbl t, const unsigned char * key)
|
||||
{
|
||||
register hash * tbl = (hash *) t;
|
||||
register hash_entry * tmp;
|
||||
|
||||
if(tbl->hash_type == String_Key)
|
||||
{
|
||||
tmp = tbl->table[hash_string(key, tbl->size)];
|
||||
for(;tmp!=NULL; tmp = tmp->next_entry)
|
||||
if(!strcmp((char*)tmp->key, (char*)key))
|
||||
return((void *)&tmp->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = tbl->table[abs((int)key) % tbl->size];
|
||||
for(;tmp!=NULL; tmp = tmp->next_entry)
|
||||
if(tmp->key == key)
|
||||
return((void *)&tmp->data);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void * _DtUtilDelHash(DtHashTbl t, const unsigned char * key)
|
||||
{
|
||||
register hash * tbl = (hash *) t;
|
||||
|
||||
register int bucket;
|
||||
register hash_entry * tmp, * prev = NULL;
|
||||
|
||||
if(tbl->hash_type == String_Key)
|
||||
bucket = hash_string(key, tbl->size);
|
||||
else
|
||||
bucket = abs((int)key) % tbl->size;
|
||||
|
||||
if((tmp = tbl->table[bucket])==NULL)
|
||||
return(NULL);
|
||||
|
||||
else
|
||||
{
|
||||
if(tbl->hash_type == String_Key)
|
||||
while(tmp!=NULL)
|
||||
{
|
||||
if(!strcmp((char*)tmp->key, (char*)key))
|
||||
break; /* found item to delete ! */
|
||||
prev = tmp;
|
||||
tmp = tmp->next_entry;
|
||||
}
|
||||
else
|
||||
while(tmp!=NULL)
|
||||
{
|
||||
if(tmp->key == key)
|
||||
break;
|
||||
prev = tmp;
|
||||
tmp = tmp->next_entry;
|
||||
}
|
||||
if(tmp == NULL)
|
||||
return(NULL); /* not found */
|
||||
}
|
||||
/* tmp now points to entry marked for deletion, prev to
|
||||
item preceeding in bucket chain or NULL if tmp is first.
|
||||
|
||||
remove from bucket chain first....
|
||||
|
||||
*/
|
||||
if(tbl->hash_type == String_Key)
|
||||
free(tmp->key);
|
||||
if(prev!=NULL)
|
||||
prev->next_entry = tmp->next_entry;
|
||||
else
|
||||
tbl->table[bucket] = tmp->next_entry;
|
||||
/*
|
||||
now remove from tbl chain....
|
||||
*/
|
||||
if(tmp->right_entry !=NULL) /* not first in chain.... */
|
||||
tmp->right_entry->left_entry = (tmp->left_entry ?
|
||||
tmp->left_entry->right_entry: NULL);
|
||||
else
|
||||
tbl->start = (tmp->left_entry ?tmp->left_entry->right_entry: NULL);
|
||||
return(tmp->data);
|
||||
}
|
||||
|
||||
int _DtUtilOperateHash(DtHashTbl t, void (*ptr)(), void * usr_arg)
|
||||
{
|
||||
hash * tbl = (hash *) t;
|
||||
register hash_entry * tmp = tbl->start;
|
||||
int c = 0;
|
||||
|
||||
while(tmp)
|
||||
{
|
||||
(*ptr)(tmp->data,usr_arg, tmp->key);
|
||||
tmp = tmp->left_entry;
|
||||
c++;
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
void _DtUtilDestroyHash(DtHashTbl t, int (*ptr)(), void * usr_arg)
|
||||
{
|
||||
hash * tbl = (hash *) t;
|
||||
register hash_entry * tmp = tbl->start, * prev;
|
||||
|
||||
while(tmp)
|
||||
{
|
||||
if(ptr)
|
||||
(*ptr)(tmp->data,usr_arg, tmp->key);
|
||||
|
||||
if(tbl->hash_type == String_Key)
|
||||
free(tmp->key);
|
||||
prev = tmp;
|
||||
tmp = tmp->left_entry;
|
||||
free((char *)prev);
|
||||
}
|
||||
free((char *)tbl->table);
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
static int hash_string(register const unsigned char * s, int modulo)
|
||||
{
|
||||
register unsigned result = 0;
|
||||
register int i=1;
|
||||
|
||||
while(*s!=0)
|
||||
result += (*s++ << i++);
|
||||
|
||||
return(result % modulo);
|
||||
}
|
||||
|
||||
27
cde/lib/DtSvc/DtUtil1/DtHash.h
Normal file
27
cde/lib/DtSvc/DtUtil1/DtHash.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* $XConsortium: DtHash.h /main/5 1996/08/29 15:42:13 cde-dec $ */
|
||||
#ifndef _DtHash_h
|
||||
#define _DtHash_h
|
||||
|
||||
typedef void * DtHashTbl;
|
||||
|
||||
DtHashTbl _DtUtilMakeHash(int size);
|
||||
DtHashTbl _DtUtilMakeIHash(int size);
|
||||
void ** _DtUtilGetHash(DtHashTbl tbl, const unsigned char * key);
|
||||
void ** _DtUtilFindHash(DtHashTbl tbl,const unsigned char * key);
|
||||
void * _DtUtilDelHash(DtHashTbl tbl, const unsigned char * key);
|
||||
int _DtUtilOperateHash(DtHashTbl tbl, void (*op_func)(), void * usr_arg);
|
||||
void _DtUtilDestroyHash(DtHashTbl tbl, int (*des_func)(), void * usr_arg);
|
||||
|
||||
typedef void (*DtHashOperateFunc)();
|
||||
typedef int (*DtHashDestroyFunc)();
|
||||
|
||||
#endif /* _DtHash_h */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
54
cde/lib/DtSvc/DtUtil1/DtShmDb.h
Normal file
54
cde/lib/DtSvc/DtUtil1/DtShmDb.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* $XConsortium: DtShmDb.h /main/4 1996/05/09 04:22:30 drk $ */
|
||||
#ifndef DtShmDb_h
|
||||
#define DtShmDb_h
|
||||
|
||||
/*
|
||||
this include file provides prototypes for the various
|
||||
shared memory database routines
|
||||
*/
|
||||
|
||||
typedef void * DtShmProtoStrtab;
|
||||
typedef void * DtShmProtoInttab;
|
||||
typedef void * DtShmProtoIntList;
|
||||
|
||||
typedef const void * DtShmStrtab;
|
||||
typedef const void * DtShmInttab;
|
||||
typedef const int * DtShmIntList;
|
||||
typedef int DtShmBoson;
|
||||
|
||||
/*
|
||||
routines used while building shared memory databases
|
||||
*/
|
||||
|
||||
DtShmProtoStrtab _DtShmProtoInitStrtab (int estimated_entries);
|
||||
DtShmBoson _DtShmProtoAddStrtab (DtShmProtoStrtab prototab, const char * string, int * isnew);
|
||||
const char * _DtShmProtoLookUpStrtab (DtShmProtoStrtab prototab, DtShmBoson boson);
|
||||
int _DtShmProtoSizeStrtab (DtShmProtoStrtab prototab);
|
||||
DtShmStrtab _DtShmProtoCopyStrtab (DtShmProtoStrtab prototab, void * dataspace);
|
||||
int _DtShmProtoDestroyStrtab (DtShmProtoStrtab prototab);
|
||||
|
||||
DtShmProtoInttab _DtShmProtoInitInttab (int estimated_entries);
|
||||
int _DtShmProtoAddInttab (DtShmProtoInttab prototab, unsigned int keyin, int datain);
|
||||
int * _DtShmProtoLookUpInttab (DtShmProtoInttab prototab, unsigned int keyin);
|
||||
int _DtShmProtoSizeInttab (DtShmProtoInttab prototab);
|
||||
DtShmInttab _DtShmProtoCopyInttab (DtShmProtoInttab prototab, void * dataspace);
|
||||
int _DtShmProtoDestroyInttab (DtShmProtoInttab prototab);
|
||||
|
||||
|
||||
DtShmProtoIntList _DtShmProtoInitIntLst (int estimated_entries);
|
||||
int * _DtShmProtoAddIntLst (DtShmProtoIntList protolist, int size, int * index_value);
|
||||
int _DtShmProtoSizeIntLst (DtShmProtoIntList protolist);
|
||||
DtShmIntList _DtShmProtoCopyIntLst (DtShmProtoIntList protolist, void * dataspace);
|
||||
int _DtShmProtoDestroyIntLst (DtShmProtoIntList protolist);
|
||||
|
||||
|
||||
/*
|
||||
run-time routines once shared memory area is built
|
||||
*/
|
||||
|
||||
DtShmBoson _DtShmStringToBoson (DtShmStrtab tab, const char * string);
|
||||
const char * _DtShmBosonToString (DtShmStrtab tab, DtShmBoson boson);
|
||||
const int * _DtShmFindIntTabEntry (DtShmInttab tab, unsigned int key);
|
||||
|
||||
#endif /* DtShmDb_h */
|
||||
|
||||
2235
cde/lib/DtSvc/DtUtil1/Dts.c
Normal file
2235
cde/lib/DtSvc/DtUtil1/Dts.c
Normal file
File diff suppressed because it is too large
Load Diff
159
cde/lib/DtSvc/DtUtil1/Dts.h
Normal file
159
cde/lib/DtSvc/DtUtil1/Dts.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/* $XConsortium: Dts.h /main/5 1996/03/05 13:30:59 drk $ */
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _Dt_Dts_h
|
||||
#define _Dt_Dts_h
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
#define DtDTS_DC_NAME "DATA_CRITERIA"
|
||||
#define DtDTS_NAME_PATTERN "NAME_PATTERN"
|
||||
#define DtDTS_PATH_PATTERN "PATH_PATTERN"
|
||||
#define DtDTS_CONTENT "CONTENT"
|
||||
#define DtDTS_MODE "MODE"
|
||||
#define DtDTS_LINK_PATH "LINK_PATH"
|
||||
#define DtDTS_LINK_NAME "LINK_NAME"
|
||||
#define DtDTS_DATA_ATTRIBUTES_NAME "DATA_ATTRIBUTES_NAME"
|
||||
|
||||
#define DtDTS_DT_RECURSIVE_LINK "RECURSIVE_LINK"
|
||||
#define DtDTS_DT_BROKEN_LINK "BROKEN_LINK"
|
||||
#define DtDTS_DT_UNKNOWN "UNKNOWN"
|
||||
|
||||
#define DtDTS_DA_IS_SYNTHETIC "IS_SYNTHETIC"
|
||||
#define DtDTS_DA_LABEL "LABEL"
|
||||
#define DtDTS_DA_NAME "DATA_ATTRIBUTES"
|
||||
#define DtDTS_DA_DESCRIPTION "DESCRIPTION"
|
||||
#define DtDTS_DA_DATA_HOST "DATA_HOST"
|
||||
#define DtDTS_DA_ICON "ICON"
|
||||
#define DtDTS_DA_INSTANCE_ICON "INSTANCE_ICON"
|
||||
#define DtDTS_DA_PROPERTIES "PROPERTIES"
|
||||
#define DtDTS_DA_ACTION_LIST "ACTIONS"
|
||||
#define DtDTS_DA_NAME_TEMPLATE "NAME_TEMPLATE"
|
||||
#define DtDTS_DA_MODE_TEMPLATE "MODE_TEMPLATE"
|
||||
#define DtDTS_DA_MOVE_TO_ACTION "MOVE_TO_ACTION"
|
||||
#define DtDTS_DA_COPY_TO_ACTION "COPY_TO_ACTION"
|
||||
#define DtDTS_DA_LINK_TO_ACTION "LINK_TO_ACTION"
|
||||
#define DtDTS_DA_IS_TEXT "IS_TEXT"
|
||||
#define DtDTS_DA_MEDIA "MEDIA"
|
||||
#define DtDTS_DA_MIME_TYPE "MIME_TYPE"
|
||||
#define DtDTS_DA_MIME_TO_MEDIA_FILTER "MIME_TO_MEDIA_FILTER"
|
||||
#define DtDTS_DA_MEDIA_TO_MIME_FILTER "MEDIA_TO_MIME_FILTER"
|
||||
#define DtDTS_DA_X400_TYPE "X400_TYPE"
|
||||
#define DtDTS_DA_X400_TO_MEDIA_FILTER "X400_TO_MEDIA_FILTER"
|
||||
#define DtDTS_DA_MEDIA_TO_X400_FILTER "MEDIA_TO_X400_FILTER"
|
||||
#define DtDTS_DA_IS_ACTION "IS_ACTION"
|
||||
#define DtDTS_DA_IS_EXECUTABLE "IS_EXECUTABLE"
|
||||
|
||||
#define DtDTS_DT_DIR ".DtDirDataType"
|
||||
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
typedef struct _DtDtsAttribute
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
} DtDtsAttribute;
|
||||
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern void DtDtsLoadDataTypes(void);
|
||||
extern void DtDtsRelease(void);
|
||||
|
||||
extern char *DtDtsDataToDataType(
|
||||
const char *filepath,
|
||||
const void *buffer,
|
||||
const int size,
|
||||
const struct stat *stat_buff,
|
||||
const char *link_name,
|
||||
const struct stat *link_stat_buff,
|
||||
const char *opt_name);
|
||||
|
||||
extern char *DtDtsFileToDataType(
|
||||
const char *filepath);
|
||||
|
||||
extern char *DtDtsFileToAttributeValue(
|
||||
const char *filepath,
|
||||
const char *attr);
|
||||
|
||||
extern DtDtsAttribute **DtDtsFileToAttributeList(
|
||||
const char *filepath);
|
||||
|
||||
extern char *DtDtsBufferToDataType(
|
||||
const void *buffer,
|
||||
const int size,
|
||||
const char *opt_name);
|
||||
|
||||
extern char *DtDtsBufferToAttributeValue(
|
||||
const void *buffer,
|
||||
const int size,
|
||||
const char *attr,
|
||||
const char *opt_name);
|
||||
|
||||
extern DtDtsAttribute **DtDtsBufferToAttributeList(
|
||||
const void *buffer,
|
||||
const int size,
|
||||
const char *opt_name);
|
||||
|
||||
extern char *DtDtsDataTypeToAttributeValue(
|
||||
const char *datatype,
|
||||
const char *attr,
|
||||
const char *opt_name);
|
||||
|
||||
extern DtDtsAttribute **DtDtsDataTypeToAttributeList(
|
||||
const char *datatype,
|
||||
const char *opt_name);
|
||||
|
||||
extern void DtDtsFreeDataTypeNames(
|
||||
char **namelist);
|
||||
|
||||
extern void DtDtsFreeAttributeList(
|
||||
DtDtsAttribute **attr_list);
|
||||
|
||||
extern void DtDtsFreeAttributeValue(
|
||||
char *attr_value);
|
||||
|
||||
extern void DtDtsFreeDataType(
|
||||
char *datatype);
|
||||
|
||||
extern char **DtDtsDataTypeNames(void);
|
||||
|
||||
extern char **DtDtsFindAttribute(
|
||||
const char *name,
|
||||
const char *value);
|
||||
|
||||
extern char *DtDtsSetDataType(
|
||||
const char *filepath,
|
||||
const char *datatype,
|
||||
const int override);
|
||||
|
||||
extern int DtDtsDataTypeIsAction(
|
||||
const char *datatype);
|
||||
|
||||
extern Boolean DtDtsIsTrue(
|
||||
const char *str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_Dts_h */
|
||||
539
cde/lib/DtSvc/DtUtil1/DtsDb.c
Normal file
539
cde/lib/DtSvc/DtUtil1/DtsDb.c
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $TOG: DtsDb.c /main/10 1998/10/23 13:48:04 mgreess $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement bertween
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef SUN_DB
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <Dt/DbReader.h>
|
||||
#include "Dt/DtsDb.h"
|
||||
#include <Dt/UserMsg.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
extern char *strdup(const char *);
|
||||
|
||||
#define PADMEM 10
|
||||
|
||||
typedef int (*genfunc)(const void *, const void *);
|
||||
|
||||
static DtDtsDbDatabase **db_list;
|
||||
static int num_db = 0;
|
||||
|
||||
_DtDtsDbPrintFields(DtDtsDbRecord *rec_ptr, FILE *fd)
|
||||
{
|
||||
int fld;
|
||||
DtDtsDbField *fld_ptr;
|
||||
|
||||
for(fld = 0; fld < rec_ptr->fieldCount; fld++)
|
||||
{
|
||||
fld_ptr = rec_ptr->fieldList[fld];
|
||||
fprintf(fd, "\t\t[%d]\t%s\t%s\n", fld,
|
||||
XrmQuarkToString(fld_ptr->fieldName),
|
||||
fld_ptr->fieldValue?
|
||||
fld_ptr->fieldValue:"(NULL)");
|
||||
}
|
||||
}
|
||||
|
||||
_DtDtsDbPrintRecords(DtDtsDbDatabase *db_ptr, FILE *fd)
|
||||
{
|
||||
int rec;
|
||||
DtDtsDbRecord *rec_ptr;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
fprintf(fd, "%d Records\n", db_ptr->recordCount);
|
||||
for(rec = 0; rec < db_ptr->recordCount; rec++)
|
||||
{
|
||||
rec_ptr = db_ptr->recordList[rec];
|
||||
fprintf(fd, "\tRec[%d] name = %s\n\t%d Fields\n", rec,
|
||||
XrmQuarkToString(rec_ptr->recordName),
|
||||
rec_ptr->fieldCount);
|
||||
_DtDtsDbPrintFields(rec_ptr, fd);
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsDbPrint(FILE *org_fd)
|
||||
{
|
||||
int db;
|
||||
int rec;
|
||||
DtDtsDbDatabase *db_ptr;
|
||||
DtDtsDbRecord *rec_ptr;
|
||||
FILE *fd = org_fd;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
for(db = 0; db < num_db; db++)
|
||||
{
|
||||
if(!db_list[db])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
db_ptr = db_list[db];
|
||||
if(fd == 0)
|
||||
{
|
||||
chdir("/tmp");
|
||||
if((fd = fopen(db_ptr->databaseName, "w")) == NULL)
|
||||
{
|
||||
_DtSimpleError(
|
||||
DtProgName, DtError, NULL,
|
||||
db_ptr->databaseName, NULL);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fprintf(fd, "DB[%d] ", db);
|
||||
fprintf(fd, "name = %s\n", db_ptr->databaseName);
|
||||
_DtDtsDbPrintRecords(db_ptr, fd);
|
||||
if(org_fd == 0)
|
||||
{
|
||||
fclose(fd);
|
||||
fd = 0;
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbCompareRecordNames(DtDtsDbRecord **a, DtDtsDbRecord **b)
|
||||
{
|
||||
return ((*a)->recordName - (*b)->recordName);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbCompareFieldNames(DtDtsDbField **a, DtDtsDbField **b)
|
||||
{
|
||||
return ((*a)->fieldName - (*b)->fieldName);
|
||||
}
|
||||
|
||||
#include <Dt/Dts.h>
|
||||
|
||||
DtDtsDbDatabase **
|
||||
_DtDtsDbInit(void)
|
||||
{
|
||||
DtDtsDbDatabase **db;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
num_db = 0;
|
||||
db = db_list = (DtDtsDbDatabase **)calloc(num_db+3, sizeof(DtDtsDbDatabase *));
|
||||
db_list[0] = (DtDtsDbDatabase *)calloc(1, sizeof(DtDtsDbDatabase));
|
||||
db_list[0]->databaseName = (char *)strdup(DtDTS_DC_NAME);
|
||||
db_list[0]->ActionSequenceNumber = 0;
|
||||
num_db++;
|
||||
|
||||
db_list[1] = (DtDtsDbDatabase *)calloc(1, sizeof(DtDtsDbDatabase));
|
||||
db_list[1]->databaseName = (char *)strdup(DtDTS_DA_NAME);
|
||||
db_list[1]->ActionSequenceNumber = 0;
|
||||
num_db++;
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(db);
|
||||
}
|
||||
|
||||
char **
|
||||
_DtsDbListDb()
|
||||
{
|
||||
int i;
|
||||
char **list = 0;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
for ( i = 0; db_list[i]; i++ );
|
||||
|
||||
if(i > 0)
|
||||
{
|
||||
list = (char **)calloc(i+1, sizeof(char *));
|
||||
for ( i = 0; db_list[i]; i++ )
|
||||
{
|
||||
list[i] = (char *)strdup(db_list[i]->databaseName);
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return(list);
|
||||
}
|
||||
|
||||
DtDtsDbDatabase *
|
||||
_DtDtsDbAddDatabase( char *db_name )
|
||||
{
|
||||
int i = 0;
|
||||
DtDtsDbDatabase **new_db_list;
|
||||
DtDtsDbDatabase *ret_db;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if ( !db_list )
|
||||
{
|
||||
_DtDtsDbInit();
|
||||
}
|
||||
for ( i = 0; db_list[i]; i++ )
|
||||
{
|
||||
if ( !strcmp(db_list[i]->databaseName,db_name) )
|
||||
{
|
||||
/*
|
||||
* A database with the given name already exists.
|
||||
* return a pointer to the existing database.
|
||||
*/
|
||||
ret_db = db_list[i];
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return ret_db;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We now have a count of the existing databases.
|
||||
* allocate enough space for the existing databases + the new one
|
||||
* + a NULL pointer to terminate the vector.
|
||||
*/
|
||||
|
||||
new_db_list = (DtDtsDbDatabase **)calloc(i+2,sizeof(DtDtsDbDatabase *));
|
||||
|
||||
memmove(new_db_list,db_list,sizeof(DtDtsDbDatabase *) * i );
|
||||
new_db_list[i] = (DtDtsDbDatabase *)calloc(1, sizeof(DtDtsDbDatabase));
|
||||
new_db_list[i]->databaseName = strdup(db_name);
|
||||
new_db_list[i]->ActionSequenceNumber = 0;
|
||||
free(db_list);
|
||||
db_list = new_db_list;
|
||||
num_db++;
|
||||
|
||||
ret_db = db_list[i];
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return ret_db;
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbDeleteDb(DtDtsDbDatabase *db)
|
||||
{
|
||||
int i;
|
||||
int flag = 0;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
_DtDtsDbDeleteRecords(db);
|
||||
if(db->databaseName) free(db->databaseName);
|
||||
if(db) free(db);
|
||||
|
||||
for(i = 0; db_list[i]; i++)
|
||||
{
|
||||
if(db_list[i] == db)
|
||||
{
|
||||
flag = 1;
|
||||
db_list[i] = 0;
|
||||
}
|
||||
if(flag)
|
||||
{
|
||||
db_list[i] = db_list[i+1];
|
||||
}
|
||||
}
|
||||
if(db_list[0] == 0)
|
||||
{
|
||||
if(db_list)free(db_list);
|
||||
db_list = 0;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
DtDtsDbDatabase *
|
||||
_DtDtsDbGet(char *name)
|
||||
{
|
||||
DtDtsDbDatabase *ret_db;
|
||||
int i;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!db_list)
|
||||
{
|
||||
_DtDtsDbInit();
|
||||
}
|
||||
for(i = 0; db_list && db_list[i] && db_list[i]->databaseName; i++)
|
||||
{
|
||||
if(strcmp(db_list[i]->databaseName, name) == 0)
|
||||
{
|
||||
ret_db = db_list[i];
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(ret_db);
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsDbFieldSort(DtDtsDbRecord *rec, _DtDtsDbFieldCompare compare)
|
||||
{
|
||||
if(compare == NULL)
|
||||
{
|
||||
compare = _DtDtsDbCompareFieldNames;
|
||||
}
|
||||
qsort(rec->fieldList,
|
||||
rec->fieldCount,
|
||||
sizeof(DtDtsDbField *),
|
||||
(genfunc)compare);
|
||||
rec->compare = compare;
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsDbRecordSort(DtDtsDbDatabase *db, _DtDtsDbRecordCompare compare)
|
||||
{
|
||||
if(compare == NULL)
|
||||
{
|
||||
compare = _DtDtsDbCompareRecordNames;
|
||||
}
|
||||
qsort(db->recordList,
|
||||
db->recordCount,
|
||||
sizeof(DtDtsDbRecord *),
|
||||
(genfunc)compare);
|
||||
db->compare = compare;
|
||||
}
|
||||
|
||||
DtDtsDbField *
|
||||
_DtDtsDbGetField(DtDtsDbRecord *rec, char *name)
|
||||
{
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* Field names have been quarked so quark 'name' and
|
||||
* do a linear search for the quark'ed field name.
|
||||
*/
|
||||
XrmQuark tmp = XrmStringToQuark (name);
|
||||
|
||||
for (i = 0; i < rec->fieldCount; i++)
|
||||
{
|
||||
if (rec->fieldList[i]->fieldName == tmp)
|
||||
{
|
||||
return (rec->fieldList[i]);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
char *
|
||||
_DtDtsDbGetFieldByName(DtDtsDbRecord *rec, char *name)
|
||||
{
|
||||
DtDtsDbField *result;
|
||||
|
||||
result = _DtDtsDbGetField(rec, name);
|
||||
if(result)
|
||||
{
|
||||
return(result->fieldValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DtDtsDbRecord *
|
||||
_DtDtsDbGetRecordByName(DtDtsDbDatabase *db, char *name)
|
||||
{
|
||||
DtDtsDbRecord srch;
|
||||
DtDtsDbRecord **result;
|
||||
DtDtsDbRecord *s = &srch;
|
||||
register int i;
|
||||
XrmQuark name_quark = XrmStringToQuark(name);
|
||||
|
||||
/*
|
||||
* If the fields are not sorted in alphanumeric order
|
||||
* by name a binary search will fail. So do the slow but
|
||||
* sure linear search.
|
||||
*/
|
||||
if(db->compare != _DtDtsDbCompareRecordNames)
|
||||
{
|
||||
|
||||
for (i = 0; i < db->recordCount; i++)
|
||||
{
|
||||
if (db->recordList[i]->recordName == name_quark)
|
||||
{
|
||||
return (db->recordList[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
srch.recordName = name_quark;
|
||||
|
||||
if(db->recordCount == 0 || db->recordList == NULL)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (DtDtsDbRecord **)bsearch(&s,
|
||||
db->recordList,
|
||||
db->recordCount,
|
||||
sizeof(DtDtsDbRecord *),
|
||||
(genfunc)_DtDtsDbCompareRecordNames);
|
||||
}
|
||||
|
||||
if(result)
|
||||
{
|
||||
return(*result);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DtDtsDbRecord *
|
||||
_DtDtsDbAddRecord(DtDtsDbDatabase *db)
|
||||
{
|
||||
DtDtsDbRecord **newlist;
|
||||
int rec = db->recordCount;
|
||||
|
||||
db->compare = (_DtDtsDbRecordCompare)NULL;
|
||||
if(rec%PADMEM == 0)
|
||||
{
|
||||
newlist = (DtDtsDbRecord **)calloc(rec+PADMEM,
|
||||
sizeof(DtDtsDbRecord *));
|
||||
if(db->recordList)
|
||||
{
|
||||
memmove(newlist, db->recordList,
|
||||
rec*sizeof(DtDtsDbRecord *));
|
||||
if(db->recordList) free(db->recordList);
|
||||
}
|
||||
db->recordList = newlist;
|
||||
}
|
||||
db->recordList[rec] = (DtDtsDbRecord *)calloc(1, sizeof(DtDtsDbRecord));
|
||||
db->recordCount++;
|
||||
|
||||
return(db->recordList[rec]);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbDeleteRecord(DtDtsDbRecord *rec, DtDtsDbDatabase *db)
|
||||
{
|
||||
int i;
|
||||
|
||||
_DtDtsDbDeleteFields(rec);
|
||||
if(rec) free(rec);
|
||||
|
||||
for(i = 0; i < db->recordCount; i++)
|
||||
{
|
||||
if(db->recordList[i] == rec)
|
||||
{
|
||||
memmove( &(db->recordList[i]),
|
||||
&(db->recordList[i+1]),
|
||||
(db->recordCount - i - 1)*
|
||||
sizeof(DtDtsDbRecord *));
|
||||
db->recordCount--;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbDeleteRecords(DtDtsDbDatabase *db)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < db->recordCount; i++)
|
||||
{
|
||||
_DtDtsDbDeleteFields(db->recordList[i]);
|
||||
if(db->recordList[i])
|
||||
free(db->recordList[i]);
|
||||
}
|
||||
if(db->recordList)
|
||||
free(db->recordList);
|
||||
db->recordList = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
DtDtsDbField *
|
||||
_DtDtsDbAddField(DtDtsDbRecord *rec)
|
||||
{
|
||||
DtDtsDbField **newlist;
|
||||
int flds = rec->fieldCount;
|
||||
|
||||
if(flds%PADMEM == 0)
|
||||
{
|
||||
newlist = (DtDtsDbField **)calloc(flds+PADMEM,
|
||||
sizeof(DtDtsDbField *));
|
||||
if(rec->fieldList)
|
||||
{
|
||||
memmove(newlist, rec->fieldList,
|
||||
flds*sizeof(DtDtsDbField *));
|
||||
if(rec->fieldList)
|
||||
free(rec->fieldList);
|
||||
}
|
||||
rec->fieldList = newlist;
|
||||
}
|
||||
rec->fieldList[flds] = (DtDtsDbField *)calloc(1, sizeof(DtDtsDbField));
|
||||
rec->fieldCount++;
|
||||
|
||||
return(rec->fieldList[flds]);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbDeleteField(DtDtsDbField *fld, DtDtsDbRecord *rec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(fld) free(fld);
|
||||
for(i = 0; i < rec->fieldCount; i++)
|
||||
{
|
||||
if(rec->fieldList[i] == fld)
|
||||
{
|
||||
memmove( &(rec->fieldList[i]),
|
||||
&(rec->fieldList[i+1]),
|
||||
(rec->fieldCount - i - 1)*
|
||||
sizeof(DtDtsDbField *));
|
||||
rec->fieldCount--;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsDbDeleteFields(DtDtsDbRecord *rec)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < rec->fieldCount; i++)
|
||||
{
|
||||
if(rec->fieldList[i]->fieldValue)
|
||||
free(rec->fieldList[i]->fieldValue);
|
||||
if(rec->fieldList[i])
|
||||
free(rec->fieldList[i]);
|
||||
}
|
||||
if(rec->fieldList) free(rec->fieldList);
|
||||
rec->fieldList = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsMMCreateFile(DtDirPaths *dirs, const char *CacheFile)
|
||||
{
|
||||
return _MMWriteDb(dirs, num_db, db_list, CacheFile);
|
||||
}
|
||||
132
cde/lib/DtSvc/DtUtil1/DtsDb.h
Normal file
132
cde/lib/DtSvc/DtUtil1/DtsDb.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $XConsortium: DtsDb.h /main/5 1996/08/28 14:32:17 rswiston $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement bertween
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
#ifndef DT_DTS_DB_H
|
||||
#define DT_DTS_DB_H
|
||||
|
||||
#include <X11/Xresource.h>
|
||||
#include <Dt/DbReader.h>
|
||||
|
||||
typedef int OtBoolean;
|
||||
|
||||
/* typedefs for casting comparison functions if needed */
|
||||
typedef int (*_DtDtsDbFieldCompare)(DtDtsDbField **fld1, DtDtsDbField **fld2);
|
||||
|
||||
/* entry of a list of attribute/pairs */
|
||||
typedef struct
|
||||
{
|
||||
XrmQuark recordName;
|
||||
_DtDtsDbFieldCompare compare;
|
||||
long pathId;
|
||||
int seq;
|
||||
int fieldCount;
|
||||
DtDtsDbField **fieldList;
|
||||
} DtDtsDbRecord;
|
||||
|
||||
/* typedefs for casting record comparison functions if needed */
|
||||
typedef int (*_DtDtsDbRecordCompare)(DtDtsDbRecord **rec1, DtDtsDbRecord **rec2);
|
||||
|
||||
/* a "database" of a collection of entrys (i.e. OBJECT-TYPE, ACTION, FILE-TYPE
|
||||
This is a private Structure to the DtDtsDb component.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *databaseName;
|
||||
_DtDtsDbRecordCompare compare;
|
||||
int recordCount;
|
||||
DtDtsDbRecord **recordList;
|
||||
unsigned long ActionSequenceNumber;
|
||||
} DtDtsDbDatabase;
|
||||
|
||||
/* for the mmaped database this the use_in_memory_db variable is used
|
||||
to call the old API while the database is being built and is set to
|
||||
false when the mmaped versions are being accessed.
|
||||
*/
|
||||
|
||||
extern int use_in_memory_db;
|
||||
|
||||
/*
|
||||
* adds a new database to the list of databases -- returns a pointer to the
|
||||
* new database. If a database of the given name already exists it returns
|
||||
* a pointer to that database.
|
||||
*/
|
||||
extern DtDtsDbDatabase *_DtDtsDbAddDatabase( char *dbname );
|
||||
|
||||
/* returns the handle for the database where name is the Database name */
|
||||
extern DtDtsDbDatabase *_DtDtsDbGet(char *name);
|
||||
extern char **_DtDtsDbListDb(void);
|
||||
|
||||
/* Record Sort function:
|
||||
* sorts the specified database, usually obtained from _DtDtsDbGet(), in the
|
||||
* order specified by the comparison function. If (*compare) == 0 then
|
||||
* _DtDtsDbCompareRecordNames() is used as the (*compare) function.
|
||||
*/
|
||||
extern void _DtDtsDbRecordSort(DtDtsDbDatabase *database,
|
||||
_DtDtsDbRecordCompare compare);
|
||||
/* Field Sort function:
|
||||
* sorts the specified Record in the order specified by the comparison function
|
||||
* If (*compare) == 0 then _DtDtsDbCompareFieldNames() is used as the
|
||||
* (*compare) function.
|
||||
*/
|
||||
extern void _DtDtsDbFieldSort(DtDtsDbRecord *record,
|
||||
_DtDtsDbFieldCompare compare);
|
||||
|
||||
/* Name Comparison functions:
|
||||
* These routines can be passed in to the corresponding sort function to
|
||||
* sort by name.
|
||||
*
|
||||
*/
|
||||
extern int _DtDtsDbCompareRecordNames(DtDtsDbRecord **entry1, DtDtsDbRecord **entry2);
|
||||
extern int _DtDtsDbCompareFieldNames(DtDtsDbField **entry1, DtDtsDbField **entry2);
|
||||
|
||||
/* retrieves the Record that matches the specified entry from the record */
|
||||
extern DtDtsDbField *_DtDtsDbGetField(DtDtsDbRecord *record,
|
||||
char *value);
|
||||
|
||||
/* retrieves the entry of the specified entry from the specified database */
|
||||
extern DtDtsDbRecord *_DtDtsDbGetRecord(DtDtsDbDatabase *database,
|
||||
DtDtsDbRecord *value);
|
||||
|
||||
/* Get By Name functions:
|
||||
* retrieves the entry of the specified name from the specified database
|
||||
* ** IF ** the _DtDtsDb*Sort routine has been called with the corresponding
|
||||
* _DtDtsDbCompare*Name comparison function. Otherwise use the standard
|
||||
* _DtDtsDbGet* functions.
|
||||
*/
|
||||
extern char *_DtDtsDbGetFieldByName(DtDtsDbRecord *record, char *name);
|
||||
extern DtDtsDbRecord *_DtDtsDbGetRecordByName(DtDtsDbDatabase *database, char *name);
|
||||
|
||||
extern DtDtsDbRecord *_DtDtsDbAddRecord(DtDtsDbDatabase *db);
|
||||
|
||||
extern DtDtsDbField *_DtDtsDbAddField(DtDtsDbRecord *rec);
|
||||
|
||||
extern int _DtDtsDbDeleteDb(DtDtsDbDatabase *db);
|
||||
extern int _DtDtsDbDeleteRecord(DtDtsDbRecord *rec, DtDtsDbDatabase *db);
|
||||
extern int _DtDtsDbDeleteRecords(DtDtsDbDatabase *db);
|
||||
extern int _DtDtsDbDeleteField(DtDtsDbField *fld, DtDtsDbRecord *rec);
|
||||
extern int _DtDtsDbDeleteFields(DtDtsDbRecord *rec);
|
||||
|
||||
#endif
|
||||
|
||||
227
cde/lib/DtSvc/DtUtil1/DtsInit.c
Normal file
227
cde/lib/DtSvc/DtUtil1/DtsInit.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*
|
||||
* +SNOTICE
|
||||
*
|
||||
* $XConsortium: DtsInit.c /main/5 1996/08/28 16:08:50 rswiston $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special restrictions in a
|
||||
* confidential disclosure agreement bertween HP, IBM, Sun, USL, SCO and
|
||||
* Univel. Do not distribute this document outside HP, IBM, Sun, USL, SCO,
|
||||
* or Univel wihtout Sun's specific written approval. This documment and all
|
||||
* copies and derivative works thereof must be returned or destroyed at Sun's
|
||||
* request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* +ENOTICE
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __hpux
|
||||
#include <ndir.h>
|
||||
#else
|
||||
|
||||
#if defined(sun) || defined(USL) || defined(sco) || defined(__uxp__)
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include <sys/dir.h>
|
||||
#endif /* sun || USL */
|
||||
|
||||
#endif /* __hpux */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NLS16
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
|
||||
#include <Dt/DbReader.h>
|
||||
#include <Dt/DtsDb.h>
|
||||
#include <Dt/Dts.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
extern char *strdup(const char *);
|
||||
|
||||
static int cur_dc_count = 0;
|
||||
static int cur_da_count = 0;
|
||||
#define _DtFT_NUM_FIELDS 20
|
||||
|
||||
int
|
||||
_DtDtsNextDCSeq()
|
||||
{
|
||||
int nextDCSeq;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
nextDCSeq = ++cur_dc_count;
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(nextDCSeq);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsNextDASeq()
|
||||
{
|
||||
int nextDASeq;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
nextDASeq = ++cur_da_count;
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(nextDASeq);
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsSeqReset()
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
cur_dc_count = 0;
|
||||
cur_da_count = 0;
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
void
|
||||
_DtDtsDCConverter(DtDtsDbField * fields,
|
||||
DtDbPathId pathId,
|
||||
char *hostPrefix,
|
||||
Boolean rejectionStatus)
|
||||
{
|
||||
DtDtsDbDatabase *db;
|
||||
DtDtsDbRecord *rec;
|
||||
DtDtsDbField *fld;
|
||||
int i = 0;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
db = _DtDtsDbGet(DtDTS_DC_NAME);
|
||||
while (fields[i].fieldName && fields[i].fieldValue)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if(rec=_DtDtsDbGetRecordByName(db,fields[i].fieldValue))
|
||||
{
|
||||
char *value = _DtDtsDbGetFieldByName(rec,DtDTS_DA_IS_SYNTHETIC);
|
||||
/*
|
||||
* Check if the record is SYNTHETIC --
|
||||
* if so then replace it with this real
|
||||
* definition -- otherwise return.
|
||||
*/
|
||||
if (value && !strcmp(value,"True") )
|
||||
{
|
||||
/* free up the current record */
|
||||
_DtDtsDbDeleteRecord(rec,db);
|
||||
}
|
||||
else
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
rec = _DtDtsDbAddRecord(db);
|
||||
rec->recordName = XrmStringToQuark(fields[i].fieldValue);
|
||||
rec->seq = _DtDtsNextDCSeq();
|
||||
rec->pathId = (int)pathId;
|
||||
}
|
||||
else
|
||||
{
|
||||
fld = _DtDtsDbAddField(rec);
|
||||
fld->fieldName = fields[i].fieldName;
|
||||
fld->fieldValue = strdup(fields[i].fieldValue);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsDAConverter(DtDtsDbField * fields,
|
||||
DtDbPathId pathId,
|
||||
char *hostPrefix,
|
||||
Boolean rejectionStatus)
|
||||
{
|
||||
DtDtsDbDatabase *db;
|
||||
DtDtsDbRecord *rec;
|
||||
DtDtsDbField *fld;
|
||||
int i = 0;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
db = _DtDtsDbGet(DtDTS_DA_NAME);
|
||||
|
||||
while (fields[i].fieldName && fields[i].fieldValue)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if(rec = _DtDtsDbGetRecordByName(db, fields[i].fieldValue))
|
||||
{
|
||||
char *value = _DtDtsDbGetFieldByName(rec,DtDTS_DA_IS_SYNTHETIC);
|
||||
/*
|
||||
* Check if the record is SYNTHETIC --
|
||||
* if so then replace it with this real
|
||||
* definition -- otherwise return.
|
||||
*/
|
||||
if (value && !strcmp(value,"True") )
|
||||
{
|
||||
/* free up the current record */
|
||||
_DtDtsDbDeleteRecord(rec,db);
|
||||
}
|
||||
else
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
rec = _DtDtsDbAddRecord(db);
|
||||
rec->recordName = XrmStringToQuark(fields[i].fieldValue);
|
||||
rec->seq = _DtDtsNextDASeq();
|
||||
fld = _DtDtsDbAddField(rec);
|
||||
fld->fieldName = XrmStringToQuark(DtDTS_DA_DATA_HOST);
|
||||
fld->fieldValue = hostPrefix?strdup(hostPrefix):(char *) 0;
|
||||
rec->pathId = (int)pathId;
|
||||
}
|
||||
else
|
||||
{
|
||||
fld = _DtDtsDbAddField(rec);
|
||||
fld->fieldName = fields[i].fieldName;
|
||||
fld->fieldValue = strdup(fields[i].fieldValue);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* DtDtsLoadDataTypes -
|
||||
*
|
||||
* Reads in the file types and action databases.
|
||||
*
|
||||
* Also initializes the variable DtMaxFileTypes to the number
|
||||
* of entries in the file types database.
|
||||
*
|
||||
* MODIFIED:
|
||||
*
|
||||
* DtMaxFtFileTypes
|
||||
* DtMaxFileTypes - set to the number of real filetypes
|
||||
* ( Holdovers from previous filetypes stuff -- still used by
|
||||
* some clients. i.e. dtfile )
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
DtDtsLoadDataTypes(void)
|
||||
{
|
||||
/* with new mmap database this function is not needed to
|
||||
* load the database. Just to initialize it.
|
||||
*/
|
||||
|
||||
_DtDtsMMUnLoad();
|
||||
}
|
||||
752
cde/lib/DtSvc/DtUtil1/DtsMM.c
Normal file
752
cde/lib/DtSvc/DtUtil1/DtsMM.c
Normal file
@@ -0,0 +1,752 @@
|
||||
/*
|
||||
* $TOG: DtsMM.c /main/16 1998/10/23 13:48:28 mgreess $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* (c) Copyright 1993,1994,1995 Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#define SUN_DB
|
||||
#ifdef SUN_DB
|
||||
#include <sys/utsname.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#define X_INCLUDE_DIRENT_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <Dt/DbReader.h>
|
||||
#include "Dt/DtsMM.h"
|
||||
#include "Dt/DtNlUtils.h"
|
||||
#include <Dt/UserMsg.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
extern char *strdup(const char *);
|
||||
static int MMValidateDb(DtDirPaths *dirs, char *suffix);
|
||||
static int _debug_print_name(char *name, char *label);
|
||||
|
||||
typedef int (*genfunc)(const void *, const void *);
|
||||
|
||||
static DtDtsMMDatabase *db_list;
|
||||
static caddr_t mmaped_db = 0;
|
||||
static size_t mmaped_size = 0;
|
||||
static int mmaped_fd = 0;
|
||||
static DtDtsMMHeader *head = 0;
|
||||
|
||||
void *
|
||||
_DtDtsMMGetPtr(int index)
|
||||
{
|
||||
DtShmIntList int_list;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
int_list = (DtShmIntList)&mmaped_db[sizeof(DtDtsMMHeader)];
|
||||
_DtSvcProcessUnlock();
|
||||
return((void *)&int_list[index]);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsMMGetPtrSize(int index)
|
||||
{
|
||||
DtShmIntList int_list;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
int_list = (DtShmIntList)&mmaped_db[sizeof(DtDtsMMHeader)];
|
||||
_DtSvcProcessUnlock();
|
||||
return(int_list[index-1]);
|
||||
}
|
||||
|
||||
int *
|
||||
_DtDtsMMGetDCNameIndex(int *size)
|
||||
{
|
||||
int *result;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
*size = _DtDtsMMGetPtrSize(head->name_list_offset);
|
||||
result = (int*) _DtDtsMMGetPtr(head->name_list_offset);
|
||||
_DtSvcProcessUnlock();
|
||||
return(result);
|
||||
}
|
||||
|
||||
int *
|
||||
_DtDtsMMGetDbName(DtDtsMMDatabase *db, DtShmBoson boson)
|
||||
{
|
||||
DtShmInttab tab = (DtShmInttab)_DtDtsMMGetPtr(db->nameIndex);
|
||||
return((int *)_DtShmFindIntTabEntry(tab, boson));
|
||||
}
|
||||
|
||||
int *
|
||||
_DtDtsMMGetNoNameIndex(int *size)
|
||||
{
|
||||
int *result;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
|
||||
if(head->no_name_offset == -1)
|
||||
{
|
||||
*size = 0;
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
*size = _DtDtsMMGetPtrSize(head->no_name_offset);
|
||||
result = (int *) _DtDtsMMGetPtr(head->no_name_offset);
|
||||
_DtSvcProcessUnlock();
|
||||
return(result);
|
||||
}
|
||||
|
||||
/* returns the pointer to buffer only name list */
|
||||
int *
|
||||
_DtDtsMMGetBufferIndex(int *size)
|
||||
{
|
||||
int *list = (int*)_DtDtsMMGetNoNameIndex(size);
|
||||
int *bufferIndex;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
*size -= head->buffer_start_index;
|
||||
bufferIndex = &list[head->buffer_start_index];
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(bufferIndex);
|
||||
}
|
||||
|
||||
DtShmInttab
|
||||
_DtDtsMMGetFileList(void)
|
||||
{
|
||||
DtShmInttab file_index;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
file_index = (DtShmStrtab)_DtDtsMMGetPtr(head->files_offset);
|
||||
_DtSvcProcessUnlock();
|
||||
return(file_index);
|
||||
}
|
||||
|
||||
const char *
|
||||
_DtDtsMMBosonToString(DtShmBoson boson)
|
||||
{
|
||||
DtShmStrtab str_table;
|
||||
|
||||
if (boson == 0)
|
||||
return(0);
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
|
||||
str_table = (DtShmStrtab)_DtDtsMMGetPtr(head->str_tbl_offset);
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(_DtShmBosonToString(str_table, boson));
|
||||
}
|
||||
|
||||
DtShmBoson
|
||||
_DtDtsMMStringToBoson(const char *string)
|
||||
{
|
||||
DtShmStrtab str_table;
|
||||
|
||||
if ((string == (char *)NULL) || (*string == '\0'))
|
||||
return(-1);
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
|
||||
str_table = (DtShmStrtab)_DtDtsMMGetPtr(head->str_tbl_offset);
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(_DtShmStringToBoson(str_table, string));
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsMMPrintFld(int fld, DtDtsMMField *fld_ptr, FILE *fd_in)
|
||||
{
|
||||
const char *tmp;
|
||||
const char *tmpv;
|
||||
FILE *fd = fd_in;
|
||||
|
||||
if(!fd) fd = stdout;
|
||||
|
||||
tmp = _DtDtsMMBosonToString(fld_ptr->fieldName);
|
||||
tmpv = _DtDtsMMBosonToString(fld_ptr->fieldValue);
|
||||
fprintf(fd, "\t\t[%d]\t%s(%d)\t%s(%d)\n", fld, tmp,fld_ptr->fieldName,
|
||||
tmpv?tmpv:"(NULL)", fld_ptr->fieldValue);
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsMMPrintRec(int rec, DtDtsMMRecord *rec_ptr, FILE *fd_in)
|
||||
{
|
||||
int fld;
|
||||
DtDtsMMField *fld_ptr;
|
||||
DtDtsMMField *fld_ptr_list;
|
||||
const char *tmp;
|
||||
FILE *fd = fd_in;
|
||||
|
||||
if(!fd) fd = stdout;
|
||||
|
||||
tmp = _DtDtsMMBosonToString(rec_ptr->recordName);
|
||||
fprintf(fd, "\tRec[%d] name = %s(%d)\n\t%d Fields\n", rec,
|
||||
tmp, rec_ptr->recordName,
|
||||
rec_ptr->fieldCount);
|
||||
fld_ptr_list = _DtDtsMMGetPtr(rec_ptr->fieldList);
|
||||
for(fld = 0; fld < rec_ptr->fieldCount; fld++)
|
||||
{
|
||||
fld_ptr = &fld_ptr_list[fld];
|
||||
_DtDtsMMPrintFld(fld, fld_ptr, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsMMPrintDb(int db, DtDtsMMDatabase *db_ptr, FILE *fd_in)
|
||||
{
|
||||
int rec;
|
||||
DtDtsMMRecord *rec_ptr;
|
||||
DtDtsMMRecord *rec_ptr_list;
|
||||
const char *tmp;
|
||||
FILE *fd = fd_in;
|
||||
|
||||
if(!fd) fd = stdout;
|
||||
|
||||
fprintf(fd, "DB[%d] ", db);
|
||||
tmp = _DtDtsMMBosonToString(db_ptr->databaseName);
|
||||
fprintf(fd, "name = %s(%d)\n", tmp, db_ptr->databaseName);
|
||||
fprintf(fd, "%d Records\n", db_ptr->recordCount);
|
||||
rec_ptr_list = _DtDtsMMGetPtr(db_ptr->recordList);
|
||||
for(rec = 0; rec < db_ptr->recordCount; rec++)
|
||||
{
|
||||
rec_ptr = &rec_ptr_list[rec];
|
||||
_DtDtsMMPrintRec(rec, rec_ptr, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsMMPrint(FILE *org_fd)
|
||||
{
|
||||
int db;
|
||||
DtDtsMMDatabase *db_ptr;
|
||||
FILE *fd = org_fd;
|
||||
const char *tmp;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
|
||||
for(db = 0; db < head->num_db; db++)
|
||||
{
|
||||
db_ptr = &db_list[db];
|
||||
if(fd == 0)
|
||||
{
|
||||
chdir("/tmp");
|
||||
tmp = _DtDtsMMBosonToString(db_ptr->databaseName);
|
||||
if((fd = fopen(tmp, "w")) == NULL)
|
||||
{
|
||||
_DtSimpleError(
|
||||
DtProgName, DtError, NULL,
|
||||
(char*) tmp, NULL);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_DtDtsMMPrintDb(db, db_ptr, fd);
|
||||
if(org_fd == 0)
|
||||
{
|
||||
fclose(fd);
|
||||
fd = 0;
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsMMCompareRecordNames(DtDtsMMRecord *a, DtDtsMMRecord *b)
|
||||
{
|
||||
return (a->recordName - b->recordName);
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsMMCompareFieldNames(DtDtsMMField *a, DtDtsMMField *b)
|
||||
{
|
||||
return (a->fieldName - b->fieldName);
|
||||
}
|
||||
|
||||
#include <Dt/Dts.h>
|
||||
|
||||
int
|
||||
_DtDtsMMInit(int override)
|
||||
{
|
||||
DtDirPaths *dirs = _DtGetDatabaseDirPaths();
|
||||
char *CacheFile = _DtDtsMMCacheName(1);
|
||||
if(override)
|
||||
{
|
||||
if (!_DtDtsMMCreateDb(dirs, CacheFile, override))
|
||||
{
|
||||
free(CacheFile);
|
||||
_DtFreeDatabaseDirPaths(dirs);
|
||||
return 0;
|
||||
}
|
||||
_debug_print_name(CacheFile, "Init");
|
||||
}
|
||||
else
|
||||
{
|
||||
int success = _DtDtsMMapDB(CacheFile);
|
||||
if(success)
|
||||
{
|
||||
if(!MMValidateDb(dirs, ".dt"))
|
||||
{
|
||||
success = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_debug_print_name(CacheFile, "Mapped");
|
||||
}
|
||||
}
|
||||
if(!success)
|
||||
{
|
||||
free(CacheFile);
|
||||
CacheFile = _DtDtsMMCacheName(0);
|
||||
_debug_print_name(CacheFile, "Private");
|
||||
/* Check return status, and pass status to caller. */
|
||||
if (!_DtDtsMMCreateDb(dirs, CacheFile, override))
|
||||
{
|
||||
free(CacheFile);
|
||||
_DtFreeDatabaseDirPaths(dirs);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(CacheFile);
|
||||
_DtFreeDatabaseDirPaths(dirs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char **
|
||||
_DtsMMListDb()
|
||||
{
|
||||
int i;
|
||||
char **list;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
|
||||
list = (char **)malloc((head->num_db+1)*sizeof(char *));
|
||||
for ( i = 0; i < head->num_db; i++ )
|
||||
{
|
||||
list[i] = (char *)_DtDtsMMBosonToString(db_list[i].databaseName);
|
||||
}
|
||||
list[i] = 0;
|
||||
_DtSvcProcessUnlock();
|
||||
return(list);
|
||||
}
|
||||
|
||||
|
||||
DtDtsMMDatabase *
|
||||
_DtDtsMMGet(const char *name)
|
||||
{
|
||||
int i;
|
||||
DtShmBoson boson = _DtDtsMMStringToBoson(name);
|
||||
DtDtsMMDatabase *ret_db;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(!mmaped_db)
|
||||
{
|
||||
_DtDtsMMInit(0);
|
||||
}
|
||||
for(i = 0; i < head->num_db; i++)
|
||||
{
|
||||
if(db_list[i].databaseName == boson)
|
||||
{
|
||||
ret_db = &db_list[i];
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
return(ret_db);
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
DtDtsMMField *
|
||||
_DtDtsMMGetField(DtDtsMMRecord *rec, const char *name)
|
||||
{
|
||||
register int i;
|
||||
int fld;
|
||||
DtDtsMMField *fld_ptr;
|
||||
DtDtsMMField *fld_ptr_list;
|
||||
|
||||
/*
|
||||
* Field names have been quarked so quark 'name' and
|
||||
* do a linear search for the quark'ed field name.
|
||||
*/
|
||||
DtShmBoson tmp = _DtDtsMMStringToBoson (name);
|
||||
|
||||
fld_ptr_list = _DtDtsMMGetPtr(rec->fieldList);
|
||||
for (i = 0; i < rec->fieldCount; i++)
|
||||
{
|
||||
fld_ptr = &fld_ptr_list[i];
|
||||
if (fld_ptr->fieldName == tmp)
|
||||
{
|
||||
return (fld_ptr);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
_DtDtsMMGetFieldByName(DtDtsMMRecord *rec, const char *name)
|
||||
{
|
||||
DtDtsMMField *result;
|
||||
|
||||
result = _DtDtsMMGetField(rec, name);
|
||||
if(result)
|
||||
{
|
||||
return(_DtDtsMMBosonToString(result->fieldValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DtDtsMMRecord *
|
||||
_DtDtsMMGetRecordByName(DtDtsMMDatabase *db, const char *name)
|
||||
{
|
||||
DtDtsMMRecord srch;
|
||||
DtDtsMMRecord *result;
|
||||
DtDtsMMRecord *s = &srch;
|
||||
register int i;
|
||||
DtShmBoson name_quark = _DtDtsMMStringToBoson(name);
|
||||
DtDtsMMRecord *rec_ptr;
|
||||
DtDtsMMRecord *rec_ptr_list;
|
||||
|
||||
/*
|
||||
* If the fields are not sorted in alphanumeric order
|
||||
* by name a binary search will fail. So do the slow but
|
||||
* sure linear search.
|
||||
*/
|
||||
rec_ptr_list = _DtDtsMMGetPtr(db->recordList);
|
||||
|
||||
for (i = 0; i < db->recordCount; i++)
|
||||
{
|
||||
rec_ptr = &rec_ptr_list[i];
|
||||
if (rec_ptr->recordName == name_quark)
|
||||
{
|
||||
return (rec_ptr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int
|
||||
_DtDtsMMPathHash(DtDirPaths *dirs)
|
||||
{
|
||||
int pathhash = 0;
|
||||
DIR *dirp;
|
||||
struct dirent *dp = NULL;
|
||||
int suffixLen;
|
||||
int nameLen;
|
||||
char *file_suffix;
|
||||
char *next_path;
|
||||
char *suffix = ".dt";
|
||||
int i;
|
||||
char *cur_dir = getcwd(0,MAXPATHLEN);
|
||||
struct stat buf;
|
||||
|
||||
_Xreaddirparams dirEntryBuf;
|
||||
struct dirent *result;
|
||||
|
||||
for(i = 0; dirs->paths[i] ; i++)
|
||||
{
|
||||
if(chdir(dirs->paths[i]) == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dirp = opendir (".");
|
||||
while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL)
|
||||
{
|
||||
if ((int)strlen (result->d_name) >= (int)strlen(suffix))
|
||||
{
|
||||
suffixLen = DtCharCount(suffix);
|
||||
nameLen = DtCharCount(result->d_name);
|
||||
file_suffix = (char *)_DtGetNthChar(result->d_name,
|
||||
nameLen - suffixLen);
|
||||
stat(result->d_name, &buf);
|
||||
if (file_suffix &&
|
||||
(strcmp(file_suffix, suffix) == 0) &&
|
||||
(buf.st_mode&S_IFREG))
|
||||
{
|
||||
char *c = dirs->paths[i];
|
||||
while(*c)
|
||||
{
|
||||
pathhash += (int)*c;
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
chdir(cur_dir);
|
||||
free(cur_dir);
|
||||
return(pathhash);
|
||||
}
|
||||
|
||||
char *
|
||||
_DtDtsMMCacheName(int override)
|
||||
{
|
||||
char *dsp = getenv("DISPLAY");
|
||||
char *results = 0;
|
||||
char *c;
|
||||
|
||||
if(override && dsp)
|
||||
{
|
||||
results = malloc(strlen(_DTDTSMMTEMPDIR)+
|
||||
strlen(_DTDTSMMTEMPFILE)+
|
||||
strlen(dsp)+3);
|
||||
sprintf(results, "%s/%s%s\0",
|
||||
_DTDTSMMTEMPDIR,
|
||||
_DTDTSMMTEMPFILE,
|
||||
dsp);
|
||||
c = strchr(results, ':');
|
||||
c = strchr(c, '.');
|
||||
if(c)
|
||||
{
|
||||
*c = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* tempnam(3) is affected by the TMPDIR environment variable. */
|
||||
/* This creates problems for rename() if "tmpfile" and "cacheFile" */
|
||||
/* are on different file systems. Use tmpnam(3) to create the */
|
||||
/* unique file name instead. */
|
||||
char tmpnam_buf[L_tmpnam + 1];
|
||||
|
||||
results = (char *)malloc(sizeof(_DTDTSMMTEMPDIR) +
|
||||
sizeof(_DTDTSMMTEMPFILE) +
|
||||
L_tmpnam + 3);
|
||||
tmpnam(tmpnam_buf);
|
||||
sprintf(results, "%s/%s%s", _DTDTSMMTEMPDIR, _DTDTSMMTEMPFILE,
|
||||
basename(tmpnam_buf));
|
||||
}
|
||||
return(results);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_DtDtsMMapDB(const char *CacheFile)
|
||||
{
|
||||
struct stat buf;
|
||||
int success = FALSE;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
|
||||
if (mmaped_fd > 0)
|
||||
{
|
||||
/* Already have a file memory-mapped. Unload it. */
|
||||
_DtDtsMMUnLoad();
|
||||
}
|
||||
|
||||
mmaped_fd = open(CacheFile, O_RDONLY, 0400);
|
||||
if(mmaped_fd != -1)
|
||||
{
|
||||
if(fstat(mmaped_fd, &buf) == 0 && buf.st_uid == getuid())
|
||||
{
|
||||
mmaped_db = (char *)mmap(NULL,
|
||||
buf.st_size,
|
||||
PROT_READ,
|
||||
#if defined(sun) || defined(USL)
|
||||
/* MAP_NORESERVE is only supported
|
||||
on sun and novell platforms */
|
||||
MAP_SHARED|MAP_NORESERVE,
|
||||
#else
|
||||
MAP_SHARED,
|
||||
#endif
|
||||
mmaped_fd,
|
||||
NULL);
|
||||
if(mmaped_db != (void *) -1)
|
||||
{
|
||||
success = TRUE;
|
||||
mmaped_size = buf.st_size;
|
||||
head = (DtDtsMMHeader *)mmaped_db;
|
||||
db_list = (DtDtsMMDatabase *)_DtDtsMMGetPtr(head->db_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
_DtSimpleError(
|
||||
DtProgName, DtError, NULL,
|
||||
(char*) CacheFile, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!success)
|
||||
{
|
||||
mmaped_db = 0;
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
return(success);
|
||||
}
|
||||
|
||||
static int
|
||||
MMValidateDb(DtDirPaths *dirs, char *suffix)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *direntp;
|
||||
struct stat buf;
|
||||
struct stat new_buf;
|
||||
int size = sizeof(buf.st_mtime);
|
||||
DtShmBoson *boson_list = 0;
|
||||
time_t *mtime_list;
|
||||
int count = 0;
|
||||
int i;
|
||||
const char *file;
|
||||
int pathhash = _DtDtsMMPathHash(dirs);
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(head->pathhash != pathhash)
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
|
||||
count = head->files_count;
|
||||
mtime_list = _DtDtsMMGetPtr(head->mtimes_offset);
|
||||
boson_list = _DtDtsMMGetPtr(head->files_offset);
|
||||
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
file = _DtDtsMMBosonToString(boson_list[i]);
|
||||
stat(file, &buf);
|
||||
if(mtime_list[i] != buf.st_mtime)
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
return(1);
|
||||
|
||||
}
|
||||
|
||||
char *
|
||||
_DtDtsMMExpandValue(const char *value)
|
||||
{
|
||||
char *newval;
|
||||
|
||||
if(!value)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
newval = (char *)malloc(1024);
|
||||
|
||||
strcpy(newval, value);
|
||||
_DtDbFillVariables(&newval);
|
||||
return(newval);
|
||||
}
|
||||
|
||||
void
|
||||
_DtDtsMMSafeFree(char *value)
|
||||
{
|
||||
if(value && !_DtDtsMMIsMemory(value))
|
||||
{
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsMMIsMemory(const char *value)
|
||||
{
|
||||
_DtSvcProcessLock();
|
||||
if((caddr_t)value < mmaped_db || (caddr_t)value > mmaped_db+mmaped_size)
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_DtDtsMMUnLoad()
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
_DtDtsClear();
|
||||
if(mmaped_db == 0)
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(error);
|
||||
}
|
||||
if(munmap(mmaped_db, mmaped_size) == -1)
|
||||
{
|
||||
_DtSimpleError(DtProgName, DtError, NULL,
|
||||
"munmap of dts_cache file", NULL);
|
||||
error = -1;
|
||||
}
|
||||
if(close(mmaped_fd) == -1)
|
||||
{
|
||||
_DtSimpleError(DtProgName, DtError, NULL,
|
||||
"close of dts_cache file", NULL);
|
||||
}
|
||||
|
||||
db_list = 0;
|
||||
mmaped_db = 0;
|
||||
mmaped_size = 0;
|
||||
mmaped_fd = 0;
|
||||
head = 0;
|
||||
_DtSvcProcessUnlock();
|
||||
return(error);
|
||||
}
|
||||
|
||||
#include "Dt/UserMsg.h"
|
||||
|
||||
static int
|
||||
_debug_print_name(char *name, char *label)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
static char *db = (char *)-1;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if(db == (char *)-1)
|
||||
{
|
||||
db = getenv("MMAP_DEBUG");
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
if(db)
|
||||
_DtSimpleError(db,
|
||||
DtInformation,
|
||||
NULL,
|
||||
"%s - db name = %s\n", label,
|
||||
name);
|
||||
#endif /* DEBUG */
|
||||
return(0);
|
||||
}
|
||||
152
cde/lib/DtSvc/DtUtil1/DtsMM.h
Normal file
152
cde/lib/DtSvc/DtUtil1/DtsMM.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* $XConsortium: DtsMM.h /main/8 1996/08/28 14:27:26 rswiston $ */
|
||||
/*
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
#ifndef DT_DTS_MM_H
|
||||
#define DT_DTS_MM_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Dt/DtShmDb.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include "Dt/DbReader.h"
|
||||
|
||||
#define DTDTSDB_TMPDATABASENAME "%s/.dt/.tmp_dt_db_cache.%s\0"
|
||||
#define DTDTSDB_DATABASENAME "%s/.dt/.dt_db_cache.%s\0"
|
||||
#define _DTDTSMMTEMPFILE "dtdbcache_"
|
||||
|
||||
/*
|
||||
* NOTE: _DTDTSMMTEMPDIR affects the location of the dtdbcache
|
||||
* file, and therefore affects the Xsession.src, Xreset.src, and
|
||||
* Xstartup.src scripts in dtlogin/config.
|
||||
*/
|
||||
#ifdef __osf__
|
||||
# define _DTDTSMMTEMPDIR "/var/tmp"
|
||||
#else
|
||||
# define _DTDTSMMTEMPDIR "/tmp"
|
||||
#endif
|
||||
|
||||
typedef int DtDtsMMSeqNo; /* the order it occures in db */
|
||||
typedef int DtDtsMMFieldCount; /* number of fields in record */
|
||||
typedef int DtDtsMMRecordCount; /* number of records in field */
|
||||
typedef int DtDtsMMDataBaseCount; /* how many databases */
|
||||
typedef int DtDtsMMFieldStart; /* index in table where field list starts */
|
||||
typedef int DtDtsMMRecordStart; /* index in table where record list starts */
|
||||
typedef int DtDtsMMDataBaseStart; /* index in table where database list starts */
|
||||
typedef int DtDtsMMIndexOffset;
|
||||
typedef int DtDtsMMNameIndex;
|
||||
typedef int DtDtsMMPathHash;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DtDtsMMPathHash pathhash; /* hash of dir. we visit */
|
||||
DtDtsMMDataBaseCount num_db; /* number of databases */
|
||||
DtDtsMMDataBaseStart db_offset; /* index to databases */
|
||||
DtDtsMMNameIndex name_list_offset; /* index to name list */
|
||||
DtDtsMMNameIndex no_name_offset; /* index to nonunique names */
|
||||
DtDtsMMNameIndex buffer_start_index; /* index to list of buffers */
|
||||
DtDtsMMIndexOffset str_tbl_offset; /* index to table of strings */
|
||||
DtDtsMMIndexOffset files_count; /* number of loaded files */
|
||||
DtDtsMMIndexOffset files_offset; /* index to list of loaded files */
|
||||
DtDtsMMIndexOffset mtimes_offset; /* index to modified times of files */
|
||||
} DtDtsMMHeader;
|
||||
|
||||
/* one set of attribute/pair */
|
||||
typedef struct
|
||||
{
|
||||
DtShmBoson fieldName; /* name of attribute */
|
||||
DtShmBoson fieldValue; /* value of attribute */
|
||||
} DtDtsMMField;
|
||||
|
||||
/* typedefs for casting comparison functions if needed */
|
||||
typedef int (*_DtDtsMMFieldCompare)(DtDtsMMField *fld1, DtDtsMMField *fld2);
|
||||
|
||||
/* entry of a list of attribute/pairs */
|
||||
typedef struct
|
||||
{
|
||||
DtShmBoson recordName; /* name of this entry */
|
||||
DtShmBoson pathId; /* file entry is located in */
|
||||
DtDtsMMSeqNo seq; /* sequence this got loaded */
|
||||
DtDtsMMFieldCount fieldCount; /* number of fields in record */
|
||||
DtDtsMMFieldStart fieldList; /* index to field table */
|
||||
} DtDtsMMRecord;
|
||||
|
||||
/* typedefs for casting record comparison functions if needed */
|
||||
typedef int (*_DtDtsMMRecordCompare)(DtDtsMMRecord *rec1, DtDtsMMRecord *rec2);
|
||||
|
||||
/* a "database" of a collection of entrys (i.e. OBJECT-TYPE, ACTION, FILE-TYPE
|
||||
This is a private Structure to the DtDtsMM component.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
DtShmBoson databaseName; /* name of database */
|
||||
DtDtsMMIndexOffset nameIndex; /* index for DataCriteria quick find */
|
||||
DtDtsMMRecordCount recordCount; /* number of records */
|
||||
DtDtsMMRecordStart recordList; /* index to records table */
|
||||
} DtDtsMMDatabase;
|
||||
|
||||
|
||||
/* Db Internal pointers */
|
||||
int * _DtDtsMMGetDCNameIndex(int *size);
|
||||
int * _DtDtsMMGetBufferIndex(int *size);
|
||||
int * _DtDtsMMGetNoNameIndex(int *size);
|
||||
void * _DtDtsMMGetPtr(int index);
|
||||
DtShmInttab _DtDtsMMGetFileList(void);
|
||||
int _DtDtsMMGetPtrSize(int index);
|
||||
int _DtDtsMMInit(int);
|
||||
void _DtDtsMMPrint(FILE *org_fd);
|
||||
int _DtDtsMMCreateDb(DtDirPaths *dirs, const char *CacheFile, int override);
|
||||
int _DtDtsMMCreateFile(DtDirPaths *dirs, const char *CacheFile);
|
||||
char * _DtDtsMMCacheName(int);
|
||||
int _DtDtsMMapDB(const char *CacheFile);
|
||||
|
||||
const char * _DtDtsMMBosonToString(DtShmBoson boson);
|
||||
DtShmBoson _DtDtsMMStringToBoson(const char *string);
|
||||
|
||||
extern int use_in_memory_db;
|
||||
|
||||
|
||||
/* returns the handle for the database where name is the Database name */
|
||||
extern DtDtsMMDatabase *_DtDtsMMGet(const char *name);
|
||||
extern char **_DtDtsMMListDb(void);
|
||||
|
||||
/* Name Comparison functions:
|
||||
* These routines can be passed in to the corresponding sort function to
|
||||
* sort by name.
|
||||
*
|
||||
*/
|
||||
extern int _DtDtsMMCompareRecordNames(DtDtsMMRecord *entry1, DtDtsMMRecord *entry2);
|
||||
extern int _DtDtsMMCompareFieldNames(DtDtsMMField *entry1, DtDtsMMField *entry2);
|
||||
|
||||
/* retrieves the Record that matches the specified entry from the record */
|
||||
extern DtDtsMMField *_DtDtsMMGetField(DtDtsMMRecord *record,
|
||||
const char *value);
|
||||
extern const char *_DtDtsMMGetFieldByName(DtDtsMMRecord *rec, const char *name);
|
||||
|
||||
/* retrieves the entry of the specified entry from the specified database */
|
||||
extern DtDtsMMRecord *_DtDtsMMGetRecord(DtDtsMMDatabase *database,
|
||||
DtDtsMMRecord *value);
|
||||
extern DtDtsMMRecord *_DtDtsMMGetRecordByName(DtDtsMMDatabase *database,
|
||||
const char *value);
|
||||
|
||||
/* Get By Name functions:
|
||||
* retrieves the entry of the specified name from the specified database
|
||||
* ** IF ** the _DtDtsMM*Sort routine has been called with the corresponding
|
||||
* _DtDtsMMCompare*Name comparison function. Otherwise use the standard
|
||||
* _DtDtsMMGet* functions.
|
||||
*/
|
||||
|
||||
|
||||
char * _DtDtsMMExpandValue(const char *value);
|
||||
void _DtDtsMMSafeFree(char *value);
|
||||
int _DtDtsMMIsMemory(const char *value);
|
||||
|
||||
extern DtShmBoson _DtDtsMMNameStringToBoson(const char *string);
|
||||
|
||||
|
||||
#endif /* DT_DTS_MM_H */
|
||||
451
cde/lib/DtSvc/DtUtil1/DtsSort.c
Normal file
451
cde/lib/DtSvc/DtUtil1/DtsSort.c
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $XConsortium: DtsSort.c /main/6 1996/11/21 19:56:08 drk $
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement bertween
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
|
||||
* Sun's specific written approval. This documment and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#define X_INCLUDE_STRING_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <Dt/DbReader.h>
|
||||
#include "Dt/DtsDb.h"
|
||||
#include "Dt/Dts.h"
|
||||
|
||||
extern char *strdup(const char *);
|
||||
|
||||
|
||||
static char *
|
||||
get_value(DtDtsDbRecord *ce_entry, char *value)
|
||||
{
|
||||
int i=0;
|
||||
XrmQuark tmp = XrmStringToQuark (value);
|
||||
|
||||
for(i = 0; i < ce_entry->fieldCount; i++)
|
||||
{
|
||||
if(ce_entry->fieldList[i]->fieldName == tmp)
|
||||
{
|
||||
return(ce_entry->fieldList[i]->fieldValue);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
parts_of_pattern(char *c, int *spec, int *count, int *front)
|
||||
{
|
||||
int nested = 0;
|
||||
int found = 0;
|
||||
int len;
|
||||
|
||||
(*count) = 0;
|
||||
(*spec) = 0;
|
||||
(*front) = 0;
|
||||
|
||||
while(*c)
|
||||
{
|
||||
if((len = mblen(c, MB_CUR_MAX)) > 1) {
|
||||
(*count) += len;
|
||||
if(!found)
|
||||
(*front) += len;
|
||||
c += len;
|
||||
continue;
|
||||
}
|
||||
switch(*c)
|
||||
{
|
||||
case '*':
|
||||
if(!nested)
|
||||
{
|
||||
(*spec) += 100;
|
||||
found = 1;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
if(!nested)
|
||||
{
|
||||
(*spec) += 1;
|
||||
found = 1;
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
(*spec) += 10;
|
||||
nested ++;
|
||||
found = 1;
|
||||
break;
|
||||
case ']':
|
||||
if(nested)
|
||||
{
|
||||
nested --;
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
if(!nested)
|
||||
{
|
||||
if((len = mblen(c + 1, MB_CUR_MAX)) > 1) {
|
||||
(*count) += len + 1;
|
||||
c += len;
|
||||
}
|
||||
else {
|
||||
(*count) += 2;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(*count)++;
|
||||
if(!found)
|
||||
{
|
||||
(*front)++;
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
check_pattern(char *value1, char *value2)
|
||||
{
|
||||
int spec1 = 0,count1 = 0, front1 = 0;
|
||||
int spec2 = 0,count2 = 0, front2 = 0;
|
||||
|
||||
if(value1 && value2)
|
||||
{
|
||||
parts_of_pattern(value1, &spec1, &count1, &front1);
|
||||
parts_of_pattern(value2, &spec2, &count2, &front2);
|
||||
}
|
||||
else if(!value1 && !value2)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
else if(value1)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
if(front1 != front2)
|
||||
{
|
||||
return(front2 - front1);
|
||||
}
|
||||
|
||||
if(spec1 != spec2)
|
||||
{
|
||||
return(spec1 - spec2);
|
||||
}
|
||||
if(count1 != count2)
|
||||
{
|
||||
return(count2-count1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mode_count(char *c)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while(c && *c)
|
||||
{
|
||||
|
||||
if(strchr("fcbdlrwx", *c))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static int
|
||||
bool(int i)
|
||||
{
|
||||
if(i > 0) return(1);
|
||||
if(i < 0) return(-1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
check_content(char *val1, char *val2)
|
||||
{
|
||||
char *v1 = strdup(val1);
|
||||
char *v2 = strdup(val2);
|
||||
char *loc1;
|
||||
char *loc2;
|
||||
char *type1;
|
||||
char *type2;
|
||||
char *cnt1;
|
||||
char *cnt2;
|
||||
int ret = 0;
|
||||
_Xstrtokparams strtok_buf;
|
||||
|
||||
loc1 = _XStrtok(v1, "\t \n", strtok_buf);
|
||||
type1 = _XStrtok(NULL, "\t \n", strtok_buf);
|
||||
cnt1 = &type1[strlen(type1)+1];
|
||||
while(isspace((u_char)*cnt1))cnt1++;
|
||||
|
||||
loc2 = _XStrtok(v2, "\t \n", strtok_buf);
|
||||
type2 = _XStrtok(NULL, "\t \n", strtok_buf);
|
||||
cnt2 = &type2[strlen(type2)+1];
|
||||
while(isspace((u_char)*cnt2))cnt2++;
|
||||
|
||||
ret = strcmp(type1, type2);
|
||||
if(loc1 && loc2 && ret == 0)
|
||||
{
|
||||
int l1 = atoi(loc1);
|
||||
int l2 = atoi(loc2);
|
||||
int sl1 = strlen(cnt1);
|
||||
int sl2 = strlen(cnt2);
|
||||
char sym;
|
||||
|
||||
if (sl1 > sl2) ret = -1;
|
||||
else if (sl1 < sl2) ret = 1;
|
||||
else if (l1 > l2 ) ret = 1;
|
||||
else if (l1 < l2 ) ret = -1;
|
||||
else ret = strcmp(cnt1,cnt2);
|
||||
|
||||
#ifdef DEBUG
|
||||
switch(bool(ret))
|
||||
{
|
||||
case 0:
|
||||
sym = '=';
|
||||
break;
|
||||
case -1:
|
||||
sym = '>';
|
||||
break;
|
||||
case 1:
|
||||
sym = '<';
|
||||
}
|
||||
printf("cc (%d,%d) for \"%s\" %c \"%s\"\n", l1, l2, cnt1, sym, cnt2);
|
||||
#endif
|
||||
}
|
||||
free(v1);
|
||||
free(v2);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
sfe(DtDtsDbRecord * item1, DtDtsDbRecord * item2)
|
||||
{
|
||||
int test1 = 0;
|
||||
int test2 = 0;
|
||||
int loc1;
|
||||
int loc2;
|
||||
char *value1, *value2;
|
||||
DtDtsDbRecord *rec;
|
||||
DtDtsDbField *fld;
|
||||
int val;
|
||||
|
||||
test1 |= get_value(item1, DtDTS_CONTENT) ? 2 : 0;
|
||||
test2 |= get_value(item2, DtDTS_CONTENT) ? 2 : 0;
|
||||
|
||||
value1 = get_value(item1, DtDTS_NAME_PATTERN);
|
||||
if (value1)
|
||||
{
|
||||
if ((strlen(value1) == 1) && (*value1 == '*'))
|
||||
{
|
||||
test1 |= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
test1 |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
value2 = get_value(item2, DtDTS_NAME_PATTERN);
|
||||
if (value2)
|
||||
{
|
||||
if ((strlen(value2) == 1) && (*value2 == '*'))
|
||||
{
|
||||
test2 |= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
test2 |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(test1 & 1))
|
||||
{
|
||||
test1 |= get_value(item1, DtDTS_PATH_PATTERN) ? 1 : 0;
|
||||
}
|
||||
if (!(test2 & 1))
|
||||
{
|
||||
test2 |= get_value(item2, DtDTS_PATH_PATTERN) ? 1 : 0;
|
||||
}
|
||||
|
||||
switch (test1)
|
||||
{
|
||||
case 0:
|
||||
loc1 = 4;
|
||||
break;
|
||||
case 1:
|
||||
loc1 = 2;
|
||||
break;
|
||||
case 2:
|
||||
loc1 = 3;
|
||||
break;
|
||||
case 3:
|
||||
loc1 = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (test2)
|
||||
{
|
||||
case 0:
|
||||
loc2 = 4;
|
||||
break;
|
||||
case 1:
|
||||
loc2 = 2;
|
||||
break;
|
||||
case 2:
|
||||
loc2 = 3;
|
||||
break;
|
||||
case 3:
|
||||
loc2 = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (loc1 - loc2)
|
||||
{
|
||||
return (loc1 - loc2);
|
||||
}
|
||||
|
||||
if (loc1 == 2) /* loc1 == loc2 */
|
||||
{
|
||||
val = check_pattern(get_value(item1, DtDTS_PATH_PATTERN),
|
||||
get_value(item2, DtDTS_PATH_PATTERN));
|
||||
if(val)
|
||||
{
|
||||
return(val);
|
||||
}
|
||||
val = check_pattern(get_value(item1, DtDTS_NAME_PATTERN),
|
||||
get_value(item2, DtDTS_NAME_PATTERN));
|
||||
if(val)
|
||||
{
|
||||
return(val);
|
||||
}
|
||||
}
|
||||
|
||||
if( loc1 == 3)
|
||||
{
|
||||
val = check_content(get_value(item1, DtDTS_CONTENT),
|
||||
get_value(item2, DtDTS_CONTENT));
|
||||
if(val)
|
||||
{
|
||||
return(val);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* neither pattern nor content, only needs to compare the
|
||||
* number of fields. If they are equal then which has shorter
|
||||
* record name will be more specific
|
||||
*/
|
||||
if (item2->fieldCount - item1->fieldCount)
|
||||
{
|
||||
return (item2->fieldCount - item1->fieldCount);
|
||||
}
|
||||
|
||||
val = mode_count(get_value(item2, DtDTS_MODE)) -
|
||||
mode_count(get_value(item1, DtDTS_MODE));
|
||||
if(val)
|
||||
{
|
||||
return(val);
|
||||
}
|
||||
|
||||
|
||||
val = strlen(XrmQuarkToString(item1->recordName)) -
|
||||
strlen(XrmQuarkToString(item2->recordName));
|
||||
if(val)
|
||||
{
|
||||
return(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(item1->recordName - item2->recordName);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cde_dc_compare(DtDtsDbRecord ** a, DtDtsDbRecord ** b)
|
||||
{
|
||||
DtDtsDbRecord **x = (DtDtsDbRecord **) a;
|
||||
DtDtsDbRecord **y = (DtDtsDbRecord **) b;
|
||||
int results;
|
||||
char c;
|
||||
|
||||
results = sfe(*x, *y);
|
||||
return(results);
|
||||
}
|
||||
|
||||
static int
|
||||
cde_ft_field_value(XrmQuark name_quark)
|
||||
{
|
||||
if (name_quark == XrmStringToQuark(DtDTS_PATH_PATTERN))
|
||||
return (1);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_NAME_PATTERN))
|
||||
return (2);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_MODE))
|
||||
return (3);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_LINK_PATH))
|
||||
return (4);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_LINK_NAME))
|
||||
return (5);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_CONTENT))
|
||||
return (6);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_DATA_ATTRIBUTES_NAME))
|
||||
return (7);
|
||||
else if (name_quark == XrmStringToQuark(DtDTS_DA_IS_SYNTHETIC))
|
||||
return (8);
|
||||
else
|
||||
return (9);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
cde_dc_field_compare(DtDtsDbField ** a, DtDtsDbField ** b)
|
||||
{
|
||||
return (cde_ft_field_value((*a)->fieldName) -
|
||||
cde_ft_field_value((*b)->fieldName));
|
||||
}
|
||||
|
||||
cde_da_compare(DtDtsDbRecord ** a, DtDtsDbRecord ** b)
|
||||
{
|
||||
int results = ((*a)->recordName) - ((*b)->recordName);
|
||||
|
||||
if (!results)
|
||||
{
|
||||
results = (*a)->seq - (*b)->seq;
|
||||
}
|
||||
return (results);
|
||||
}
|
||||
190
cde/lib/DtSvc/DtUtil1/GetMwmW.c
Normal file
190
cde/lib/DtSvc/DtUtil1/GetMwmW.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/* $XConsortium: GetMwmW.c /main/5 1996/05/20 16:07:08 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1990,1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: GetMwmW.c
|
||||
**
|
||||
** Project: DT Workspace Manager
|
||||
**
|
||||
** Description: Gets the mwm window id.
|
||||
**
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <Xm/MwmUtil.h>
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/AtomMgr.h>
|
||||
|
||||
|
||||
|
||||
/******** Public Function Declarations ********/
|
||||
|
||||
extern int _DtGetMwmWindow(
|
||||
Display *display,
|
||||
Window root,
|
||||
Window *pMwmWindow) ;
|
||||
|
||||
/******** End Public Function Declarations ********/
|
||||
|
||||
/******** Static Function Declarations ********/
|
||||
|
||||
static int _GetMwmWindow(
|
||||
Display *display,
|
||||
Window root,
|
||||
Window *pMwmWindow,
|
||||
Atom property) ;
|
||||
|
||||
/******** End Static Function Declarations ********/
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* int _GetMwmWindow (display, root, pMwmWindow, property)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Get the Motif Window manager window
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display
|
||||
* root - root window of screen
|
||||
* pMwmWindow - pointer to a window (to be returned)
|
||||
* property - the property atom
|
||||
*
|
||||
* Outputs:
|
||||
* --------
|
||||
* *pMwmWindow - mwm window id, if successful
|
||||
* Return - status from XGetWindowProperty
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* This can fail if mwm is not managing the screen for the root window
|
||||
* passed in.
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
static int
|
||||
_GetMwmWindow(
|
||||
Display *display,
|
||||
Window root,
|
||||
Window *pMwmWindow,
|
||||
Atom property )
|
||||
{
|
||||
Atom actualType;
|
||||
int actualFormat;
|
||||
unsigned long nitems;
|
||||
unsigned long leftover;
|
||||
PropMotifWmInfo *pWmInfo = NULL;
|
||||
int rcode;
|
||||
Window wroot, wparent, *pchildren;
|
||||
unsigned int nchildren;
|
||||
|
||||
*pMwmWindow = NULL;
|
||||
if ((rcode=XGetWindowProperty(display,root,
|
||||
property,0L, PROP_MWM_INFO_ELEMENTS,
|
||||
False,property,
|
||||
&actualType,&actualFormat,
|
||||
&nitems,&leftover,(unsigned char **)&pWmInfo))==Success)
|
||||
{
|
||||
|
||||
if (actualType != property)
|
||||
{
|
||||
/* wrong type, force failure */
|
||||
rcode = BadValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
rcode = BadWindow; /* assume the worst */
|
||||
|
||||
/*
|
||||
* The mwm window should be a direct child of root
|
||||
*/
|
||||
if (XQueryTree (display, root, &wroot, &wparent,
|
||||
&pchildren, &nchildren))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < nchildren) && (rcode != Success); i++)
|
||||
{
|
||||
if (pchildren[i] == pWmInfo->wmWindow)
|
||||
{
|
||||
rcode = Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rcode == Success);
|
||||
{
|
||||
*pMwmWindow = pWmInfo->wmWindow;
|
||||
}
|
||||
|
||||
if (pchildren)
|
||||
{
|
||||
XFree ((char *)pchildren);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pWmInfo)
|
||||
{
|
||||
XFree ((char *)pWmInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return(rcode);
|
||||
|
||||
} /* END OF FUNCTION _GetMwmWindow */
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* int _DtGetMwmWindow (display, root, pMwmWindow)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Get the Motif Window manager window
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display
|
||||
* root - root window of screen
|
||||
* pMwmWindow - pointer to a window (to be returned)
|
||||
*
|
||||
* Outputs:
|
||||
* --------
|
||||
* *pMwmWindow - mwm window id, if successful
|
||||
* Return - status from XGetWindowProperty
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* This can fail if mwm is not managing the screen for the root window
|
||||
* passed in.
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
int
|
||||
_DtGetMwmWindow(
|
||||
Display *display,
|
||||
Window root,
|
||||
Window *pMwmWindow )
|
||||
{
|
||||
Atom xa_MWM_INFO;
|
||||
|
||||
xa_MWM_INFO = XmInternAtom (display, _XA_MWM_INFO, False);
|
||||
return (_GetMwmWindow (display, root, pMwmWindow, xa_MWM_INFO));
|
||||
}
|
||||
167
cde/lib/DtSvc/DtUtil1/GetVWmHint.c
Normal file
167
cde/lib/DtSvc/DtUtil1/GetVWmHint.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/* $XConsortium: GetVWmHint.c /main/5 1996/05/20 16:07:19 drk $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1991,1993,1994,1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993,1994,1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: GetVwmHint.c
|
||||
**
|
||||
** Project: DT Workspace Manager
|
||||
**
|
||||
** Description: Get Dt Window manager hints
|
||||
**
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <Dt/Wsm.h>
|
||||
#include <Dt/WsmP.h>
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/AtomMgr.h>
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* int _DtWsmGetDtWmHints (display, window, ppDtWmHints)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Get the contents of the _DT_WM_HINTS property on a window
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display
|
||||
* window - window to get hints from
|
||||
* ppDtWmHints- pointer to a pointer to return
|
||||
*
|
||||
* Outputs:
|
||||
* --------
|
||||
* *ppDtWmHints-points to the DtWmHints structure retrieved from
|
||||
* the window (NOTE: This should be freed using XFree)
|
||||
*
|
||||
* Comments:
|
||||
* ---------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
int
|
||||
_DtWsmGetDtWmHints(
|
||||
Display *display,
|
||||
Window window,
|
||||
DtWmHints **ppDtWmHints)
|
||||
{
|
||||
Atom actualType;
|
||||
int actualFormat;
|
||||
unsigned long leftover, items, length;
|
||||
int rcode;
|
||||
Atom property;
|
||||
#ifdef HP_VUE
|
||||
unsigned long oldlength;
|
||||
#endif /* HP_VUE */
|
||||
|
||||
|
||||
property = XmInternAtom(display, _XA_DT_WM_HINTS, False);
|
||||
length = sizeof (DtWmHints) / sizeof (long);
|
||||
|
||||
*ppDtWmHints = NULL;
|
||||
if ((rcode=XGetWindowProperty(
|
||||
display,
|
||||
window,
|
||||
property,
|
||||
0L, /* offset */
|
||||
length,
|
||||
False, /* delete */
|
||||
property, /* req_type */
|
||||
&actualType,
|
||||
&actualFormat,
|
||||
&items, /* items returned */
|
||||
&leftover,
|
||||
(unsigned char **)ppDtWmHints))==Success)
|
||||
{
|
||||
|
||||
if ((actualType != property) || (items < length))
|
||||
{
|
||||
/* wrong type, force failure */
|
||||
rcode = BadValue;
|
||||
if (actualType != None)
|
||||
{
|
||||
XFree ((char *)*ppDtWmHints);
|
||||
}
|
||||
*ppDtWmHints = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef HP_VUE
|
||||
else {
|
||||
/*
|
||||
* Didn't get the Dt hints, try to get the Vue hints.
|
||||
* Not that the Vue hints had the same structure, just
|
||||
* under a different property name.
|
||||
*/
|
||||
property = XmInternAtom(display, _XA_VUE_WM_HINTS, False);
|
||||
/*
|
||||
* Property previously existed without attachWindow.
|
||||
*/
|
||||
oldlength = length - (sizeof(Window)/sizeof(long));
|
||||
|
||||
*ppDtWmHints = NULL;
|
||||
if ((rcode=XGetWindowProperty(
|
||||
display,
|
||||
window,
|
||||
property,
|
||||
0L, /* offset */
|
||||
length,
|
||||
False, /* delete */
|
||||
property, /* req_type */
|
||||
&actualType,
|
||||
&actualFormat,
|
||||
&items, /* items returned */
|
||||
&leftover,
|
||||
(unsigned char **)ppDtWmHints))==Success)
|
||||
{
|
||||
|
||||
if ((actualType != property) ||
|
||||
(items < oldlength))
|
||||
{
|
||||
/* wrong type, force failure */
|
||||
rcode = BadValue;
|
||||
if (actualType != None)
|
||||
{
|
||||
XFree ((char *)*ppDtWmHints);
|
||||
}
|
||||
*ppDtWmHints = NULL;
|
||||
}
|
||||
|
||||
if (*ppDtWmHints && (items < length))
|
||||
{
|
||||
DtWmHints *pvh;
|
||||
|
||||
/* assume old property, return full sized
|
||||
property with empty values */
|
||||
pvh = (DtWmHints *) malloc (length * sizeof (long));
|
||||
|
||||
pvh->flags = (*ppDtWmHints)->flags;
|
||||
pvh->functions = (*ppDtWmHints)->functions;
|
||||
pvh->behaviors = (*ppDtWmHints)->behaviors;
|
||||
pvh->attachWindow = NULL;
|
||||
|
||||
XFree ((char *) *ppDtWmHints);
|
||||
|
||||
*ppDtWmHints = pvh;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HP_VUE */
|
||||
|
||||
return(rcode);
|
||||
|
||||
} /* END OF FUNCTION _DtWsmGetDtWmHints */
|
||||
|
||||
167
cde/lib/DtSvc/DtUtil1/Imakefile
Normal file
167
cde/lib/DtSvc/DtUtil1/Imakefile
Normal file
@@ -0,0 +1,167 @@
|
||||
XCOMM $XConsortium: Imakefile /main/6 1996/08/20 14:48:27 drk $
|
||||
#define DoNormalLib NormalLibDtSvc
|
||||
#define DoSharedLib SharedLibDtSvc
|
||||
#define DoDebugLib DebugLibDtSvc
|
||||
#define DoProfileLib ProfileLibDtSvc
|
||||
#define LibName DtSvc
|
||||
#define SoRev SODTSVCREV
|
||||
#define IncSubdir Dt
|
||||
#define LibCreate NO
|
||||
#define LargePICTable YES
|
||||
|
||||
#include <Threads.tmpl>
|
||||
|
||||
#ifndef DtSvcDefines
|
||||
# define DtSvcDefines -DXK_MISCELLANY -DMULTIBYTE
|
||||
#endif
|
||||
DEFINES = DtSvcDefines \
|
||||
-DCDE_INSTALLATION_TOP=\"$(CDE_INSTALLATION_TOP)\" \
|
||||
-DCDE_CONFIGURATION_TOP=\"$(CDE_CONFIGURATION_TOP)\"
|
||||
INCLUDES = -I. -I../include
|
||||
|
||||
|
||||
HEADERS = \
|
||||
Action.h \
|
||||
ActionDb.h \
|
||||
ActionDbP.h \
|
||||
ActionP.h \
|
||||
ActionFind.h \
|
||||
ActionUtilP.h \
|
||||
CmdInv.h \
|
||||
CmdInvP.h \
|
||||
DbReader.h \
|
||||
DbUtil.h \
|
||||
Dnd.h \
|
||||
DndP.h \
|
||||
DndIconI.h \
|
||||
Dt.h \
|
||||
Dts.h \
|
||||
DtsDb.h \
|
||||
DtsMM.h \
|
||||
DtHash.h \
|
||||
DtShmDb.h \
|
||||
Qualify.h \
|
||||
Saver.h \
|
||||
SaverP.h \
|
||||
Session.h \
|
||||
SessionM.h \
|
||||
SessionP.h \
|
||||
Wsm.h \
|
||||
WsmM.h \
|
||||
WsmP.h
|
||||
|
||||
|
||||
SRCS = \
|
||||
Action.c \
|
||||
ActionTt.c \
|
||||
ActionDb.c \
|
||||
ActionFind.c \
|
||||
ActionUtil.c \
|
||||
DbReader.c \
|
||||
DbUtil.c \
|
||||
CmdSpc.c \
|
||||
CmdMain.c \
|
||||
CmdProcess.c \
|
||||
CmdUtilityP.c \
|
||||
Dnd.c \
|
||||
DndDrag.c \
|
||||
DndDrop.c \
|
||||
DndIcon.c \
|
||||
DndBuff.c \
|
||||
DndFile.c \
|
||||
DndText.c \
|
||||
Dt.c \
|
||||
Dts.c \
|
||||
DtsDb.c \
|
||||
DtsSort.c \
|
||||
DbLoad.c \
|
||||
DtsInit.c \
|
||||
DtHash.c \
|
||||
intarray.c \
|
||||
inttab.c \
|
||||
strtab.c \
|
||||
DtsMM.c \
|
||||
MMDb.c \
|
||||
GetVWmHint.c \
|
||||
GetMwmW.c \
|
||||
Qualify.c \
|
||||
Saver.c \
|
||||
SetVWmHint.c \
|
||||
SmComm.c \
|
||||
SmUtil.c \
|
||||
WmAddDelWs.c \
|
||||
WmBackWin.c \
|
||||
WmChBackD.c \
|
||||
WmGWsInfo.c \
|
||||
WmGWsList.c \
|
||||
WmMarquee.c \
|
||||
WmRestart.c \
|
||||
WmRmWsFcn.c \
|
||||
WmSetTitle.c \
|
||||
WmWsCallB.c \
|
||||
WmSetWs.c \
|
||||
WmWsHints.c \
|
||||
WmWsOccupy.c
|
||||
|
||||
|
||||
/* WARNING!!!!
|
||||
* Any .o's added to this list need to be added to DTUTIL1_OBJS1
|
||||
* and SHARED_DTUTIL1_OBJS1 in the DtSvc Imakefile.
|
||||
*/
|
||||
OBJS = \
|
||||
Action.o \
|
||||
ActionTt.o \
|
||||
ActionDb.o \
|
||||
ActionFind.o \
|
||||
ActionUtil.o \
|
||||
DbReader.o \
|
||||
DbUtil.o \
|
||||
CmdSpc.o \
|
||||
CmdMain.o \
|
||||
CmdProcess.o \
|
||||
CmdUtilityP.o \
|
||||
Dnd.o \
|
||||
DndDrag.o \
|
||||
DndDrop.o \
|
||||
DndIcon.o \
|
||||
DndBuff.o \
|
||||
DndFile.o \
|
||||
DndText.o \
|
||||
Dt.o \
|
||||
Dts.o \
|
||||
DtsDb.o \
|
||||
DtsSort.o \
|
||||
DbLoad.o \
|
||||
DtsInit.o \
|
||||
DtHash.o \
|
||||
intarray.o \
|
||||
inttab.o \
|
||||
strtab.o \
|
||||
DtsMM.o \
|
||||
MMDb.o \
|
||||
GetVWmHint.o \
|
||||
GetMwmW.o \
|
||||
Qualify.o \
|
||||
Saver.o \
|
||||
SetVWmHint.o \
|
||||
SmComm.o \
|
||||
SmUtil.o \
|
||||
WmAddDelWs.o \
|
||||
WmBackWin.o \
|
||||
WmChBackD.o \
|
||||
WmGWsInfo.o \
|
||||
WmGWsList.o \
|
||||
WmMarquee.o \
|
||||
WmRestart.o \
|
||||
WmRmWsFcn.o\
|
||||
WmSetTitle.o \
|
||||
WmWsCallB.o \
|
||||
WmSetWs.o \
|
||||
WmWsHints.o \
|
||||
WmWsOccupy.o
|
||||
|
||||
#include <Library.tmpl>
|
||||
|
||||
SubdirLibraryRule($(OBJS))
|
||||
|
||||
DependTarget()
|
||||
717
cde/lib/DtSvc/DtUtil1/MMDb.c
Normal file
717
cde/lib/DtSvc/DtUtil1/MMDb.c
Normal file
@@ -0,0 +1,717 @@
|
||||
/* $TOG: MMDb.c /main/19 1998/10/23 13:48:52 mgreess $ */
|
||||
/*
|
||||
* +SNOTICE
|
||||
*
|
||||
* Copyright 1995 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* +ENOTICE
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NLS16
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
|
||||
#define X_INCLUDE_DIRENT_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <Dt/DbReader.h>
|
||||
#include <Dt/DtsDb.h>
|
||||
#include <Dt/DtsMM.h>
|
||||
#include <Dt/DtShmDb.h>
|
||||
#include <Dt/Dts.h>
|
||||
#include <Dt/ActionP.h>
|
||||
#include <Dt/ActionDbP.h>
|
||||
#include <Dt/ActionUtilP.h>
|
||||
#include <Dt/DtNlUtils.h>
|
||||
#include <Dt/UserMsg.h>
|
||||
#include "myassertP.h"
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
static void build_file_list(DtShmProtoIntList, DtDirPaths *,
|
||||
DtDtsMMHeader *, const char *);
|
||||
extern int cde_dc_field_compare(DtDtsDbField **, DtDtsDbField **);
|
||||
extern int cde_dc_compare(DtDtsDbRecord **, DtDtsDbRecord **);
|
||||
static void _DtMMSortDataTypes(DtShmProtoStrtab str_handle);
|
||||
static void _DtMMAddActionsToDataAttribute(DtDtsDbDatabase *db_ptr);
|
||||
static int write_db(DtDtsMMHeader *header, void *index, int size,
|
||||
const char *CacheFile);
|
||||
static int build_new_db(DtShmProtoStrtab, DtShmProtoIntList, int, DtDtsDbDatabase **);
|
||||
static int build_name_list(DtDtsDbDatabase *, DtShmProtoIntList, DtDtsMMHeader *);
|
||||
|
||||
static DtShmProtoStrtab shm_handle = 0;
|
||||
static DtShmProtoIntList int_handle = 0;
|
||||
|
||||
#define QtB(a) _DtShmProtoAddStrtab(shm_handle, XrmQuarkToString(a), &isnew)
|
||||
|
||||
int
|
||||
_MMWriteDb(DtDirPaths *dirs, int num_db, DtDtsDbDatabase **db_list,
|
||||
const char *CacheFile)
|
||||
{
|
||||
DtDtsMMHeader header;
|
||||
char *suffix = ".dt";
|
||||
int tbl_size;
|
||||
void *tbl_data;
|
||||
DtDtsDbDatabase *db;
|
||||
int returnCode;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
memset(&header, '\0', sizeof(header));
|
||||
int_handle = _DtShmProtoInitIntLst(50000);
|
||||
shm_handle = _DtShmProtoInitStrtab(10000);
|
||||
|
||||
build_file_list(int_handle, dirs, &header, suffix);
|
||||
|
||||
_DtMMSortDataTypes(shm_handle);
|
||||
db = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DA_NAME);
|
||||
_DtMMAddActionsToDataAttribute(db);
|
||||
|
||||
header.pathhash = _DtDtsMMPathHash(dirs);
|
||||
header.num_db = num_db;
|
||||
header.db_offset = build_new_db(shm_handle, int_handle, num_db,
|
||||
db_list);
|
||||
db = (DtDtsDbDatabase *) _DtDtsDbGet("DATA_CRITERIA");
|
||||
build_name_list(db, int_handle, &header);
|
||||
|
||||
tbl_size = _DtShmProtoSizeStrtab(shm_handle);
|
||||
tbl_data = (void *) _DtShmProtoAddIntLst(int_handle,
|
||||
tbl_size/sizeof(int), &header.str_tbl_offset);
|
||||
_DtShmProtoCopyStrtab(shm_handle, tbl_data);
|
||||
|
||||
|
||||
tbl_size = _DtShmProtoSizeIntLst(int_handle);
|
||||
tbl_data = (void *)malloc(tbl_size);
|
||||
memset(tbl_data, '\0', tbl_size);
|
||||
tbl_data = (void *)_DtShmProtoCopyIntLst(int_handle, tbl_data);
|
||||
|
||||
returnCode = write_db(&header, tbl_data, tbl_size, CacheFile);
|
||||
_DtShmProtoDestroyStrtab(shm_handle);
|
||||
_DtShmProtoDestroyIntLst(int_handle);
|
||||
_DtSvcProcessUnlock();
|
||||
free(tbl_data);
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
static void
|
||||
build_file_list(DtShmProtoIntList int_handle, DtDirPaths *dirs,
|
||||
DtDtsMMHeader *header, const char *suffix)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp = NULL;
|
||||
struct stat buf;
|
||||
char cur_path[MAXPATHLEN+1];
|
||||
void *data;
|
||||
int size = sizeof(buf.st_mtime);
|
||||
int i;
|
||||
int isnew;
|
||||
DtShmBoson *boson_list = 0;
|
||||
time_t *mtime_list = 0;
|
||||
int count = 0;
|
||||
_Xreaddirparams dirEntryBuf;
|
||||
struct dirent *result;
|
||||
|
||||
/* Theses here to make sure it gets into the string tables
|
||||
because actions uses it in its "types" field. */
|
||||
_DtShmProtoAddStrtab(shm_handle, DtDTS_DT_UNKNOWN, &isnew);
|
||||
_DtShmProtoAddStrtab(shm_handle, DtDTS_DT_RECURSIVE_LINK, &isnew);
|
||||
_DtShmProtoAddStrtab(shm_handle, DtDTS_DT_BROKEN_LINK, &isnew);
|
||||
|
||||
getcwd(cur_path, sizeof(cur_path));
|
||||
for(i = 0; dirs->paths[i]; i++)
|
||||
{
|
||||
chdir(dirs->paths[i]);
|
||||
stat(".", &buf);
|
||||
count++;
|
||||
boson_list = (int *)realloc(boson_list, count*sizeof(int));
|
||||
mtime_list = (time_t *)realloc(mtime_list, count*sizeof(time_t));
|
||||
|
||||
mtime_list[count-1] = buf.st_mtime;
|
||||
boson_list[count-1] = _DtShmProtoAddStrtab(shm_handle, dirs->paths[i], &isnew);
|
||||
dirp = opendir(".");
|
||||
while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL)
|
||||
{
|
||||
char *c = strrchr(result->d_name, suffix[0]);
|
||||
if(c && strcmp(c, suffix) == 0)
|
||||
{
|
||||
char *pathname = malloc(MAXPATHLEN+1);
|
||||
sprintf(pathname, "%s/%s", dirs->paths[i], result->d_name);
|
||||
stat(result->d_name, &buf);
|
||||
count++;
|
||||
boson_list = (int *)realloc(boson_list, count*sizeof(int));
|
||||
mtime_list = (time_t *)realloc(mtime_list, count*sizeof(time_t));
|
||||
mtime_list[count-1] = buf.st_mtime;
|
||||
boson_list[count-1] = _DtShmProtoAddStrtab(shm_handle,
|
||||
pathname, &isnew);
|
||||
if (pathname) free(pathname);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
(void)closedir( dirp );
|
||||
}
|
||||
chdir(cur_path);
|
||||
data = _DtShmProtoAddIntLst(int_handle, count, &header->files_offset);
|
||||
memcpy(data, boson_list, count*sizeof(int));
|
||||
data = _DtShmProtoAddIntLst(int_handle, count*sizeof(time_t)/sizeof(int), &header->mtimes_offset);
|
||||
memcpy(data, mtime_list, count*sizeof(time_t));
|
||||
header->files_count = count;
|
||||
if(boson_list)free(boson_list);
|
||||
if(mtime_list)free(mtime_list);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
db_table_size(int num_db, DtDtsDbDatabase **db_list)
|
||||
{
|
||||
int db;
|
||||
DtDtsDbDatabase *db_ptr;
|
||||
int rec;
|
||||
DtDtsDbRecord *rec_ptr;
|
||||
int fld;
|
||||
DtDtsDbField *fld_ptr;
|
||||
int size = 0;
|
||||
|
||||
size += num_db*sizeof(DtDtsMMDatabase);
|
||||
for(db = 0; db < num_db; db++)
|
||||
{
|
||||
db_ptr = db_list[db];
|
||||
size += db_ptr->recordCount * sizeof(DtDtsMMRecord);
|
||||
for(rec = 0; rec < db_ptr->recordCount; rec++)
|
||||
{
|
||||
rec_ptr = db_ptr->recordList[rec];
|
||||
size += rec_ptr->fieldCount * sizeof(DtDtsMMField);
|
||||
}
|
||||
}
|
||||
return(size/sizeof(int));
|
||||
}
|
||||
static void
|
||||
_DtMMSortDataTypes(DtShmProtoStrtab str_handle)
|
||||
{
|
||||
DtDtsDbDatabase *dc;
|
||||
DtDtsDbDatabase *da;
|
||||
int i;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
dc = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DC_NAME);
|
||||
da = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DA_NAME);
|
||||
|
||||
/*_DtDtsDbPrintRecords(dc, stdout);*/
|
||||
for(i = 0; i < dc->recordCount; i++)
|
||||
{
|
||||
if(dc->recordList[i]->compare != cde_dc_field_compare)
|
||||
{
|
||||
_DtDtsDbFieldSort(dc->recordList[i],
|
||||
cde_dc_field_compare);
|
||||
}
|
||||
}
|
||||
_DtDtsDbRecordSort(dc, cde_dc_compare);
|
||||
|
||||
for(i = 0; i < da->recordCount; i++)
|
||||
{
|
||||
if(da->recordList[i]->compare !=
|
||||
_DtDtsDbCompareFieldNames)
|
||||
{
|
||||
_DtDtsDbFieldSort(da->recordList[i],
|
||||
_DtDtsDbCompareFieldNames);
|
||||
}
|
||||
}
|
||||
|
||||
_DtDtsDbRecordSort(da, _DtDtsDbCompareRecordNames);
|
||||
/*_DtDtsDbPrintRecords(dc, stdout);*/
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
|
||||
static void
|
||||
add_if_missing(DtDtsDbRecord *rec_ptr, XrmQuark name, char *value)
|
||||
{
|
||||
DtDtsDbField *fld_ptr;
|
||||
int fld;
|
||||
int found = 0;
|
||||
|
||||
for(fld = 0; fld < rec_ptr->fieldCount; fld++)
|
||||
{
|
||||
fld_ptr = rec_ptr->fieldList[fld];
|
||||
if(name == fld_ptr->fieldName)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fld_ptr = _DtDtsDbAddField(rec_ptr);
|
||||
fld_ptr->fieldName = name;
|
||||
fld_ptr->fieldValue = value;
|
||||
_DtDtsDbFieldSort(rec_ptr, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
_DtMMAddActionsToDataAttribute(DtDtsDbDatabase *db_ptr)
|
||||
{
|
||||
int rec;
|
||||
DtDtsDbRecord *rec_ptr;
|
||||
int action_flag = 0;
|
||||
int sort_flag = 0;
|
||||
int found_flag = 0;
|
||||
int n;
|
||||
const char *tmp;
|
||||
XrmQuark desc_qrk = XrmStringToQuark(DtDTS_DA_DESCRIPTION);
|
||||
XrmQuark icon_qrk = XrmStringToQuark(DtDTS_DA_ICON);
|
||||
XrmQuark label_qrk = XrmStringToQuark(DtDTS_DA_LABEL);
|
||||
|
||||
for(rec = 0; rec < db_ptr->recordCount; rec++)
|
||||
{
|
||||
int found_des = 0;
|
||||
int found_icon = 0;
|
||||
int found_label = 0;
|
||||
char *obj_type;
|
||||
|
||||
rec_ptr = db_ptr->recordList[rec];
|
||||
obj_type = XrmQuarkToString(rec_ptr->recordName);
|
||||
|
||||
if ( _DtDtsDbGetFieldByName(rec_ptr,
|
||||
DtDTS_DA_IS_ACTION) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
add_if_missing(rec_ptr, desc_qrk,
|
||||
DtActionDescription(obj_type));
|
||||
add_if_missing(rec_ptr, icon_qrk, DtActionIcon(obj_type));
|
||||
add_if_missing(rec_ptr, label_qrk, DtActionLabel(obj_type));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
build_new_db(DtShmProtoStrtab shm_handle, DtShmProtoIntList int_handle, int num_db, DtDtsDbDatabase **db_list)
|
||||
{
|
||||
DtDtsMMDatabase *new_db_list;
|
||||
int db;
|
||||
DtDtsDbDatabase *db_ptr;
|
||||
DtDtsMMDatabase *new_db_ptr;
|
||||
int rec;
|
||||
DtDtsDbRecord *rec_ptr;
|
||||
DtDtsMMRecord *new_rec_ptr;
|
||||
DtDtsMMRecord *new_rec_ptr_list;
|
||||
int fld;
|
||||
DtDtsDbField *fld_ptr;
|
||||
DtDtsMMField *new_fld_ptr;
|
||||
DtDtsMMField *new_fld_ptr_list;
|
||||
int index;
|
||||
int db_index;
|
||||
int isnew;
|
||||
char *tmp;
|
||||
|
||||
/* create a space to hold the list of database structures */
|
||||
new_db_list = (DtDtsMMDatabase *)_DtShmProtoAddIntLst(int_handle,
|
||||
num_db*sizeof(DtDtsMMDatabase)/sizeof(int),
|
||||
&db_index);
|
||||
for(db = 0; db < num_db; db++)
|
||||
{
|
||||
int last_boson = -1;
|
||||
int list_count = 0;
|
||||
DtShmProtoInttab nameIndex;
|
||||
int size;
|
||||
int *idx;
|
||||
|
||||
new_db_ptr = &new_db_list[db];
|
||||
db_ptr = db_list[db];
|
||||
|
||||
new_db_ptr->databaseName = _DtShmProtoAddStrtab(shm_handle, db_ptr->databaseName, &isnew);
|
||||
new_db_ptr->recordCount = db_ptr->recordCount;
|
||||
/* create space to hold record list */
|
||||
new_rec_ptr_list = (DtDtsMMRecord *)_DtShmProtoAddIntLst(int_handle,
|
||||
db_ptr->recordCount*sizeof(DtDtsMMRecord)/sizeof(int),
|
||||
&index);
|
||||
|
||||
new_db_ptr->recordList = index;
|
||||
/* create index to names list */
|
||||
nameIndex = _DtShmProtoInitInttab(db_ptr->recordCount);
|
||||
for(rec = 0; rec < db_ptr->recordCount; rec++)
|
||||
{
|
||||
new_rec_ptr = &new_rec_ptr_list[rec];
|
||||
rec_ptr = db_ptr->recordList[rec];
|
||||
new_rec_ptr->recordName = QtB(rec_ptr->recordName);
|
||||
|
||||
if(new_rec_ptr->recordName != last_boson)
|
||||
{
|
||||
/* save name position */
|
||||
_DtShmProtoAddInttab(nameIndex, new_rec_ptr->recordName, rec);
|
||||
|
||||
last_boson = new_rec_ptr->recordName;
|
||||
}
|
||||
new_rec_ptr->pathId = _DtShmProtoAddStrtab(shm_handle,
|
||||
tmp = _DtDbPathIdToString(rec_ptr->pathId),
|
||||
&isnew);
|
||||
XtFree(tmp);
|
||||
new_rec_ptr->seq = rec_ptr->seq;
|
||||
new_rec_ptr->fieldCount = rec_ptr->fieldCount;
|
||||
|
||||
/* create space for field list */
|
||||
new_fld_ptr_list = (DtDtsMMField *)_DtShmProtoAddIntLst(int_handle,
|
||||
rec_ptr->fieldCount*sizeof(DtDtsMMField)/sizeof(int),
|
||||
&index);
|
||||
|
||||
new_rec_ptr->fieldList = index;
|
||||
for(fld = 0; fld < rec_ptr->fieldCount; fld++)
|
||||
{
|
||||
new_fld_ptr = &new_fld_ptr_list[fld];
|
||||
fld_ptr = rec_ptr->fieldList[fld];
|
||||
|
||||
new_fld_ptr->fieldName = QtB(fld_ptr->fieldName);
|
||||
new_fld_ptr->fieldValue = fld_ptr->fieldValue?_DtShmProtoAddStrtab(shm_handle,
|
||||
fld_ptr->fieldValue, &isnew):0;
|
||||
}
|
||||
}
|
||||
/* create table for index and save it */
|
||||
size = _DtShmProtoSizeInttab(nameIndex);
|
||||
idx = _DtShmProtoAddIntLst(int_handle, size/sizeof(int), &new_db_ptr->nameIndex);
|
||||
_DtShmProtoCopyInttab(nameIndex, (void *)idx);
|
||||
_DtShmProtoDestroyInttab(nameIndex);
|
||||
}
|
||||
return(db_index);
|
||||
}
|
||||
|
||||
struct list
|
||||
{
|
||||
DtShmBoson boson;
|
||||
int rec;
|
||||
};
|
||||
|
||||
static int
|
||||
srch(const void *a, const void *b)
|
||||
{
|
||||
int results = ((struct list *)a)->boson - ((struct list *)b)->boson;
|
||||
|
||||
if(results == 0)
|
||||
{
|
||||
results = ((struct list *)a)->rec - ((struct list *)b)->rec;
|
||||
}
|
||||
return(results);
|
||||
}
|
||||
|
||||
static void
|
||||
showtable(
|
||||
DtDtsDbDatabase *db,
|
||||
struct list *name_index,
|
||||
struct list *other,
|
||||
DtDtsMMHeader *head,
|
||||
int other_break)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("============== names =====================\n");
|
||||
for(i = 0; name_index[i].boson; i++)
|
||||
{
|
||||
printf("%20s -> %s\n",
|
||||
XrmQuarkToString(db->recordList[name_index[i].rec]->recordName),
|
||||
_DtShmProtoLookUpStrtab(shm_handle,
|
||||
name_index[i].boson));
|
||||
}
|
||||
printf("%d entries\n", i);
|
||||
|
||||
printf("============= other ======================\n");
|
||||
for(i = 0; i < other_break; i++)
|
||||
{
|
||||
printf("%s\n",
|
||||
XrmQuarkToString(db->recordList[other[i].rec]->recordName));
|
||||
}
|
||||
printf("%d entries\n", i);
|
||||
}
|
||||
|
||||
static int
|
||||
build_name_list(DtDtsDbDatabase *db,
|
||||
DtShmProtoIntList int_handle,
|
||||
DtDtsMMHeader *head)
|
||||
{
|
||||
struct list *other;
|
||||
int i;
|
||||
char *c;
|
||||
int isnew;
|
||||
struct list *name_index;
|
||||
int next = 0;
|
||||
int other_break = 0;
|
||||
DtShmProtoInttab indexList = 0;
|
||||
DtShmBoson last_boson = -1;
|
||||
int *list_of_recs = 0;
|
||||
int list_count = 0;
|
||||
int index = 0;
|
||||
int size;
|
||||
void *space;
|
||||
|
||||
/* create tmp space for two lists */
|
||||
name_index = (struct list *)calloc(db->recordCount*2,
|
||||
sizeof(struct list));
|
||||
other = (struct list *)calloc(db->recordCount, sizeof(struct list));
|
||||
|
||||
/* step through all records */
|
||||
for(i = 0; i < db->recordCount; i++)
|
||||
{
|
||||
DtShmBoson boson;
|
||||
char *attr;
|
||||
char *t;
|
||||
|
||||
/* see if a name pattern exist */
|
||||
attr = _DtDtsDbGetFieldByName(db->recordList[i],
|
||||
DtDTS_NAME_PATTERN);
|
||||
if(!attr)
|
||||
{
|
||||
/* it didn't so check path pattern */
|
||||
attr = _DtDtsDbGetFieldByName(db->recordList[i],
|
||||
DtDTS_PATH_PATTERN);
|
||||
if(!attr)
|
||||
{
|
||||
/* neither exist so save it as plain buffer */
|
||||
if(!head->buffer_start_index)
|
||||
{
|
||||
head->buffer_start_index = other_break;
|
||||
}
|
||||
other[other_break++].rec = i;
|
||||
continue; /* go to next record */
|
||||
}
|
||||
}
|
||||
|
||||
/* we have a name now find its final component */
|
||||
c = strrchr(attr, '/');
|
||||
if(c)
|
||||
{
|
||||
c++;
|
||||
}
|
||||
if(!c)
|
||||
{
|
||||
c = attr;
|
||||
}
|
||||
else
|
||||
{
|
||||
attr = c;
|
||||
}
|
||||
|
||||
/* now see if that final component has any *,?,[ */
|
||||
while(c && *c &&
|
||||
!(*c == '*' ||
|
||||
*c == '[' ||
|
||||
*c == '?' ||
|
||||
*c == '$' ))
|
||||
{
|
||||
c++;
|
||||
}
|
||||
|
||||
|
||||
if(c && *c == '\0')
|
||||
{
|
||||
/* it doesn't so save it in the name index */
|
||||
name_index[next].boson =
|
||||
_DtShmProtoAddStrtab(shm_handle,
|
||||
(const char *)attr, &isnew);
|
||||
name_index[next++].rec = i;
|
||||
continue; /* next record */
|
||||
}
|
||||
|
||||
/* the name had something in it now lets get the suffix */
|
||||
c = strrchr(attr, '.');
|
||||
attr = c;
|
||||
|
||||
/* lets see if the suffix has any *,?,[ */
|
||||
while(c && *c &&
|
||||
!(*c == '*' ||
|
||||
*c == '[' ||
|
||||
*c == '?' ||
|
||||
*c == '$' ))
|
||||
{
|
||||
c++;
|
||||
}
|
||||
if(c && *c == '\0')
|
||||
{
|
||||
/* it doesn't so save it in the name index */
|
||||
name_index[next].boson =
|
||||
_DtShmProtoAddStrtab(shm_handle,
|
||||
(const char *)attr, &isnew);
|
||||
name_index[next++].rec = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* couldn't find any thing so save it as other */
|
||||
other[other_break++].rec = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (next > 0)
|
||||
{
|
||||
qsort(name_index, next, sizeof(struct list), srch);
|
||||
}
|
||||
|
||||
/*
|
||||
showtable(db, name_index, other, head, other_break);
|
||||
printf(" next = %d\n", next);
|
||||
printf(" other_break = %d\n", other_break);
|
||||
printf("head->buffer_start_index = %d\n", head->buffer_start_index);
|
||||
*/
|
||||
/* create a table and add the records to it. However
|
||||
duplicates need to be in separate lists.
|
||||
*/
|
||||
indexList = _DtShmProtoInitInttab(next+3);
|
||||
for(i = 0; i <= next; i++)
|
||||
{
|
||||
if(i != next && (last_boson == -1 || name_index[i].boson == last_boson))
|
||||
{
|
||||
/* this a new list of records or an addition to one */
|
||||
list_of_recs = (int *)realloc(list_of_recs,
|
||||
++list_count*sizeof(int));
|
||||
last_boson = name_index[i].boson;
|
||||
list_of_recs[list_count-1] = name_index[i].rec;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we reached the end of a list now we check how many
|
||||
are in the list.
|
||||
*/
|
||||
if(list_count == 1)
|
||||
{
|
||||
/* if just one just add it in the index */
|
||||
_DtShmProtoAddInttab(indexList,
|
||||
last_boson, list_of_recs[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if there are multiple items in the list
|
||||
create a table for them */
|
||||
int *list = _DtShmProtoAddIntLst(int_handle,
|
||||
list_count, &index);
|
||||
|
||||
/* write the list to the to the table */
|
||||
memcpy(list, list_of_recs,
|
||||
list_count*sizeof(int));
|
||||
|
||||
/* then index on the negative of the boson
|
||||
so that we know it is a list */
|
||||
_DtShmProtoAddInttab(indexList,
|
||||
last_boson, -index);
|
||||
list_count = 0;
|
||||
list_of_recs = (int *)realloc(list_of_recs,
|
||||
++list_count*sizeof(int));
|
||||
}
|
||||
if ( i != next )
|
||||
{
|
||||
/* reset for the next set */
|
||||
last_boson = name_index[i].boson;
|
||||
list_of_recs[list_count-1] = name_index[i].rec;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* same thing but they all go into a separate list */
|
||||
if(other_break > 0)
|
||||
{
|
||||
/* create the space */
|
||||
int *list = _DtShmProtoAddIntLst(int_handle,
|
||||
other_break, &head->no_name_offset);
|
||||
|
||||
/* copy it into the list */
|
||||
for(i = 0; i < other_break; i++)
|
||||
{
|
||||
list[i] = other[i].rec;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
head->no_name_offset = -1;
|
||||
}
|
||||
|
||||
/* make the real space */
|
||||
size = _DtShmProtoSizeInttab(indexList);
|
||||
space = _DtShmProtoAddIntLst(int_handle, size/sizeof(int),
|
||||
&head->name_list_offset);
|
||||
_DtShmProtoCopyInttab(indexList, space);
|
||||
_DtShmProtoDestroyInttab(indexList);
|
||||
if(name_index)free(name_index);
|
||||
if(list_of_recs)free(list_of_recs);
|
||||
if(other)free(other);
|
||||
return(index);
|
||||
}
|
||||
|
||||
static int
|
||||
write_db(DtDtsMMHeader *header, void *index, int size, const char *CacheFile)
|
||||
{
|
||||
int fd;
|
||||
mode_t cmask = umask((mode_t)077);
|
||||
char *tmpfile;
|
||||
/* tempnam(3) is affected by the TMPDIR environment variable. */
|
||||
/* This creates problems for rename() is "tmpfile" and "cacheFile" */
|
||||
/* are on different file systems. Use tmpnam(3) to create the */
|
||||
/* unique file name instead. */
|
||||
char tmpnam_buf[L_tmpnam + 1];
|
||||
|
||||
tmpfile = (char *)malloc(sizeof(_DTDTSMMTEMPDIR) +
|
||||
sizeof(_DTDTSMMTEMPFILE) + L_tmpnam + 3);
|
||||
tmpnam(tmpnam_buf);
|
||||
sprintf(tmpfile, "%s/%s%s", _DTDTSMMTEMPDIR, _DTDTSMMTEMPFILE,
|
||||
basename(tmpnam_buf));
|
||||
|
||||
fd = open(tmpfile, O_RDWR|O_CREAT, 0600);
|
||||
umask(cmask);
|
||||
|
||||
if(fd == -1)
|
||||
{
|
||||
_DtSimpleError(
|
||||
DtProgName, DtError, NULL,
|
||||
(char*) tmpfile, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Remove file on write failure - we don't */
|
||||
/* want a partial dtdbcache file. */
|
||||
if ((write(fd, header, sizeof(DtDtsMMHeader))
|
||||
!= sizeof(DtDtsMMHeader)) ||
|
||||
(write(fd, index, size) != size))
|
||||
{
|
||||
close(fd);
|
||||
unlink(tmpfile);
|
||||
free(tmpfile);
|
||||
return(0);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
if(rename((const char *)tmpfile, CacheFile) == -1)
|
||||
{
|
||||
_DtSimpleError(
|
||||
DtProgName, DtError, NULL,
|
||||
(char*) CacheFile, NULL);
|
||||
unlink(CacheFile); /* Just in case? */
|
||||
unlink(tmpfile);
|
||||
free(tmpfile);
|
||||
return(0);
|
||||
}
|
||||
free(tmpfile);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
_DtActionCompareRecordBoson(
|
||||
DtDtsMMRecord *record1,
|
||||
DtDtsMMRecord *record2 )
|
||||
{
|
||||
int results = (int)record1->recordName - (int)record2->recordName;
|
||||
|
||||
if (results)
|
||||
return(results);
|
||||
|
||||
return((int)record1 - (int)record2);
|
||||
}
|
||||
92
cde/lib/DtSvc/DtUtil1/Qualify.c
Normal file
92
cde/lib/DtSvc/DtUtil1/Qualify.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: Qualify.c
|
||||
**
|
||||
** RCS: $XConsortium: Qualify.c /main/3 1995/10/26 15:09:47 rswiston $
|
||||
**
|
||||
** Project: DT
|
||||
**
|
||||
** Description: Fully qualify a file with the first path found
|
||||
** in a list of colon-separated paths
|
||||
**
|
||||
** (c) Copyright 1993 by Hewlett-Packard Company
|
||||
**
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*********************************************************************
|
||||
* _DtQualifyWithFirst
|
||||
*
|
||||
* takes: an unqualified filename like foo.txt, and
|
||||
* a colon-separated list of pathnames, such as
|
||||
* /etc/dt:/usr/dt/config
|
||||
*
|
||||
* returns: a fully qualified filename. Space for the filename
|
||||
* has been allocated off the heap using malloc. It is
|
||||
* the responsibility of the calling function to dispose
|
||||
* of the space using free.
|
||||
*
|
||||
* example: ...
|
||||
* char * filename;
|
||||
* ...
|
||||
* filename = _DtQualifyWithFirst("configFile",
|
||||
* "/foo/first/location:/foo/second/choice");
|
||||
* < use filename >
|
||||
* free(filename);
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
char * _DtQualifyWithFirst
|
||||
(
|
||||
char * filename,
|
||||
char * searchPath
|
||||
)
|
||||
{
|
||||
char * paths = searchPath;
|
||||
char * path;
|
||||
char * chance;
|
||||
FILE * f;
|
||||
|
||||
/* assert that the arguments cannot be NULL and cannot be empty */
|
||||
|
||||
if (filename == NULL || searchPath == NULL ||
|
||||
filename[0] == 0 || searchPath[0] == 0)
|
||||
return NULL;
|
||||
|
||||
while (1) {
|
||||
|
||||
/* if there is a :, zero it */
|
||||
|
||||
if ((path = strchr(paths, ':')) != NULL)
|
||||
*path = 0;
|
||||
|
||||
/* allocate space and create the qualified filename */
|
||||
|
||||
chance = (char *)malloc(strlen(paths) + strlen(filename) + 2);
|
||||
if (filename[0] == '/')
|
||||
sprintf(chance,"%s%s",paths,filename);
|
||||
else
|
||||
sprintf(chance,"%s/%s",paths,filename);
|
||||
|
||||
/* see if it is there by opening it for reading */
|
||||
|
||||
if (f = fopen(chance,"r")) {
|
||||
fclose(f); /* it's there so close it, .... */
|
||||
if (path) /* ... restore the colon, .... */
|
||||
*path = ':';
|
||||
return chance; /* return the fully qualified filename */
|
||||
}
|
||||
|
||||
free(chance);
|
||||
if (path == NULL) /* reached the end of the list of paths */
|
||||
break;
|
||||
*path = ':'; /* restore the colon */
|
||||
paths = path + 1; /* try the next path */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
56
cde/lib/DtSvc/DtUtil1/Qualify.h
Normal file
56
cde/lib/DtSvc/DtUtil1/Qualify.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File: Qualify.h
|
||||
* RCS: $XConsortium: Qualify.h /main/3 1995/10/26 15:10:03 rswiston $
|
||||
* Description: Public header file for the Qualify routine
|
||||
* Project: DT Runtime Library
|
||||
* Language: C
|
||||
* Package: N/A
|
||||
*
|
||||
* (c) Copyright 1993 by Hewlett-Packard Company
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* _DtQualifyWithFirst
|
||||
*
|
||||
* takes: an unqualified filename like foo.txt, and
|
||||
* a colon-separated list of pathnames, such as
|
||||
* /etc/dt:/usr/dt/config
|
||||
*
|
||||
* returns: a fully qualified filename. Space for the filename
|
||||
* has been allocated off the heap using malloc. It is
|
||||
* the responsibility of the calling function to dispose
|
||||
* of the space using free.
|
||||
*
|
||||
* example: ...
|
||||
* char * filename;
|
||||
* ...
|
||||
* filename = _DtQualifyWithFirst("configFile",
|
||||
* "/foo/first/location:/foo/second/choice");
|
||||
* < use filename >
|
||||
* free(filename);
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _Dt_Qualify_h
|
||||
#define _Dt_Qualify_h
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
extern char * _DtQualifyWithFirst
|
||||
(
|
||||
char *, /* file to locate */
|
||||
char * /* list of colon-separated paths in which to look */
|
||||
);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* _Dt_Qualify_h */
|
||||
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
515
cde/lib/DtSvc/DtUtil1/Saver.c
Normal file
515
cde/lib/DtSvc/DtUtil1/Saver.c
Normal file
@@ -0,0 +1,515 @@
|
||||
/* $XConsortium: Saver.c /main/8 1996/11/21 19:56:41 drk $ */
|
||||
/* *
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*************************************<+>*************************************
|
||||
*****************************************************************************
|
||||
**
|
||||
** File: Saver.c
|
||||
**
|
||||
** Description:
|
||||
** -----------
|
||||
** This file contains public and private screen saver utilities.
|
||||
**
|
||||
** Public:
|
||||
** DtSaverGetWindows() - return array of windows on which saver can draw
|
||||
**
|
||||
** Private:
|
||||
** _DtSaverStart() - launch specified screen saver
|
||||
** _DtSaverStop() - kill specified screen saver
|
||||
**
|
||||
*****************************************************************************
|
||||
*************************************<+>*************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define X_INCLUDE_STRING_H
|
||||
#define XOS_USE_XT_LOCKING
|
||||
#include <X11/Xos_r.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <Saver.h>
|
||||
#include <SaverP.h>
|
||||
#include "DtSvcLock.h"
|
||||
|
||||
/*
|
||||
* Constants global to this file.
|
||||
*/
|
||||
#define DT_SAVER_MAX_SCREENS 10
|
||||
|
||||
struct saver_state {
|
||||
unsigned short serial;
|
||||
Window xid;
|
||||
struct saver_state *next;
|
||||
};
|
||||
|
||||
static Atom xa_saver_register;
|
||||
|
||||
static struct saver_state saver_list = {0, (Window)0, NULL};
|
||||
|
||||
/*
|
||||
* Local functions.
|
||||
*/
|
||||
static void RegisterSaverCB(
|
||||
Widget w,
|
||||
XtPointer client_data,
|
||||
XEvent *event,
|
||||
Boolean *continue_to_dispatch
|
||||
);
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* _DtSaverStart() - start a screen saver
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* _DtSaverStart() is one of a suite of screen saver API's used in the
|
||||
* desktop. These APIs are:
|
||||
*
|
||||
* _DtSaverStart() starts a screen saver (private)
|
||||
* _DtSaverStop() stops a screen saver (private)
|
||||
* DtSaverGetWindows() return array of windows on which saver can draw
|
||||
*
|
||||
* The _DtSaverStart() API allocates a state variable for the screen saver
|
||||
* which contains a serial number and NIL window ID. A list of these state
|
||||
* variables is maintained, one for each call to _DtSaverStart().
|
||||
* DtSaverStart() then sets up the DTSAVERINFO environment variable containing
|
||||
* the serial number, window count and window list provided. Finally, it
|
||||
* launches the provided action and returns an opaque pointer to the state
|
||||
* variable. The action is expected to be a screen saver which makes use
|
||||
* of the DtSaverGetWindows() API.
|
||||
*
|
||||
* When the screen saver starts, it calls the DtSaverGetWindows() API. From
|
||||
* the screen saver perspective, the API returns an array of windows on which
|
||||
* the screen saver can draw. To to this, the API obtains the DTSAVERINFO
|
||||
* environment variable, and parses out the window array. The API also
|
||||
* creates a window and sends a ClientMessage to the first DTSAVERINFO window
|
||||
* containing the serial number and newly created window id.
|
||||
*
|
||||
* RegisterSaverCB() is a callback called when the ClientMessage arrives from
|
||||
* a screen saver. This callback first searches the screen saver state list
|
||||
* by serial number. If a state variable is not found, RegisterSaverCB()
|
||||
* assumes the screen saver must have been stopped by a call to
|
||||
* _DtSaverStop(), so kills the client via XKillClient() using the window id
|
||||
* provided in the message. If the state variable is located,
|
||||
* RegisterSaverCB() stores the window id in the state variable.
|
||||
*
|
||||
* _DtSaverStop() searches the screen saver list using the serial number
|
||||
* provided in the input state variable. It should always be found. When
|
||||
* found, if the state variable window id is set, _DtSaverStop() kills the
|
||||
* screen saver client via XKillClient(), deletes the state variable from
|
||||
* the list and deallocates the state variable.
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display structure
|
||||
* drawArea - array of widgets to be stored drawn upon by saver
|
||||
* count - number of elements in drawArea array
|
||||
* saverAction - screen saver action name to invoke
|
||||
* wAction - widget on which possible DtActionInvoke() errors should display
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* state - pointer to opaque state structure
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* This function uses DtActionInvoke() to launch an action. As a result,
|
||||
* the caller is responsible for loading and maintaining the action database
|
||||
* using the DtDbLoad() function and procedures. The caller
|
||||
* must call _DtSaverStop() to terminate screen saver
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
void *
|
||||
_DtSaverStart(
|
||||
Display *display,
|
||||
Widget *drawArea,
|
||||
int count,
|
||||
char *saverAction,
|
||||
Widget wAction)
|
||||
{
|
||||
static char envdata[(DT_SAVER_MAX_SCREENS * 12) + 20];
|
||||
struct saver_state *state;
|
||||
struct saver_state *p;
|
||||
int i;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
/*
|
||||
* If first time in, insert envdata in process environment.
|
||||
*/
|
||||
if (saver_list.serial == 0)
|
||||
{
|
||||
putenv(envdata);
|
||||
envdata[0] = '\0';
|
||||
xa_saver_register = XInternAtom(display, "_DT_SAVER_REGISTER", False);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add event handler (it might already be there - that's ok).
|
||||
*/
|
||||
XtAddEventHandler(drawArea[0], 0, True, RegisterSaverCB, NULL);
|
||||
|
||||
/*
|
||||
* Allocate state structure for this saver.
|
||||
*/
|
||||
if (!(state = (struct saver_state *)malloc(sizeof(struct saver_state))))
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize state structure and append to saver_list.
|
||||
*/
|
||||
state->serial = saver_list.serial++;
|
||||
state->xid = (Window)0;
|
||||
state->next = NULL;
|
||||
p = &saver_list;
|
||||
while (p->next != NULL)
|
||||
{
|
||||
p = p->next;
|
||||
}
|
||||
p->next = state;
|
||||
|
||||
/*
|
||||
* Set up environment. It will look like:
|
||||
* DTSAVERINFO="<serial> <count> <win0> <win1> ... <winN>"
|
||||
*/
|
||||
sprintf(envdata, "DTSAVERINFO=%u %i %lx",
|
||||
state->serial, count, XtWindow(drawArea[0]));
|
||||
for (i = 1; i < count; i++)
|
||||
{
|
||||
char *pe = envdata + strlen(envdata);
|
||||
sprintf(pe, " %lx", XtWindow(drawArea[i]));
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/*
|
||||
* Launch saver.
|
||||
*/
|
||||
DtActionInvoke(wAction, saverAction, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
/*
|
||||
* Return array as state information.
|
||||
*/
|
||||
return((void *)state);
|
||||
}
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* _DtSaverStop() - stop a screen saver
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Stop an external screen saver started with DtStartSaver().
|
||||
*
|
||||
* _DtSaverStop() searches the screen saver list using the serial number
|
||||
* provided in the input state variable. It should always be found. When
|
||||
* found, if the state variable window id is set, _DtSaverStop() kills the
|
||||
* screen saver client via XKillClient(), deletes the state variable from
|
||||
* the list and deallocates the state variable.
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display structure
|
||||
* state - state returned from _DtSaverStart()
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
void
|
||||
_DtSaverStop(
|
||||
Display *display,
|
||||
void *pstate)
|
||||
{
|
||||
struct saver_state *state = (struct saver_state *)pstate;
|
||||
struct saver_state *p;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
/*
|
||||
* Unlink from saver_list.
|
||||
*/
|
||||
p = &saver_list;
|
||||
while (p->next != state)
|
||||
{
|
||||
p = p->next;
|
||||
}
|
||||
p->next = state->next;
|
||||
_DtSvcProcessUnlock();
|
||||
|
||||
/*
|
||||
* Kill client using window id provided by RegisterSaverCB().
|
||||
*/
|
||||
if (state->xid != (Window)0)
|
||||
{
|
||||
XKillClient(display, state->xid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free state allocated by _DtSaverStart();
|
||||
*/
|
||||
free(pstate);
|
||||
}
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* DtSaverGetWindows() - return array of windows on which saver can draw
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
*
|
||||
* This is a PUBLIC API.
|
||||
*
|
||||
* When the screen saver starts, it calls the DtSaverGetWindows() API. From
|
||||
* the screen saver perspective, the API returns an array of windows on which
|
||||
* the screen saver can draw. To to this, the API obtains the DTSAVERINFO
|
||||
* environment variable, and parses out the window array. The API also
|
||||
* creates a window and sends a ClientMessage to the first DTSAVERINFO window
|
||||
* containing the serial number and newly created window id.
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display structure
|
||||
* window - pointer to memory in which to place pointer to array
|
||||
* count - pointer to memory in which to place count
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
* *window - pointer to array
|
||||
* *count - count
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* True - window list returned
|
||||
* False - window list not returned
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* The array memory should be freed by the caller via free().
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
Boolean
|
||||
DtSaverGetWindows(
|
||||
Display *display,
|
||||
Window **window,
|
||||
int *count)
|
||||
{
|
||||
char *envdata, *p, *q;
|
||||
unsigned short serial;
|
||||
int envcount;
|
||||
XClientMessageEvent event;
|
||||
Window xid_window;
|
||||
_Xstrtokparams strtok_buf;
|
||||
_DtSvcDisplayToAppContext(display);
|
||||
|
||||
_DtSvcAppLock(app);
|
||||
*window = NULL;
|
||||
*count = 0;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
xa_saver_register = XInternAtom(display, "_DT_SAVER_REGISTER", False);
|
||||
|
||||
/*
|
||||
* Get invocation information from environment.
|
||||
*/
|
||||
envdata = getenv("DTSAVERINFO");
|
||||
if (!envdata)
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
_DtSvcAppUnlock(app);
|
||||
return(False);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy string for later strtok() use.
|
||||
*/
|
||||
p = strdup(envdata);
|
||||
if (!p)
|
||||
{
|
||||
_DtSvcProcessUnlock();
|
||||
_DtSvcAppUnlock(app);
|
||||
return(False);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract serial.
|
||||
*/
|
||||
q = _XStrtok(p, " ", strtok_buf);
|
||||
serial = (unsigned short)strtoul(q, NULL, 10);
|
||||
|
||||
/*
|
||||
* Extract envcount.
|
||||
*/
|
||||
q = _XStrtok(NULL, " ", strtok_buf);
|
||||
envcount = (int)strtoul(q, NULL, 10);
|
||||
|
||||
/*
|
||||
* Allocate memory for window array.
|
||||
*/
|
||||
*window = (Window *)malloc((envcount)*sizeof(Window *));
|
||||
if (!*window)
|
||||
{
|
||||
free(p);
|
||||
_DtSvcProcessUnlock();
|
||||
_DtSvcAppUnlock(app);
|
||||
return(False);
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate result array and envcount.
|
||||
*/
|
||||
for (*count = 0; *count < envcount; (*count)++)
|
||||
{
|
||||
q = _XStrtok(NULL, " ", strtok_buf);
|
||||
(*window)[*count] = (Window)strtoul(q, NULL, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free temp copy of envdata.
|
||||
*/
|
||||
free(p);
|
||||
|
||||
/*
|
||||
* Create dummy window to obtain XID.
|
||||
*/
|
||||
xid_window = XCreateWindow(display, DefaultRootWindow(display),
|
||||
0, 0, 1, 1, 0,
|
||||
CopyFromParent, InputOutput, CopyFromParent,
|
||||
0, NULL);
|
||||
|
||||
if (xid_window == (Window)0)
|
||||
{
|
||||
/*
|
||||
* Could not create dummy window.
|
||||
*/
|
||||
free((char *)*window);
|
||||
*window = NULL;
|
||||
*count = 0;
|
||||
_DtSvcProcessUnlock();
|
||||
_DtSvcAppUnlock(app);
|
||||
return(False);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send client message to win0 to register.
|
||||
*/
|
||||
event.type = ClientMessage;
|
||||
event.window = (*window)[0];
|
||||
event.message_type = xa_saver_register;
|
||||
event.format = 32;
|
||||
event.data.l[0] = (Atom)0;
|
||||
event.data.l[1] = (long)serial;
|
||||
event.data.l[2] = (long)xid_window;
|
||||
event.data.l[3] = CurrentTime;
|
||||
XSendEvent(display, (*window)[0], False, NoEventMask,
|
||||
(XEvent *) &event);
|
||||
|
||||
_DtSvcProcessUnlock();
|
||||
/*
|
||||
* Ensure window creation and client message have been processed by
|
||||
* the server before continuing.
|
||||
*/
|
||||
XSync(display, False);
|
||||
|
||||
_DtSvcAppUnlock(app);
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* RegisterSaverCB() - register a screen saver
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* RegisterSaverCB() is a callback called when the ClientMessage arrives from
|
||||
* a screen saver. This callback first searches the screen saver state list
|
||||
* by serial number. If a state variable is not found, RegisterSaverCB()
|
||||
* assumes the screen saver must have been stopped by a call to
|
||||
* _DtSaverStop(), so kills the client via XKillClient() using the window id
|
||||
* provided in the message. If the state variable is located,
|
||||
* RegisterSaverCB() stores the window id in the state variable.
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* w - widget from which we derive the display
|
||||
* client_data - pointer to client data (unused)
|
||||
* event - ClientMessage event structure
|
||||
* continue_to_dispatch - dispatch to remaining event handlers (unused)
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
static void
|
||||
RegisterSaverCB(
|
||||
Widget w,
|
||||
XtPointer client_data,
|
||||
XEvent *event,
|
||||
Boolean *continue_to_dispatch)
|
||||
{
|
||||
if (event->type == ClientMessage)
|
||||
{
|
||||
XClientMessageEvent *cEvent = (XClientMessageEvent *) event;
|
||||
|
||||
_DtSvcProcessLock();
|
||||
if (cEvent->message_type == xa_saver_register)
|
||||
{
|
||||
unsigned short serial = (unsigned short)cEvent->data.l[1];
|
||||
Window win = (Window)cEvent->data.l[2];
|
||||
struct saver_state *state;
|
||||
|
||||
/*
|
||||
* Find event in saver list.
|
||||
*/
|
||||
state = saver_list.next;
|
||||
while (state != NULL && state->serial != serial)
|
||||
{
|
||||
state = state->next;
|
||||
}
|
||||
|
||||
if (state != NULL)
|
||||
{
|
||||
/*
|
||||
* _DtSaverStop() not yet called for this saver. Store xid in
|
||||
* saver's state for _DtSaverStop()'s use.
|
||||
*/
|
||||
state->xid = win;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* _DtSaverStop() has already been called for this saver, but at the
|
||||
* time, the saver had not yet registered. Kill the saver client.
|
||||
*/
|
||||
XKillClient(XtDisplay(w), win);
|
||||
}
|
||||
}
|
||||
_DtSvcProcessUnlock();
|
||||
}
|
||||
}
|
||||
30
cde/lib/DtSvc/DtUtil1/Saver.h
Normal file
30
cde/lib/DtSvc/DtUtil1/Saver.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* $XConsortium: Saver.h /main/3 1995/10/26 15:10:29 rswiston $ */
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _dtsaver_h
|
||||
#define _dtsaver_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern Boolean DtSaverGetWindows(
|
||||
Display *display,
|
||||
Window **window,
|
||||
int *count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* Close scope of 'extern "C"' declaration which encloses file. */
|
||||
#endif
|
||||
|
||||
#endif /*_dtsaver_h*/
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
90
cde/lib/DtSvc/DtUtil1/SaverP.h
Normal file
90
cde/lib/DtSvc/DtUtil1/SaverP.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* $XConsortium: SaverP.h /main/4 1995/10/26 15:10:42 rswiston $ */
|
||||
/* *
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/************************************<+>*************************************
|
||||
****************************************************************************
|
||||
**
|
||||
** File: Saver.h
|
||||
**
|
||||
** Description
|
||||
** -----------
|
||||
** Variables and declarations needed for
|
||||
** managing external screen savers
|
||||
**
|
||||
****************************************************************************
|
||||
************************************<+>*************************************/
|
||||
#ifndef _dtsaverp_h
|
||||
#define _dtsaverp_h
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* _DtSaverStart()
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Store provided array of windows on root window property
|
||||
* _DT_SAVER_WINDOWS and launch specified screen saver. Screen savers
|
||||
* will attempt to use these windows as drawables.
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display structure
|
||||
* drawArea - array of widgets to be drawn upon by screen saver
|
||||
* count - number of elements in drawArea array
|
||||
* saverAction - screen saver action to invoke
|
||||
* wAction - action UI widget
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* state - pointer to opaque state structure
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* This function uses _DtActionInvoke() to launch an action. As a result,
|
||||
* the caller is responsible for loading and maintaining the action database
|
||||
* using the DtDbLoad() function and procedures. The caller
|
||||
* must call _DtSaverStop() to terminate screen saver
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
extern void * _DtSaverStart(Display *, Widget *, int, char *, Widget);
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* _DtSaverStop()
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Stop an external screen saver started with DtStartSaver(). Deletes
|
||||
* _DT_SAVER_WINDOWS property from root window.
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* display - display structure
|
||||
* state - state returned from _DtSaverStart()
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
extern void _DtSaverStop(Display *, void *);
|
||||
|
||||
|
||||
#endif /*_dtsaverp_h*/
|
||||
/* DON'T ADD ANYTHING AFTER THIS #endif */
|
||||
37
cde/lib/DtSvc/DtUtil1/Session.h
Normal file
37
cde/lib/DtSvc/DtUtil1/Session.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* $XConsortium: Session.h /main/3 1995/10/26 15:10:56 rswiston $ */
|
||||
/*
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _Dt_Session_h
|
||||
#define _Dt_Session_h
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
extern Boolean DtSessionSavePath(
|
||||
Widget widget,
|
||||
char **save_path,
|
||||
char **save_file);
|
||||
|
||||
extern Boolean DtSessionRestorePath(
|
||||
Widget widget,
|
||||
char **restore_path,
|
||||
char *restore_file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _Dt_Session_h */
|
||||
228
cde/lib/DtSvc/DtUtil1/SessionM.h
Normal file
228
cde/lib/DtSvc/DtUtil1/SessionM.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/* $TOG: SessionM.h /main/8 1998/07/30 12:10:49 mgreess $ */
|
||||
/*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company
|
||||
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
|
||||
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1993, 1994, 1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
/*************************************<+>*************************************
|
||||
*****************************************************************************
|
||||
**
|
||||
** File: SessionM.h
|
||||
**
|
||||
** Description:
|
||||
** -----------
|
||||
** Contains all variables needed for SM messaging. All messages serviced,
|
||||
** and the tool class name for the session manager
|
||||
**
|
||||
**
|
||||
**
|
||||
*******************************************************************
|
||||
** (c) Copyright Hewlett-Packard Company, 1990. All rights are
|
||||
** reserved. Copying or other reproduction of this program
|
||||
** except for archival purposes is prohibited without prior
|
||||
** written consent of Hewlett-Packard Company.
|
||||
********************************************************************
|
||||
**
|
||||
**
|
||||
*****************************************************************************
|
||||
*************************************<+>*************************************/
|
||||
#ifndef _SessionM_h
|
||||
#define _SessionM_h
|
||||
|
||||
/*
|
||||
* Include files
|
||||
*/
|
||||
/* If <X11/Intrinsic.h> is included along with this file, <X11/Intrinsic.h>
|
||||
MUST be included first due to "typedef Boolean ..." problems. The following
|
||||
conditional #define is also part of the solution to this problem. */
|
||||
#include <X11/X.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
/*
|
||||
* Tool class for the session manager
|
||||
*/
|
||||
#define DtSM_TOOL_CLASS "SESSIONMGR"
|
||||
|
||||
/*
|
||||
* SM_STARTUP_CHANGE an SM_STATE parameters
|
||||
*/
|
||||
#define DtSM_VERBOSE_MODE 1
|
||||
#define DtSM_QUIET_MODE 2
|
||||
#define DtSM_ASK_STATE 0
|
||||
#define DtSM_HOME_STATE 3
|
||||
#define DtSM_CURRENT_STATE 4
|
||||
|
||||
|
||||
/*
|
||||
* Atoms for session manager/style manager communication
|
||||
*/
|
||||
#define _XA_DT_SM_STM_PROTOCOL "_DT_SM_STM_PROTOCOL"
|
||||
#define _XA_DT_SM_SAVE_TO_HOME "_DT_SM_SAVE_TO_HOME"
|
||||
#define _XA_DT_SM_STATE_CHANGE "_DT_SM_STATE_CHANGE"
|
||||
#define _XA_DT_SM_RESTORE_DEFAULT "_DT_SM_RESTORE_DEFAULT"
|
||||
#define _XA_DT_SM_PREFERENCES "_DT_SM_PREFERENCES"
|
||||
|
||||
/*
|
||||
* Atoms for lock changes
|
||||
*/
|
||||
#define _XA_DT_SM_LOCK_CHANGE "_DT_SM_LOCK_CHANGE"
|
||||
#define CoverScreenMask (1L<<0)
|
||||
#define LockOnTimeoutMask (1L<<1)
|
||||
|
||||
/*
|
||||
* Parameters to be sent into session manager
|
||||
*/
|
||||
|
||||
/*
|
||||
* Atoms for communicating configuration changes and state
|
||||
*/
|
||||
/*
|
||||
* Defines needed for getting/setting the sm window property on the root
|
||||
*/
|
||||
#define PROP_DT_SM_WINDOW_INFO_ELEMENTS 2
|
||||
#define _XA_DT_SM_WINDOW_INFO "_DT_SM_WINDOW_INFO"
|
||||
|
||||
/*
|
||||
* Defines needed for getting the session manager state off it's window
|
||||
*/
|
||||
#define PROP_DT_SM_STATE_INFO_ELEMENTS 13
|
||||
#define _XA_DT_SM_STATE_INFO "_DT_SM_STATE_INFO"
|
||||
|
||||
/*
|
||||
* Defines needed for the screen saver list property.
|
||||
*/
|
||||
#define _XA_DT_SM_SAVER_INFO "_DT_SM_SAVER_INFO"
|
||||
|
||||
/*
|
||||
* Defines needed for the screen saver property
|
||||
*/
|
||||
#define PROP_DT_SM_SCREEN_INFO_ELEMENTS 5
|
||||
#define _XA_DT_SM_SCREEN_INFO "_DT_SM_SCREEN_INFO"
|
||||
|
||||
/*
|
||||
* Defines needed for the audio property
|
||||
*/
|
||||
#define PROP_DT_SM_AUDIO_INFO_ELEMENTS 4
|
||||
#define _XA_DT_SM_AUDIO_INFO "_DT_SM_AUDIO_INFO"
|
||||
|
||||
/*
|
||||
* Defines needed for the keyboard property
|
||||
*/
|
||||
#define PROP_DT_SM_KEYBOARD_INFO_ELEMENTS 3
|
||||
#define _XA_DT_SM_KEYBOARD_INFO "_DT_SM_KEYBOARD_INFO"
|
||||
|
||||
/*
|
||||
* Define needed for the font info property
|
||||
*/
|
||||
#define _XA_DT_SM_FONT_INFO "_DT_SM_FONT_INFO"
|
||||
|
||||
/*
|
||||
* Define needed for the font info property
|
||||
*/
|
||||
#define _XA_DT_SM_POINTER_INFO "_DT_SM_POINTER_INFO"
|
||||
|
||||
/*
|
||||
* Define needed for the preeditType info property
|
||||
*/
|
||||
#define _XA_DT_SM_PREEDIT_INFO "_DT_SM_PREEDIT_INFO"
|
||||
|
||||
/* bit definitions for SmStateInfo.flags */
|
||||
#define SM_STATE_NONE 0
|
||||
#define SM_STATE_START (1L << 0)
|
||||
#define SM_STATE_CONFIRM (1L << 1)
|
||||
#define SM_STATE_COMPAT (1L << 2)
|
||||
#define SM_STATE_SEND (1L << 3)
|
||||
#define SM_STATE_COVER (1L << 4) /* Obsolete */
|
||||
#define SM_STATE_LOTOUT (1L << 5) /* Obsolete */
|
||||
#define SM_STATE_LOTOUTSTAT (1L << 6)
|
||||
|
||||
#define SM_STATE_CYCLETIMEOUT (1L << 7)
|
||||
#define SM_STATE_LOCKTIMEOUT (1L << 8)
|
||||
#define SM_STATE_SAVERTIMEOUT (1L << 9)
|
||||
#define SM_STATE_RANDOM (1L << 10)
|
||||
#define SM_STATE_DISP_SESSION (1L << 11)
|
||||
|
||||
|
||||
#define SM_STATE_ALL (SM_STATE_START | SM_STATE_CONFIRM |\
|
||||
SM_STATE_COMPAT | SM_STATE_SEND |\
|
||||
SM_STATE_COVER | SM_STATE_LOTOUT |\
|
||||
SM_STATE_LOTOUTSTAT | SM_STATE_CYCLETIMEOUT |\
|
||||
SM_STATE_LOCKTIMEOUT | SM_STATE_SAVERTIMEOUT |\
|
||||
SM_STATE_RANDOM | SM_STATE_DISP_SESSION)
|
||||
|
||||
|
||||
/*
|
||||
* typedef statements for structures to be returned
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int flags;
|
||||
int smStartState;
|
||||
int smConfirmMode;
|
||||
Boolean smCompatMode;
|
||||
Boolean smSendSettings;
|
||||
Boolean smCoverScreen; /* Obsolete */
|
||||
Boolean smLockOnTimeout; /* Obsolete */
|
||||
Boolean smLockOnTimeoutStatus;
|
||||
int smCycleTimeout;
|
||||
int smLockTimeout;
|
||||
int smSaverTimeout;
|
||||
Boolean smRandom;
|
||||
Boolean smDisplaySpecific; /* If True, the currently running
|
||||
session is for a specific display */
|
||||
|
||||
} SmStateInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *saverList;
|
||||
} SmSaverInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flags;
|
||||
int smTimeout;
|
||||
int smInterval;
|
||||
int smPreferBlank;
|
||||
int smAllowExp;
|
||||
} SmScreenInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flags;
|
||||
int smBellPercent;
|
||||
unsigned int smBellPitch;
|
||||
unsigned int smBellDuration;
|
||||
} SmAudioInfo;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flags;
|
||||
int smKeyClickPercent;
|
||||
int smGlobalAutoRepeat;
|
||||
} SmKeyboardInfo;
|
||||
|
||||
/*
|
||||
* Function definitions
|
||||
*/
|
||||
extern Status _DtGetSmWindow(Display *, Window, Window *) ;
|
||||
extern Status _DtGetSmState(Display *, Window, SmStateInfo *);
|
||||
extern Status _DtSetSmState(Display *, Window, SmStateInfo *);
|
||||
extern Status _DtGetSmSaver(Display *, Window, SmSaverInfo *);
|
||||
extern void _DtSetSmSaver(Display *, Window, SmSaverInfo *);
|
||||
extern Status _DtGetSmScreen(Display *, Window, Atom, SmScreenInfo *);
|
||||
extern Status _DtGetSmAudio(Display *, Window, Atom, SmAudioInfo *);
|
||||
extern Status _DtGetSmKeyboard(Display *, Window, Atom, SmKeyboardInfo *);
|
||||
extern Status _DtGetSmFont(Display *, Window, Atom, char **);
|
||||
extern Status _DtGetSmPointer(Display *, Window, Atom, char **);
|
||||
extern Status _DtGetSmPreedit(Display *, Window, Atom, char **);
|
||||
|
||||
#endif /* _SessionM_h */
|
||||
|
||||
|
||||
|
||||
108
cde/lib/DtSvc/DtUtil1/SessionP.h
Normal file
108
cde/lib/DtSvc/DtUtil1/SessionP.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/* $TOG: SessionP.h /main/5 1998/07/30 12:11:06 mgreess $ */
|
||||
/* *
|
||||
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
||||
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
||||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
||||
* (c) Copyright 1993, 1994 Novell, Inc. *
|
||||
*/
|
||||
/*************************************<+>*************************************
|
||||
*****************************************************************************
|
||||
**
|
||||
** File: SessionP.h
|
||||
**
|
||||
** Description: Private header for Session Management routines
|
||||
** -----------
|
||||
**
|
||||
*******************************************************************
|
||||
** (c) Copyright Hewlett-Packard Company, 1990. All rights are
|
||||
** reserved. Copying or other reproduction of this program
|
||||
** except for archival purposes is prohibited without prior
|
||||
** written consent of Hewlett-Packard Company.
|
||||
********************************************************************
|
||||
**
|
||||
**
|
||||
**
|
||||
*****************************************************************************
|
||||
*************************************<+>*************************************/
|
||||
|
||||
#ifndef _SessionP_h
|
||||
#define _SessionP_h
|
||||
|
||||
/*
|
||||
* include statements
|
||||
*/
|
||||
|
||||
/*
|
||||
* define statements
|
||||
*/
|
||||
|
||||
/*
|
||||
* typedef statements
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definition for the _DT_SM_WINDOW_INFO property.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long smWindow;
|
||||
} PropDtSmWindowInfo;
|
||||
|
||||
/*
|
||||
* Definition for the _DT_SM_STATE_INFO property
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long smStartState;
|
||||
unsigned long smConfirmMode;
|
||||
unsigned long smCompatMode;
|
||||
unsigned long smSendSettings;
|
||||
unsigned long smCoverScreen;
|
||||
unsigned long smLockOnTimeout;
|
||||
unsigned long smLockOnTimeoutStatus;
|
||||
unsigned long smCycleTimeout;
|
||||
unsigned long smLockTimeout;
|
||||
unsigned long smSaverTimeout;
|
||||
unsigned long smRandom;
|
||||
unsigned long smDisplaySpecific;
|
||||
} PropDtSmStateInfo;
|
||||
|
||||
/*
|
||||
* Definition for the _DT_SM_SCREEN_INFO property
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long smTimeout;
|
||||
unsigned long smInterval;
|
||||
unsigned long smPreferBlank;
|
||||
unsigned long smAllowExp;
|
||||
} PropDtSmScreenInfo;
|
||||
|
||||
/*
|
||||
* Definition for the _DT_SM_AUDIO_INFO property
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long smBellPercent;
|
||||
unsigned long smBellPitch;
|
||||
unsigned long smBellDuration;
|
||||
} PropDtSmAudioInfo;
|
||||
|
||||
|
||||
/*
|
||||
* Definition for the _DT_SM_KEYBOARD_INFO property
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long smKeyClickPercent;
|
||||
unsigned long smGlobalAutoRepeat;
|
||||
} PropDtSmKeyboardInfo;
|
||||
|
||||
|
||||
#endif /* _SessionP_h */
|
||||
/* Do not add anything after this endif. */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user