Intial commit

This commit is contained in:
Mario Fetka
2024-05-27 16:13:40 +02:00
parent f8dc12b10a
commit d71d446104
2495 changed files with 539746 additions and 0 deletions

1
prospero/lib/psrv/wais_gw/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
Makefile

View File

@@ -0,0 +1,49 @@
FILES
Makefile
buffalloc.c
buffalloc.h
cdialect.h
cutil.c
cutil.h
docid.h
futil.c
futil.h
ietftype.c
ietftype.h
ietftype_parse.c
ietftype_parse.h
ietftypes
inface.c
inface.h
irfileio.c
irfileio.h
list.c
list.h
main.c
panic.c
panic.h
sockets.c
sockets.h
source.c
source.h
sourcealloc.c
sourceparse.c
ustubs.c
ustubs.h
wais_gw_dsdb.c
wais_gw_dsdb.h
wais_gw_mutex.c
waislog.c
waislog.h
wmessage.c
wmessage.h
wprot.c
wprot.h
wutil.c
wutil.h
zprot.c
zprot.h
ztype1.c
ztype1.h
zutil.c
zutil.h

View File

@@ -0,0 +1,234 @@
#*****************************************************************************
# (c) Copyright 1992,1993 Wide Area Information Servers, Inc *
# of California. All rights reserved. *
# *
# This notice is intended as a precaution against inadvertent publication *
# and does not constitute an admission or acknowledgement that publication *
# has occurred or constitute a waiver of confidentiality. *
# *
# Wide Area Information Server software is the proprietary and *
# confidential property of Wide Area Information Servers, Inc. *
#*****************************************************************************
# this file has different configuration ideas from the rest of Prospero.
# this is a problem.
SOURCEBASE=../../..
include $(SOURCEBASE)/Makefile.config
# Note that not all versions of make will support this construct.
CFLAGS += $(WCFLAGS)
# These are needed by the Prospero 'setdependencies' script.
CFILES = buffalloc.c \
ustubs.c \
list.c \
cutil.c \
futil.c \
panic.c \
waislog.c \
irfileio.c \
wutil.c \
wprot.c \
zprot.c \
zutil.c \
ztype1.c \
source.c \
sourcealloc.c \
sockets.c \
inface.c \
wmessage.c \
ietftype.c \
ietftype_parse.c \
wais_gw_mutex.c \
wais_gw_dsdb.c \
sourceparse.c
# the z3950 protocol and tcp communications
UTIL = \
buffalloc.o \
ustubs.o \
list.o \
cutil.o \
futil.o \
panic.o \
waislog.o \
irfileio.o
OBJS = \
wutil.o \
wprot.o \
zprot.o \
zutil.o \
ztype1.o \
source.o \
sourcealloc.o \
sockets.o \
inface.o \
wmessage.o
GW = \
ietftype.o \
ietftype_parse.o \
wais_gw_mutex.o \
wais_gw_dsdb.o
OBJECTS = ${UTIL} ${OBJS} ${GW} sourceparse.o
all: ${WAIS_GW_LIB} sourceparse
${WAIS_GW_LIB}: ${OBJS} ${UTIL} ${GW}
$(RM) -f $@
$(AR) $(ARFLAGS) $@ $(OBJS) $(UTIL) $(GW)
$(RANLIB) $@
install: sourceparse ietftypes
-for i in sourceparse ietftypes ; do \
${INSTALL} -c -m 755 -o ${OWNER} -g ${GROUP} $$i ${P_BINARIES}/$$i${GENERATIONSUFFIX}; \
${GENERATION} ${P_BINARIES}/$$i ; \
done
sourceparse: sourceparse.o ${WAIS_GW_LIB} $(PFS_LIBS_DEPENDENCIES)
${CC} ${CFLAGS} -o $@ sourceparse.o $(WAIS_GW_LIB) $(PFS_LIBS)
# Not clear why this is necessary. --swa
#-u ${COMPILER_PREPENDS_C_SYMBOLS_WITH_UNDERSCORE}gopher_gw_init_mutexes ${SPLIBS}
# Dependencies
buffalloc.o : buffalloc.h inface.h \
wprot.h cdialect.h zprot.h zutil.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h ztype1.h ../../../include/pfs.h \
../../../include/ardp.h \
../../../include/list_macros.h ../../../include/../lib/ardp/flocks.h \
../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/mitra_macros.h ../../../include/psrv.h \
../../../include/pparse.h
ustubs.o : ustubs.h cdialect.h futil.h cutil.h \
../../../include/pmachine.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h
list.o : list.h cutil.h \
cdialect.h
cutil.o : \
../../../include/pfs.h \
../../../include/pfs_utils.h ../../../include/ardp.h \
../../../include/pfs_threads.h \
../../../include/list_macros.h ../../../include/../lib/ardp/flocks.h \
../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/perrno.h cutil.h cdialect.h futil.h
futil.o : \
futil.h \
cdialect.h cutil.h \
panic.h ../../../include/pfs_threads.h ../../../include/pfs_utils.h
panic.o : \
panic.h cdialect.h waislog.h \
cutil.h \
../../../include/pfs.h ../../../include/pfs_utils.h \
../../../include/ardp.h ../../../include/pfs_threads.h \
../../../include/list_macros.h ../../../include/../lib/ardp/flocks.h \
../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/perrno.h
waislog.o :
irfileio.o : \
../../../include/pfs.h ../../../include/pfs_utils.h \
../../../include/ardp.h \
../../../include/pfs_threads.h \
../../../include/list_macros.h \
../../../include/../lib/ardp/flocks.h ../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/perrno.h irfileio.h cdialect.h futil.h cutil.h zprot.h zutil.h
wutil.o : futil.h cdialect.h cutil.h \
zprot.h \
zutil.h ../../../include/pfs_threads.h ../../../include/pfs_utils.h \
wprot.h ztype1.h \
wutil.h
wprot.o : wprot.h cdialect.h zprot.h zutil.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h \
ztype1.h panic.h
zprot.o : zprot.h cdialect.h zutil.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h
zutil.o : \
zutil.h \
cdialect.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h
ztype1.o : ztype1.h cdialect.h zutil.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h \
panic.h waislog.h
source.o : ../../../include/string_with_strcasecmp.h \
cutil.h \
cdialect.h \
futil.h \
irfileio.h zprot.h zutil.h ../../../include/pfs_threads.h \
../../../include/pfs_utils.h source.h ../../../include/pfs.h ../../../include/ardp.h \
../../../include/list_macros.h \
../../../include/../lib/ardp/flocks.h ../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/mitra_macros.h ../../../include/psrv.h \
../../../include/pparse.h
sourcealloc.o : buffalloc.h inface.h wprot.h cdialect.h zprot.h \
zutil.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h \
ztype1.h ../../../include/pfs.h ../../../include/ardp.h \
../../../include/list_macros.h ../../../include/../lib/ardp/flocks.h \
../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/mitra_macros.h source.h
sockets.o : sockets.h cdialect.h cutil.h \
../../../include/posix_signal.h \
panic.h waislog.h
inface.o : zutil.h cdialect.h cutil.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h \
zprot.h wprot.h ztype1.h wmessage.h inface.h sockets.h \
waislog.h \
../../../include/pfs.h ../../../include/ardp.h ../../../include/list_macros.h \
../../../include/../lib/ardp/flocks.h ../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/perrno.h buffalloc.h
wmessage.o : \
wmessage.h cdialect.h cutil.h
ietftype.o : ietftype.h ../../../include/pfs.h \
../../../include/pfs_utils.h ../../../include/ardp.h \
../../../include/pfs_threads.h \
../../../include/list_macros.h \
../../../include/../lib/ardp/flocks.h ../../../include/implicit_fixes.h \
../../../include/pmachine.h \
../../../include/mitra_macros.h ../../../include/psrv.h \
../../../include/pparse.h
ietftype_parse.o : \
../../../include/pfs.h ../../../include/pfs_utils.h \
../../../include/ardp.h ../../../include/pfs_threads.h \
../../../include/list_macros.h \
../../../include/../lib/ardp/flocks.h ../../../include/implicit_fixes.h \
../../../include/pmachine.h \
ietftype.h ../../../include/mitra_macros.h
wais_gw_mutex.o : ../../../include/pfs_threads.h \
../../../include/pfs_utils.h \
ietftype_parse.h ietftype.h ../../../include/pfs.h ../../../include/ardp.h \
../../../include/list_macros.h \
../../../include/../lib/ardp/flocks.h ../../../include/implicit_fixes.h \
../../../include/pmachine.h
wais_gw_dsdb.o : \
../../../include/pmachine.h \
../../../include/psite.h \
../../../include/ardp.h \
../../../include/pfs_threads.h ../../../include/pfs_utils.h \
../../../include/list_macros.h ../../../include/../lib/ardp/flocks.h \
../../../include/pfs.h \
../../../include/implicit_fixes.h \
../../../include/pserver.h ../../../include/psrv.h \
../../../include/pparse.h \
../../../include/perrno.h ../../../include/plog.h wprot.h cdialect.h zprot.h \
zutil.h cutil.h ztype1.h source.h inface.h wais_gw_dsdb.h ietftype.h ietftype_parse.h
sourceparse.o : \
source.h ../../../include/pfs.h ../../../include/pfs_utils.h \
../../../include/ardp.h ../../../include/pfs_threads.h \
../../../include/list_macros.h ../../../include/../lib/ardp/flocks.h \
../../../include/implicit_fixes.h \
../../../include/pmachine.h

View File

@@ -0,0 +1,137 @@
/* Copyright (c) 1993, by Pandora Systems */
/* Author: Mitra <mitra@path.net> */
/* Allocation code copied and adapted from:
prospero/alpha.5.2a+/lib/pfs/flalloc */
/*
* Original allocation code Copyright (c) 1991-1993 by the University of
* Southern California
* Modifications to Pandora code copyright (c) 1994 by the University
* of Southern California
*
* For copying and distribution information, please see the file
* <usc-license.h>.
*/
#include <usc-license.h>
#include "buffalloc.h"
#include <pfs.h>
#include <mitra_macros.h>
#define Channel_Illegal 0;
#include <psrv.h> /* includes global declarations of
waismsgbuff_count and waismsgbuff_max to be
read by dirsrv.c. */
static WAISMSGBUFF lfree = NULL; /* Free waismsgbuffs */
/* These are global variables which will be read by dirsrv.c
Too bad C doesn't have better methods for structuring such global data. */
int waismsgbuff_count = 0;
int waismsgbuff_max = 0;
/************* Standard routines to alloc, free and copy *************/
/*
* waismsgbuff_alloc - allocate and initialize WAISMSGBUFF structure
*
* returns a pointer to an initialized structure of type
* WAISMSGBUFF. If it is unable to allocate such a structure, it
* signals out_of_memory();
*/
WAISMSGBUFF
waismsgbuff_alloc()
{
WAISMSGBUFF msgbuff;
TH_STRUC_ALLOC(waismsgbuff,WAISMSGBUFF,msgbuff);
return(msgbuff);
}
/*
* waismsgbuff_free - free a WAISMSGBUFF structure
*
* waismsgbuff_free takes a pointer to a WAISMSGBUFF structure and adds it to
* the free list for later reuse.
*/
void
waismsgbuff_free(WAISMSGBUFF msgbuff)
{
TH_STRUC_FREE(waismsgbuff,WAISMSGBUFF,msgbuff);
}
/*
* waismsgbuff_lfree - free a linked list of WAISMSGBUFF structures.
*
* waismsgbuff_lfree takes a pointer to a waismsgbuff structure frees it and
* any linked
* WAISMSGBUFF structures. It is used to free an entire list of WAISMSGBUFF
* structures.
*/
void
waismsgbuff_lfree(msgbuff)
WAISMSGBUFF msgbuff;
{
TH_STRUC_LFREE(WAISMSGBUFF,msgbuff,waismsgbuff_free);
}
void
waismsgbuff_freespares()
{
TH_FREESPARES(waismsgbuff,WAISMSGBUFF);
}
#ifdef NEVERDEFINED
/*
* waismsgbuff_copy - allocates a new waismsgbuff structure and
* initializes it with a copy of another
* waismsgbuff, v.
*
* If r is non-zero, successive waismsgbuffs will be
* iteratively copied.
*
* msgbuff-previous will always be null on the first link, and
* will be appropriately filled in for iteratively copied links.
*
* waismsgbuff_copy returns a pointer to the new structure of type
* WAISMSGBUFF. If it is unable to allocate such a structure, it
* returns NULL.
*
* waismsgbuff_copy will recursively copy the link associated with
* a waismsgbuff and
* its associated attributes.
*/
WAISMSGBUFF
waismsgbuff_copy(f,r)
WAISMSGBUFF f;
int r; /* Currently ignored. */
{
WAISMSGBUFF nf;
WAISMSGBUFF snf; /* Start of the chain of new links */
WAISMSGBUFF tf; /* Temporary link pointer */
nf = waismsgbuff_alloc();
snf = nf;
copyeach:
/* Copy f into nf */
#ifdef ALLOCATOR_CONSISTENCY_CHECK
assert(f->consistency == INUSE_PATTERN);
#endif
LOCAL STUFF NOT DEFINED
if(r && f->next) {
f = f->next;
tf = nf;
nf = waismsgbuff_alloc();
nf->previous = tf;
tf->next = nf;
goto copyeach;
}
return(snf);
}
#endif

View File

@@ -0,0 +1,27 @@
#ifndef wais_buffalloc_h
#define wais_buffalloc_h
#include "inface.h" /* For MAX_MESSAGE_LENGTH */
#include <pfs.h>
#include <pfs_threads.h>
struct waismsgbuff {
#ifdef ALLOCATOR_CONSISTENCY_CHECK
int consistency;
#endif
char buff[(size_t)MAX_MESSAGE_LENGTH * sizeof(char)];
struct waismsgbuff *next;
struct waismsgbuff *previous;
};
typedef struct waismsgbuff *WAISMSGBUFF;
typedef struct waismsgbuff WAISMSGBUFF_ST;
extern WAISMSGBUFF waismsgbuff_alloc();
extern void waismsgbuff_free(WAISMSGBUFF msgbuff);
extern void waismsgbuff_lfree(WAISMSGBUFF msgbuff);
extern void waismsgbuff_freespares();
/*extern WAISMSGBUFF waismsgbuff_copy(WAISMSGBUFF f, int r);*/
EXTERN_ALLOC_DECL(WAISMSGBUFF);
#endif /*wais_buffalloc_h*/

View File

@@ -0,0 +1,117 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
/* there are three kinds of C that we have encountered so far:
1. ANSI_LIKE - full prototypes and stdargs and ansi includes
2. PROTO_ANSI - full prototypes, varargs and misc includes
3. K_AND_R - k&r prototypes, varargs and misc includes
This file is a mess because some compilers do not handle elif. sorry.
defined symbols for other machines:
hp: hpux
Next: NeXT
*/
#ifndef C_DIALECT
#define C_DIALECT
/*----------------------------------------------------------------------*/
#define _AP(args) args
#ifdef STDC
#define ANSI_LIKE
#endif /* def STDC */
#ifdef __STDC__
#ifndef M_XENIX /* for some reason XENIX defines __STDC__ */
#define ANSI_LIKE
#endif /* ndef M_XENIX */
#endif /* __STDC__ */
#ifdef __alpha
#define ANSI_LIKE
#endif /* def __alpha */
#ifdef THINK_C
#define ANSI_LIKE
#endif /* THINK_C */
#ifdef MPW
#define ANSI_LIKE
#endif /* MPW */
#ifdef VAX_C /* vms */
#define ANSI_LIKE
#endif /* VAX_C */
#ifdef MSC /* XXX not sure if this is correct */
#define ANSI_LIKE
#endif /* MSC */
#ifndef ANSI_LIKE
#ifdef SABER /* c interpreter/debugger */
#define PROTO_ANSI
#endif /* SABER */
#ifdef cstar /* parallel C on the CM */
#define PROTO_ANSI
#endif /* cstar */
#ifndef PROTO_ANSI
#ifdef SUN_C /* XXX not sure if this is correct */
#define K_AND_R
#endif /* SUN_C */
#ifdef __GNUC__ /* gcc in traditional mode */
#define K_AND_R /* gcc in ansi mode defines __STDC__ */
#endif /* __GNUC__ */
#ifdef M_XENIX
#define K_AND_R
#define NOTCPIP /* doesn't support TCP */
#define SYSV /* is based on system V */
#endif /* M_XENIX */
/* otherwise */
#define K_AND_R /* default to the stone age */
#endif /* ndef PROTO_ANSI */
#endif /* ndef ANSI_LIKE */
/* if you are not k_and_r, then load in ustubs always */
#ifdef K_AND_R
#include "ustubs.h"
#endif /* def K_AND_R */
/* Comment this back in to figure out what the compiler thinks we are */
/*
#ifdef ANSI_LIKE
WeareAnsiLike
#endif
#ifdef PROTO_ANSI
WeareProtoAnsi
#endif
#ifdef K_AND_R
WeareKandR
#endif
Crash-and-Burn
*/
/* End of chunk to comment back in */
#ifdef SCOUNIX
#define getdomainname(str,len) sprintf(str,"")
#endif /*SCOUNIX*/
#endif /* ndef C_DIALECT */
/*----------------------------------------------------------------------*/

View File

@@ -0,0 +1,777 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
#define cutil_c
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <pfs.h>
#include <perrno.h>
#include "cutil.h"
#include "futil.h"
#ifdef NOTUSEDANDNOTTHREADSAFE
long myPID = -1;
#endif /*NOTUSEDANDNOTTHREADSAFE*/
typedef long (longfunc)(long c);
/*---------------------------------------------------------------------------*/
char*
s_strdup(char* s)
{
unsigned long len;
char* copy = NULL;
if (s == NULL)
return(NULL);
len = strlen(s);
copy = (char*)s_malloc((size_t)(sizeof(char)*(len + 1)));
strncpy(copy,s,len + 1);
return(copy);
}
/*---------------------------------------------------------------------------*/
#if !defined(IN_RMG) && !defined(PFS_THREADS)
char*
strtokf(char* s1,longfunc *isDelimiter)
{
static char* searchStr = NULL;
static longfunc *delimiterFunc;
long i;
char* startTok = NULL;
if (s1 != NULL)
searchStr = s1;
if (isDelimiter != NULL)
delimiterFunc = isDelimiter;
if (searchStr == NULL || searchStr[0] == '\0')
return(NULL);
if (delimiterFunc == NULL)
return(NULL);
for (i = 0; searchStr[i] != '\0'; i++)
{ if ((*delimiterFunc)((long)searchStr[i]) == NOT_DELIMITER)
break;
}
if (searchStr[i] == '\0')
return(NULL);
else
startTok = searchStr + i;
for (; searchStr[i] != '\0'; i++)
{ if ((*delimiterFunc)((long)searchStr[i]) == IS_DELIMITER)
break;
}
if (searchStr[i] != '\0')
{ searchStr[i] = '\0';
searchStr = searchStr + i + 1;
}
else
searchStr = searchStr + i;
return(startTok);
}
/*---------------------------------------------------------------------------*/
char*
strtokf_isalnum(char* s1)
{
static char* searchStr = NULL;
long i;
char* startTok = NULL;
if (s1 != NULL)
searchStr = s1;
if (searchStr == NULL || searchStr[0] == '\0')
return(NULL);
for (i = 0; searchStr[i] != '\0'; i++)
{ if (safeIsAlNum(searchStr[i]))
break;
}
if (searchStr[i] == '\0')
return(NULL);
else
startTok = searchStr + i;
for (; searchStr[i] != '\0'; i++)
{ if (!safeIsAlNum(searchStr[i]))
break;
}
if (searchStr[i] != '\0')
{ searchStr[i] = '\0';
searchStr = searchStr + i + 1;
}
else
searchStr = searchStr + i;
return(startTok);
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
boolean
substrcmp(char* string1,char* string2)
/* return true if they match up to the length of the smaller (but not if the
smaller is empty)
*/
{
register char *a, *b;
a = string1;
b = string2;
/* see if they are both empty - if so them match */
if (*a == '\0' && *b == '\0')
return(true);
/* see if either is empty (but not both) - no match */
if (*a == '\0' || *b == '\0')
return(false);
/* otherwise we need to look through each byte */
while (*a && *b)
{ if (*a++ != *b++)
return(false);
}
return(true);
}
/*---------------------------------------------------------------------------*/
char
char_downcase(unsigned long long_ch)
{
unsigned char ch = long_ch & 0xFF;
return(((ch >= 'A') && (ch <= 'Z')) ? (ch + 'a' -'A') : ch);
}
/*---------------------------------------------------------------------------*/
char*
string_downcase(char *word)
{
long i = 0;
if (word == NULL)
return(NULL);
while (word[i] != '\0')
{ word[i] = char_downcase((unsigned long)word[i]);
i++;
}
return(word);
}
/*---------------------------------------------------------------------------*/
long
cprintf(boolean print, char* format, ...)
{
va_list ap;
if (print == 1)
{ long res;
va_start(ap,format);
res = vprintf(format,ap);
va_end(ap);
return(res);
}
else
return(0);
}
/*---------------------------------------------------------------------------*/
void
printHexByte(unsigned char h)
{
if (h < 0x10)
printf("0%x",h);
else
printf("%x",h);
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
commafy(long val,char* buf)
/*
prints the value using format, then adds commas separating every
three orders of magnitude on the left side of the decimal point.
limitations
- there needs to be a buffer to write the result into. We provide
one for convenience, but of course that's not reentrant, so if you
are calling this is multiple times before using the result you'll
need to pass in your own buffer
- only works on longs
- only works on positive nums
- no other formatting allowed
*/
{
static char myBuf[100];
if (buf == NULL)
buf = myBuf;
if (val < 1000) /* 1 thousand */
sprintf(buf,"%ld",val);
else if (val < 1000000) /* 1 millon */
{ long lessThanAGrand = val%1000;
long moreThanAGrand = val - lessThanAGrand;
sprintf(buf,"%ld,%03ld",moreThanAGrand/1000,lessThanAGrand);
}
else if (val < 1000000000) /* 1 trillion, 1 gig */
{ long lessThanAGrand = val%1000;
long lessThanAMil = (val%1000000) - lessThanAGrand;
long moreThanAMil = val - lessThanAMil - lessThanAGrand;
sprintf(buf,"%ld,%03ld,%03ld",moreThanAMil/1000000,lessThanAMil/1000,
val%1000);
}
return(buf);
}
#endif NOTUSEDANDNOTTHREADSAFE
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
printable_time(void)
{
static char *string;
time_t tptr;
time(&tptr);
string = ctime(&tptr);
if (string)
{ if (string[strlen(string)-1] == '\n')
string[strlen(string)-1] = '\0';
return(string+4);
}
else
return("Time Unknown");
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
#ifdef BSD
#define NEED_VPRINTF
#endif
#ifdef NEED_VPRINTF
#ifdef OSK
#define LONGINT
#define INTSPRINTF
#endif
#ifdef NOVOID
typedef char *pointer;
#else
typedef void *pointer;
#endif
#ifdef INTSPRINTF
#define Sprintf(string,format,arg) (sprintf((string),(format),(arg)))
#else
#define Sprintf(string,format,arg) (\
sprintf((string),(format),(arg)),\
strlen(string)\
)
#endif
typedef int *intp;
int vsprintf(dest, format, args)
char *dest;
register char *format;
va_list args;
{
register char *dp = dest;
register char c;
register char *tp;
char tempfmt[64];
#ifndef LONGINT
int longflag;
#endif
tempfmt[0] = '%';
while( (c = *format++) != 0) {
if(c=='%') {
tp = &tempfmt[1];
#ifndef LONGINT
longflag = 0;
#endif
continue_format:
switch(c = *format++) {
case 's':
*tp++ = c;
*tp = '\0';
dp += Sprintf(dp, tempfmt, va_arg(args, char *));
break;
case 'u':
case 'x':
case 'o':
case 'X':
#ifdef UNSIGNEDSPECIAL
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
else
#endif
dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
break;
#endif
case 'd':
case 'c':
case 'i':
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
dp += Sprintf(dp, tempfmt, va_arg(args, long));
else
#endif
dp += Sprintf(dp, tempfmt, va_arg(args, int));
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
*tp++ = c;
*tp = '\0';
dp += Sprintf(dp, tempfmt, va_arg(args, double));
break;
case 'p':
*tp++ = c;
*tp = '\0';
dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
break;
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case ' ':
case '#':
case 'h':
*tp++ = c;
goto continue_format;
case 'l':
#ifndef LONGINT
longflag = 1;
*tp++ = c;
#endif
goto continue_format;
case '*':
tp += Sprintf(tp, "%d", va_arg(args, int));
goto continue_format;
case 'n':
*va_arg(args, intp) = dp - dest;
break;
case '%':
default:
*dp++ = c;
break;
}
} else *dp++ = c;
}
*dp = '\0';
return dp - dest;
}
int vfprintf(dest, format, args)
FILE *dest;
register char *format;
va_list args;
{
register char c;
register char *tp;
register int count = 0;
char tempfmt[64];
#ifndef LONGINT
int longflag;
#endif
tempfmt[0] = '%';
while(c = *format++) {
if(c=='%') {
tp = &tempfmt[1];
#ifndef LONGINT
longflag = 0;
#endif
continue_format:
switch(c = *format++) {
case 's':
*tp++ = c;
*tp = '\0';
count += fprintf(dest, tempfmt, va_arg(args, char *));
break;
case 'u':
case 'x':
case 'o':
case 'X':
#ifdef UNSIGNEDSPECIAL
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
else
#endif
count += fprintf(dest, tempfmt, va_arg(args, unsigned));
break;
#endif
case 'd':
case 'c':
case 'i':
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
count += fprintf(dest, tempfmt, va_arg(args, long));
else
#endif
count += fprintf(dest, tempfmt, va_arg(args, int));
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
*tp++ = c;
*tp = '\0';
count += fprintf(dest, tempfmt, va_arg(args, double));
break;
case 'p':
*tp++ = c;
*tp = '\0';
count += fprintf(dest, tempfmt, va_arg(args, pointer));
break;
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case ' ':
case '#':
case 'h':
*tp++ = c;
goto continue_format;
case 'l':
#ifndef LONGINT
longflag = 1;
*tp++ = c;
#endif
goto continue_format;
case '*':
tp += Sprintf(tp, "%d", va_arg(args, int));
goto continue_format;
case 'n':
*va_arg(args, intp) = count;
break;
case '%':
default:
putc(c, dest);
count++;
break;
}
} else {
putc(c, dest);
count++;
}
}
return count;
}
vprintf(format, args)
char *format;
va_list args;
{
return vfprintf(stdout, format, args);
}
#endif
/*---------------------------------------------------------------------------*/
void
fs_checkPtr(void* ptr)
{
if (ptr == NULL)
p_err_string = qsprintf_stcopyr(p_err_string,
"checkPtr found a NULL pointer");
}
/*---------------------------------------------------------------------------*/
void*
fs_malloc(size_t size)
{
void* ptr = NULL;
if (size <= 0) {
/* Define error message - even though caller may change it */
p_err_string = qsprintf_stcopyr(p_err_string,
"Allocating zero or -ve size %d", size);
return(NULL);
}
#ifdef THINK_C
ptr = (void*)NewPtr((long)size);
s_checkPtr(ptr);
memset(ptr,0,(size_t)size);
#else
ptr = (void*)calloc((size_t)size,(size_t)1);
s_checkPtr(ptr);
if (!ptr) out_of_memory();
#endif
return(ptr);
}
/*---------------------------------------------------------------------------*/
void*
fs_realloc(void* ptr,size_t size)
{
register void* nptr = NULL;
if (size <= 0)
return(NULL);
if (ptr == NULL)
return(s_malloc(size));
#ifdef THINK_C
nptr = NewPtr(size);
s_checkPtr(nptr);
BlockMove(ptr,nptr,size);
DisposPtr(ptr);
#else
nptr = (void*)realloc(ptr,size);
s_checkPtr(ptr);
if (!ptr) out_of_memory();
#endif
return(nptr);
}
/*---------------------------------------------------------------------------*/
void
fs_free(void* ptr)
{
if (ptr != NULL)
{
#ifdef THINK_C
DisposPtr(ptr);
#else
free(ptr);
#endif
}
}
/*---------------------------------------------------------------------------*/
char*
fs_strncat(char* dst,char* src,size_t maxToAdd,size_t maxTotal)
{
size_t dstSize = strlen(dst);
size_t srcSize = strlen(src);
if (dstSize + srcSize < maxTotal)
return(strncat(dst,src,maxToAdd));
else
{ size_t truncateTo = maxTotal - dstSize - 1;
char saveChar;
char* result = NULL;
saveChar = src[truncateTo];
src[truncateTo] = '\0';
result = strncat(dst,src,maxToAdd);
src[truncateTo] = saveChar;
return(result);
}
}
/*---------------------------------------------------------------------------*/
char*
fs_strncpy(char* s1,char* s2,long n)
{
s1[n-1] = '\0';
return(strncpy(s1, s2, n - 1));
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
void
initMyPID(void)
{
if (myPID == -1)
myPID = getpid();
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
void
warn(char* message)
{
#ifdef THINK_C
Debugger();
#else
printf("%s\n<press return to continue>\n",message);
getchar();
#endif
}
/*---------------------------------------------------------------------------*/
char*
next_arg(long* argc,char*** argv)
{
if ((*argc)-- > 0)
{ char* arg = *((*argv)++);
return(arg);
}
else
{ return(NULL);
}
}
/*---------------------------------------------------------------------------*/
char*
peek_arg(long* argc,char*** argv)
{
if ((*argc) > 0)
return(**argv);
else
return(NULL);
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
readNextArg(long* argc,char*** argv,boolean* useFile,FILE* file)
/*
Like next_arg(), but can read arguments from a file (one line per arg).
Note you must copy the returned value if you need access to more
than one argument at a time.
*/
{
static char buf[300];
if (file != NULL && useFile != NULL && *useFile)
{ if (fgets(buf,300,file) == NULL) /* nothing more on the file */
{ *useFile = false;
return(next_arg(argc,argv)); /* start reading regular args again */
}
else /* return a line from the file */
{ buf[strlen(buf) - 1] = '\0'; /* get rid of newline */
return(buf);
}
}
else /* just read regular args from the command line */
{ return(next_arg(argc,argv));
}
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
#ifdef THINK_C
#if THINK_C == 1
#include <EventMgr.h>
#endif
#if THINK_C == 5
#include <Events.h>
#endif
#ifdef WAIStation
#include "CRetrievalApp.h"
#endif
#endif
#ifdef NOTUSEDANDNOTTHREADSAFE
void
beFriendly()
{
#ifdef never
#ifdef THINK_C
EventRecord macEvent;
static RgnHandle mouseRgn = NULL;
long sleepTime;
#ifdef WAIStation
gApplication->FrobWaitCursor();
#endif
if (mouseRgn == NULL)
mouseRgn = NewRgn();
sleepTime = 5;
WaitNextEvent(everyEvent,&macEvent,sleepTime,mouseRgn);
#endif
#endif
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/

View File

@@ -0,0 +1,151 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
#ifndef cutil_h
#define cutil_h
#include <stdarg.h>
#include <stdio.h>
#ifndef EXIT_SUCCESS
/* #include <stdlib.h> */ /* Commented out so compiles on SCO */
#endif /* ndef EXIT_SUCCESS */
#include "cdialect.h"
#if defined(THINK_C) || defined(SCOUNIX)
#include <time.h>
#else
#include <sys/time.h>
#endif
#define byte char
#ifndef cutil_c
extern long myPID;
#endif /* ndef cutil_c */
/*---------------------------------------------------------------------------*/
/* Math utilities */
/*---------------------------------------------------------------------------*/
#ifndef MAXLONG
#define MAXLONG ((long)0x7FFFFFFF)
#endif
#undef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#undef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#undef ABS
#define ABS(x) (((x) < 0) ? (-(x)) : (x))
/*---------------------------------------------------------------------------*/
/* Define boolean data type */
/*---------------------------------------------------------------------------*/
#ifndef boolean
#define boolean unsigned long
#endif /* ndef boolean */
#ifndef true
#define true ((boolean)1)
#endif /* ndef true */
#ifndef false
#define false ((boolean)0)
#endif /* ndef false */
#ifndef TRUE
#define TRUE true
#endif /* ndef TRUE */
#ifndef FALSE
#define FALSE false
#endif /* ndef FALSE */
#ifndef NULL
#define NULL (0L)
#endif /* ndef NULL */
/*---------------------------------------------------------------------------*/
/* String utlities */
/*---------------------------------------------------------------------------*/
#define IS_DELIMITER (1L)
#define NOT_DELIMITER !IS_DELIMITER
#define STREQ(s1,s2) ((*(s1)==*(s2)) && !strcmp(s1,s2))
#define STRNCMP(s1,s2,n) \
((*(s1)==*(s2)) ? strncmp(s1,s2,n) : (*(s1) - *(s2)))
#define s_strncat(dst,src,maxToAdd,maxTotal) \
fs_strncat((dst),(src),(maxToAdd),(maxTotal))
#define s_strncpy(s1,s2,n) fs_strncpy((s1), (s2), (n))
#define safeIsAlNum(c) ((c > '`' && c < '{') || \
(c > '/' && c < ':') || \
(c > '@' && c < '['))
char* s_strdup(char* s);
char* strtokf(char* s1,long (*isDelimiter)(long c));
char* strtokf_isalnum(char* s1);
boolean substrcmp(char *string1, char *string2);
char char_downcase(unsigned long ch);
char* string_downcase(char* word);
/*---------------------------------------------------------------------------*/
/* Printing utilities */
/*---------------------------------------------------------------------------*/
#define NL() printf("\n")
long cprintf(boolean print,char* format,...);
void printHexByte(unsigned char h);
char* commafy(long val,char* buf);
char* printable_time(void);
/*---------------------------------------------------------------------------*/
/* Heap utilities */
/*---------------------------------------------------------------------------*/
#define s_checkPtr(ptr) fs_checkPtr(ptr)
#define s_malloc(size) fs_malloc(size)
#define s_realloc(ptr,size) fs_realloc((ptr),(size))
#define s_free(ptr) { fs_free((char*)ptr); ptr = NULL; }
void fs_checkPtr(void* ptr);
void* fs_malloc(size_t size);
void* fs_realloc(void* ptr,size_t size);
void fs_free(void* ptr);
char* fs_strncat(char* dst,char* src,size_t maxToAdd,size_t maxTotal);
char* fs_strncpy(char* s1,char* s2, long n);
/*---------------------------------------------------------------------------*/
/* Miscelaneous Utilities */
/*---------------------------------------------------------------------------*/
void initMyPID(void);
void warn(char* message);
char* next_arg(long* argc, char*** argv);
char* peek_arg(long* argc, char*** argv);
char* readNextArg(long* argc,char*** argv,boolean* useFile,FILE* file);
void beFriendly(void);
/*---------------------------------------------------------------------------*/
#endif /* ndef cutil_h */

View File

@@ -0,0 +1,41 @@
#ifndef docid_h
#define docid_h
#include "cdialect.h"
#include "zprot.h"
#define COPY_WITHOUT_RESTRICTION (0L)
#define ALL_RIGHTS_RESERVED (1L)
#define DISTRIBUTION_RESTRICTIONS_APPLY (2L)
/*---------------------------------------------------------------------------*/
typedef struct DocID
{ any* originalServer;
any* originalDatabase;
any* originalLocalID;
any* distributorServer;
any* distributorDatabase;
any* distributorLocalID;
long copyrightDisposition;
} DocID;
DocID* makeDocID(void);
DocID* copyDocID(DocID* doc);
void freeDocID(DocID* doc);
any* GetServer(DocID* doc);
DocID* docIDFromAny(any* rawDocID);
any* anyFromDocID(DocID* docID);
any* GetDatabase(DocID* doc);
any* GetLocalID(DocID* doc);
long GetCopyrightDisposition(DocID* doc);
long ReadDocID(DocID* doc, FILE* file);
long WriteDocID(DocID* doc, FILE* file);
boolean cmpDocIDs(DocID* d1,DocID* d2);
/*---------------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,564 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
/*-------------------------------------------------------------------------- */
/*-------------------------------------------------------------------------- */
#ifdef THINK_C
#include <pascal.h>
#if THINK_C == 1
#include <FileMgr.h>
#endif
#if THINK_C == 5
#include <Files.h>
#endif
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#if defined(__svr4__) || defined(SCOUNIX)
#include <unistd.h>
#endif
#endif
#include <string.h>
#include "futil.h"
#include "panic.h"
#include <pfs_threads.h> /* For locked_fopen etc */
/*---------------------------------------------------------------------------*/
/* Shared by all threads */
static long numFilesCurrentlyOpen = 0;
static long maxNumFilesOpenAtOneTime = 0;
#if 0
FILE*
doSafeFOpen(char* filename,char* mode)
{
FILE* file = NULL;
char realMode[100];
file = locked_fopen(filename,mode);
if (file != NULL)
{ numFilesCurrentlyOpen++;
if (numFilesCurrentlyOpen > maxNumFilesOpenAtOneTime)
maxNumFilesOpenAtOneTime = numFilesCurrentlyOpen;
/*cprintf(dbg,"fopen %ld %s\n",fileno(file),filename);*/
}
return(file);
}
/*---------------------------------------------------------------------------*/
long
doSafeFClose(FILE* file)
{
if (file != NULL)
{ numFilesCurrentlyOpen--;
return(locked_fclose(file));
}
else
return(0L);
}
#endif
/*---------------------------------------------------------------------------*/
long
doSafeFSeek(FILE* file,long offset,long fromWhere)
{
long result;
if (file == NULL)
return -1;
/*cprintf(dbg,"seek %ld %ld %ld\n",fileno(file),offset,fromWhere);*/
if (offset == 0 && fromWhere == SEEK_CUR) /* this is a nop */
return(0);
result = fseek(file,offset,fromWhere);
/* if (result != 0)
cprintf(dbg,"seek failed: file %ld offset %ld, fromWhere %d\n",
fileno(file),offset,fromWhere);
*/
return(result);
}
/*---------------------------------------------------------------------------*/
long
doSafeFTell(FILE* file)
{
long result;
if (file == NULL)
return(0);
result = ftell(file);
if (result == EOF)
panic("A seek on an index file failed.\n");
return(result);
}
/*---------------------------------------------------------------------------*/
long
doSafeRename(char* path1,char* path2)
{
#ifdef THINK_C
remove(path2);
#endif
return(rename(path1,path2));
}
/*---------------------------------------------------------------------------*/
long
writeBytes(long value,long size,FILE* stream)
{
long i;
long answer;
if ((size < sizeof(long)) && ((value >> (size * 8)) != 0))
panic("In a call to writeBytes, the value %ld can not be represented in %ld bytes",value,size);
for (i = size - 1; i >= 0; i--)
answer = putc((value >> (i * 8)) & 0xFF,stream);
if (ferror(stream) != 0)
panic("Write failed");
return(answer);
}
/*---------------------------------------------------------------------------*/
#ifdef NEVERDEFINEDUNUSED
long
readBytes(long n,FILE* stream)
{
long answer = 0;
unsigned long ch;
long i;
for (i = 0; i < n; i++)
{ ch = fgetc(stream); /* Note - no timeout */
if (ch == EOF)
return(EOF);
answer = (answer << 8) + (unsigned char)ch;
}
return(answer);
}
#endif
/*---------------------------------------------------------------------------*/
long
readBytesFromMemory(long n,unsigned char* block)
{
long answer = 0;
unsigned char ch;
long i;
for (i = 0; i < n; i++)
{ ch = *(block++);
answer = (answer << 8) + ch;
}
return(answer);
}
/*---------------------------------------------------------------------------*/
static char*
cleanPath(char* filename)
{
#ifdef THINK_C
return(filename);
#endif /* def THINK_C */
char* beginningPtr = strstr(filename,"/../");
if (beginningPtr != NULL)
{ char *ptr;
for (ptr = beginningPtr - 1; ptr >= filename; ptr--)
{ if (*ptr == '/')
{ strcpy(ptr,beginningPtr + strlen("/../") - 1);
cleanPath(filename);
break;
}
}
}
beginningPtr = strstr(filename,"/./");
if (beginningPtr != NULL)
{ strcpy(beginningPtr,beginningPtr + strlen("/./") - 1);
cleanPath(filename);
}
return(filename);
}
/*---------------------------------------------------------------------------*/
char*
truename(char* filename,char* fullPath)
{
#ifdef THINK_C
strcpy(fullPath,filename);
return(fullPath);
#else
if (filename[0] == '/')
{ strcpy(fullPath,filename);
cleanPath(fullPath);
return(fullPath);
}
else
{ getwd(fullPath);
s_strncat(fullPath,"/",MAX_FILENAME_LEN,MAX_FILENAME_LEN);
s_strncat(fullPath,filename,MAX_FILENAME_LEN,MAX_FILENAME_LEN);
cleanPath(fullPath);
return(fullPath);
}
#endif
}
/*---------------------------------------------------------------------------*/
char*
pathnameName(char* pathname)
{
#ifdef THINK_C
char *answer = strrchr(pathname,':');
#else
char *answer = strrchr(pathname,'/');
#endif
if (answer == NULL)
return(pathname);
return(answer + 1);
}
/*---------------------------------------------------------------------------*/
char*
pathnameDirectory(char* pathname,char* destination)
{
#ifdef THINK_C
n char *dirptr = strrchr(pathname,':');
#else
char *dirptr = strrchr(pathname,'/');
#endif
if (dirptr == NULL)
{
#ifdef THINK_C
strncpy(destination,pathname,MAX_FILENAME_LEN);
#else
strncpy(destination,"./",MAX_FILENAME_LEN);
#endif
}
else
{ strncpy(destination,pathname,MAX_FILENAME_LEN);
destination[dirptr - pathname + 1] = '\0';
}
return(destination);
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
mergePathnames(char* pathname,char* directory)
{
static char answer[MAX_FILENAME_LEN + 1];
if ((pathname[0] == '/') || (NULL == directory) || directory[0] == '\0')
return(pathname);
else
{ answer[0] = '\0';
strncat(answer,directory,MAX_FILENAME_LEN);
#ifdef THINK_C
if (directory[strlen(directory) - 1] != ':')
strncat(answer,":",MAX_FILENAME_LEN);
#else
if (directory[strlen(directory) - 1] != '/')
strncat(answer,"/",MAX_FILENAME_LEN);
#endif
strncat(answer,pathname,MAX_FILENAME_LEN);
}
return(answer);
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
boolean
directoryP(char* f)
/* XXX strangely, this fails if f = "". It says that f is a directory */
{
#ifdef THINK_C
return(false);
#else
struct stat stbuf;
if (f == NULL)
return(FALSE);
else if (stat(f,&stbuf) == -1)
return(FALSE);
else if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
return(true);
else
return(FALSE);
#endif
}
/*---------------------------------------------------------------------------*/
boolean
fileP(char* f)
{
if (f == NULL)
return(false);
#ifdef THINK_C
return(probeFile(f));
#else
{ struct stat stbuf;
if (stat(f,&stbuf) == -1)
return(FALSE);
else if (!((stbuf.st_mode & S_IFMT) == S_IFDIR))
return(true);
else
return(FALSE);
}
#endif
}
/*---------------------------------------------------------------------------*/
boolean
probeFile(char* filename)
{
if (filename == NULL)
return(false);
#ifdef THINK_C
{ FILE* f;
f = locked_fopen(filename,"r");
if (f == NULL)
return(false);
else
{ locked_fclose_A(f,filename,TRUE);
return(true);
}
}
#else
if (access(filename,R_OK) == 0)
return(true);
else
return(false);
#endif
}
/*---------------------------------------------------------------------------*/
boolean
probeFilePossiblyCompressed(char* filename)
{
if (filename == NULL)
return(false);
else if (!probeFile(filename))
{ char buffer[MAX_FILENAME_LEN * 2];
strcpy(buffer,filename);
strcat(buffer,".Z");
return(probeFile(buffer));
}
else
return(true);
}
/*---------------------------------------------------------------------------*/
boolean
touchFile(char* filename)
{
FILE *stream = NULL;
if (filename == NULL)
return(false);
stream = locked_fopen(filename,"a");
if (stream == NULL)
return(false);
else
{ locked_fclose_A(stream,filename,FALSE);
return(true);
}
}
/*---------------------------------------------------------------------------*/
long
fileLength(FILE* stream)
{
long position;
long end = -1;
if (stream == NULL)
return(-1);
position = ftell(stream);
safeFSeek(stream,0L,SEEK_END);
end = ftell(stream);
safeFSeek(stream,position,SEEK_SET);
return(end);
}
/*---------------------------------------------------------------------------*/
void
getFileDates(char* filename,time_t* createDate,time_t* modDate)
{
#ifdef THINK_C
*createDate = *modDate = 0;
#else
struct stat buf;
if (stat(filename,&buf) != 0)
panic("could not stat %s",filename);
*modDate = buf.st_mtime;
*createDate = buf.st_mtime; /* no separate creation date maintained in
unix! */
#endif
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
currentUserName(void)
{
static char answer[200];
char hostname[120];
#ifdef THINK_C
strcpy(answer,"MAC");
#else
#include <pwd.h>
assert(MASTER_IS_ONLY_UNTHREAD); /*getpwuid MT-Unsafe*/
struct passwd *pwent = getpwuid(getuid());
strncpy(answer,pwent->pw_name,200);
strncat(answer,"@",200);
gethostname(hostname,120);
strncat(answer,hostname,200);
#endif
return(answer);
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTIMEOUTONREAD
boolean
readStringFromFile(FILE* stream,char* array,long arrayLength)
{
long ch;
long count = 0;
array[0] = '\0';
while (true)
{ ch = fgetc(stream); /* Note no timeout */
if(ch == EOF)
{ array[count] = '\0';
return(false);
}
else if (count == arrayLength)
{ array[count] = '\0';
return(false);
}
else if('\0' == ch)
{ array[count] = '\0';
return(true);
}
else
array[count++] = ch;
}
}
#endif
/*---------------------------------------------------------------------------*/
/* Probably works, but unused */
#if 0
FILE*
openTempFile(char* dir,char* root,char* fullName,char* mode)
/* given dir and mode, return a file pointer to the file, fullName is the
full name of the file including dir. The leaf of the name begins with
root. Only makes sense if mode is a write or append mode
*/
{
FILE* f;
if (dir == NULL)
dir = ".";
if (root == NULL)
root = "temp";
if (!directoryP(dir))
return(NULL);
assert(P_IS_THIS_THREAD_MASTER()); /* random is MT-Unsafe */
for(;;) {
sprintf(fullName,"%s/%s%d.%d",dir,root,getpid(),random() % 10000);
if ((f = locked_fopen(fullName,"r")) == NULL) {
/* no file there to read, we're ok */
return locked_fopen(fullName, mode);
}
else
locked_fclose(f,fullName, TRUE);
}
}
#endif
/*---------------------------------------------------------------------------*/
void
growFile(FILE* file,long length)
{
long currentLength;
safeFSeek(file,0L,SEEK_END);
currentLength = safeFTell(file);
safeFSeek(file,length - currentLength,SEEK_END);
}
/*---------------------------------------------------------------------------*/

View File

@@ -0,0 +1,97 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
/*-------------------------------------------------------------------------- */
#ifndef futil_h
#define futil_h
#include "cdialect.h"
#include "cutil.h"
/*-------------------------------------------------------------------------- */
/* the maximum length of any filename in the system */
#define MAX_FILENAME_LEN (255L)
/* arguments for fseek, which aren't defined on all systems */
#ifndef SEEK_SET
#define SEEK_SET (0L)
#define SEEK_CUR (1L)
#define SEEK_END (2L)
#endif /* ndef SEEK_SET */
/* allow NeXT's to check if the file's mode indicates it's a directory */
#if (defined(NeXT) && !(defined(S_ISDIR)))
#define S_ISDIR(f_mode) ((f_mode) & S_IFDIR)
#endif
/*-------------------------------------------------------------------------- */
/* the following functions are "safe" versions of the standard fileio
utilities. They should be called through the macros rather than
actually calling the functions themselves
*/
/* Replaced by locked_{fopen,fclose} */
#if 0
#define safeFOpen(name,mode) doSafeFOpen((name),(mode))
#define safeFClose(file) { doSafeFClose((FILE*)(file)); \
(file) = NULL;}
#endif
#define safeFSeek(file,offset,whereFrom) \
doSafeFSeek((file),(offset),(whereFrom))
#define safeFTell(file) doSafeFTell((file))
#define safeRename(path1,path2) doSafeRename((path1),(path2))
#if 0
FILE* doSafeFOpen(char* fileName,char* mode);
long doSafeFClose(FILE* file);
#endif
long doSafeFSeek(FILE* file,long offset,long wherefrom);
long doSafeFTell(FILE* file);
/* these functions read and write arbitrary numbers of bytes in
an architecture independent fashion
*/
long writeBytes(long value,long numBytes,FILE* stream);
long readBytes(long numBytes,FILE *stream);
long readBytesFromMemory(long numBytes,unsigned char* block);
/* these routines help manage unix style path names */
char *truename(char *filename,char *full_path);
char *pathnameName(char *pathname);
char *pathnameDirectory(char *pathname,char *destination);
char *mergePathnames(char *pathname,char *directory);
/* set and get characteristics of a file or directory*/
boolean directoryP(char* f);
boolean fileP(char* f);
boolean probeFile(char *filename);
boolean probeFilePossiblyCompressed(char *filename);
boolean touchFile(char *filename);
long fileLength(FILE* stream);
void getFileDates(char* filename,time_t* createDate,time_t* modDate);
/* miscellanious routines */
char *currentUserName(void);
boolean readStringFromFile(FILE* stream,char* array,long array_length);
#if 0
FILE* openTempFile(char* dir,char* root,char* fullName,char* mode);
#endif
void growFile(FILE* file,long len);
/*-------------------------------------------------------------------------- */
#endif /* ndef futil_h */

View File

@@ -0,0 +1,101 @@
/* Copyright (c) 1993, by Pandora Systems */
/* Author: Mitra <mitra@path.net> */
/* Allocation code copied and adapted from:
prospero/alpha.5.2a+/lib/pfs/flalloc */
#include "ietftype.h"
#include <pfs.h>
#include <mitra_macros.h>
#include <psrv.h> /* includes global declarations of
ietftype_count and ietftype_max to be read.
*/
static IETFTYPE lfree = NULL; /* Free ietftypes */
/* These are global shared variables which will be read by dirsrv.c
Too bad C doesn't have better methods for structuring such global data. */
int ietftype_count = 0;
int ietftype_max = 0;
/* Syntactically same as atput in goph_gw_dsdb.c */
PATTRIB ietftype_atput(IETFTYPE it, char *name)
{
PATTRIB at;
/* Fails if no arguments -- at = vatbuild(name, ap); */
at = atalloc();
at->aname = stcopy(name);
at->avtype = ATR_SEQUENCE;
at->nature = ATR_NATURE_APPLICATION;
at->precedence = ATR_PREC_OBJECT;
APPEND_ITEM(at, it->prosperotype);
return at;
}
/************* Standard routines to alloc, free and copy *************/
/*
* ietftype_alloc - allocate and initialize IETFTYPE structure
*
* returns a pointer to an initialized structure of type
* IETFTYPE. If it is unable to allocate such a structure, it
* signals out_of_memory();
*/
IETFTYPE
ietftype_alloc()
{
IETFTYPE thistype;
TH_STRUC_ALLOC(ietftype,IETFTYPE,thistype);
thistype->standardtype=NULL;
thistype->waistype=NULL;
thistype->prosperotype=NULL;
return(thistype);
}
/*
* ietftype_free - free a IETFTYPE structure
*
* ietftype_free takes a pointer to a IETFTYPE structure and adds it to
* the free list for later reuse.
*/
void
ietftype_free(IETFTYPE thistype)
{
if (thistype->standardtype)
{ stfree(thistype->standardtype); thistype->standardtype = NULL;}
if (thistype->waistype)
{ stfree(thistype->waistype); thistype->waistype = NULL;}
if (thistype->prosperotype)
{ atfree(thistype->prosperotype); thistype->prosperotype = NULL;}
TH_STRUC_FREE(ietftype,IETFTYPE,thistype);
}
/*
* ietftype_lfree - free a linked list of IETFTYPE structures.
*
* ietftype_lfree takes a pointer to a ietftype structure frees it and
* any linked
* IETFTYPE structures. It is used to free an entire list of IETFTYPE
* structures.
*/
void
ietftype_lfree(IETFTYPE thistype)
{
TH_STRUC_LFREE(IETFTYPE,thistype,ietftype_free);
}
void
ietftype_freespares()
/* This is used for ietftypes to free up space in the child */
{
IETFTYPE instance;
while((instance = lfree) != NULL) {
/* Note this is slightly lazy, the thistype list is broken during loop*/
lfree = instance->next;
free(lfree); /* Matches malloc in STRUC_ALLOC1*/
ietftype_max--;
}
}

View File

@@ -0,0 +1,32 @@
#ifndef _rmg_ietftype_h
#define _rmg_ietftype_h
#include <pfs.h> /* For ALLOCATOR_CONSISTENCY_CHECK*/
#include <pfs_threads.h>
struct ietftype {
#ifdef ALLOCATOR_CONSISTENCY_CHECK
int consistency;
#endif
char *standardtype;
char *waistype;
PATTRIB prosperotype;
struct ietftype *next;
struct ietftype *previous;
};
typedef struct ietftype *IETFTYPE;
typedef struct ietftype IETFTYPE_ST;
extern PATTRIB ietftype_atput(IETFTYPE it, char *name);
extern IETFTYPE ietftype_alloc();
extern void ietftype_free(IETFTYPE it);
extern void ietftype_lfree(IETFTYPE it);
extern IETFTYPE ietftype_copy(IETFTYPE f,int r);
#ifdef PFS_THREADS
extern p_th_mutex p_th_mutexIETFTYPE;
#endif
#endif /*_rmg_ietftype_h*/

View File

@@ -0,0 +1,90 @@
#define IETFTYPEFILE "/usr/local/lib/ietftypes"
#include <stdio.h>
#include <pfs.h>
#include "ietftype.h"
#include <string.h>
#include <pfs_threads.h>
#include <mitra_macros.h>
/* Shared across threads */
IETFTYPE IETFTypes = NULL;
void ietftype_init();
/* Return the IETF type corresponding to the waistype - or NULL if not found*/
IETFTYPE wais_2_ietftype(char *waistype)
{
IETFTYPE thistype;
if (IETFTypes == NULL) {
#ifndef PFS_THREADS
/* In threaded version, this is done at init time */
ietftype_init();
if (IETFTypes == NULL)
#endif
return NULL;
}
thistype = IETFTypes;
TH_FIND_STRING_LIST_CASE(thistype, waistype, waistype, IETFTYPE);
/* temp = NULL or ietftype to return */
return (thistype);
}
/* Open file of types and initialise data structure */
void ietftype_init() {
FILE *st;
IETFTYPE thistype = NULL;
char ourlinebuf[1024];
int i;
char *tag = NULL;
char *value = NULL;
char *cp;
assert(P_IS_THIS_THREAD_MASTER());
if ((st = fopen(IETFTYPEFILE, "r")) == NULL) /* Not locked_fclose - before mutexes */
/* Should set an error string */
return;
while ((cp = fgets(ourlinebuf, sizeof(ourlinebuf), st)) != NULL) {
if (ourlinebuf[0] == '\n')
continue;
if (ourlinebuf[0] == '#') { /* Seperator & comment*/
thistype = NULL;
continue;
}
if (thistype == NULL) {
thistype = ietftype_alloc();
APPEND_ITEM(thistype, IETFTypes);
}
/*Would be nice if could skip trailing white space in qsscanf*/
for ( i = strlen(ourlinebuf) - 1;
strchr(" \t\n\r",ourlinebuf[i]);
i--)
ourlinebuf[i] = '\0';
if (qsscanf(ourlinebuf, "%&[^:= \t]%*[:= \t]%r",&tag,&value) == 2) {
#define tt1(tgstr,field) \
if (stcaseequal(tag,tgstr)) { \
thistype->field = stcopyr(value,thistype->field); \
continue; \
}
tt1("ietf",standardtype);
tt1("wais",waistype);
if (stcaseequal(tag,"prospero")) {
PATTRIB at=ietftype_atput(thistype,"OBJECT-INTERPRETATION");
assert(P_IS_THIS_THREAD_MASTER());
for(cp=strtok(value,"/");cp != NULL; cp=strtok(NULL,"/"))
tkappend(cp,at->value.sequence);
}
/* Add other fields here as we need them */
/* Ignores unrecognized fields */
}
/* Ignores syntactically incorrect lines */
}
stfree(tag);
fclose(st);
}

View File

@@ -0,0 +1,6 @@
#ifndef IETFTYPE_PARSE_H
#define IETFTYPE_PARSE_H
#include "ietftype.h"
extern IETFTYPE wais_2_ietftype(char *waistype);
extern void ietftype_init(void);
#endif /*IETFTYPE_PARSE_H*/

View File

@@ -0,0 +1,127 @@
# This file defines the relationships between different types
# new records can be added anywhere,
# Order is insignificant, except that this file is searched in order,
# so converting x=a to y will return the value for y, from the first record
# where x=a
#
ietf text/plain
wais TEXT
prospero DOCUMENT/TEXT/ASCII
gopher0 0
#
ietf application/gopher-menu
prospero DOCUMENT
gopher0 1
#
gopher0 4
prospero EMBEDDED/BINHEX/DATA
#
# The Generic Binaries should be Gopher type 9
gopher0 9
prospero DATA
#
gopher0 5
prospero DATA
#
gopher0 6
prospero EMBEDDED/UUENCODE/DATA
#
gopher0 7
prospero SEARCH
#
gopher0 8
prospero PORTAL
#
gopher0 I
prospero IMAGE
#
gopher0 :
prospero IMAGE
#
gopher0 M
ietf multipart/composite?
wais MIME
prospero DOCUMENT/MIME
#
gopher0 T
prospero PORTAL
#
gopher0 g
prospero IMAGE/GIF
wais GIF
#
gopher0 s
prospero SOUND
#
gopher0 <
prospero SOUND
#
# Uncommon type in Iowa gopher - Panda
gopher0 i
prospero VOID
#
gopher0 !
prospero VOID
#
gopher0 ;
prospero VIDEO
#
# CSO
gopher0 2
#
# Error
gopher0 3
#
# Whois
gopher0 w
#
# Possibly an error message type
gopher0 -
#########################################################################
# WAIS types for which incomplete information is available #
#########################################################################
#
#
wais EXCEL
#
wais DVI
#
wais MS-EXCEL
#
wais MS-POWERPOINT
#
wais MS-WORD
# Aldus Persuasion
wais PERSUASION
#
wais PICT
#
wais PS
#
wais QUICKTIME
#
wais TEXT-FTP
#
wais TIFF
# Wais question format
wais WQST
# Wais Source format
# this may end up being special cased to generate appropriate pointers
wais WSRC
ietf text/plain
prospero DOCUMENT/TEXT/ASCII
gopher0 0
#
#########################################################################
# GOPHER0 #
# #
# The next bunch are gopher0 types that correspond to other #
# types that are already listed above. #
#########################################################################
gopher0 e
ietf text/plain
wais TEXT
#
gopher0 c
ietf text/plain
wais TEXT

View File

@@ -0,0 +1,896 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
#define INPROSPERO
#include "zutil.h"
#include "zprot.h"
#include "wprot.h"
#include "wmessage.h"
#include "inface.h"
#include "sockets.h"
#include "waislog.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef INPROSPERO
#include <pfs.h>
#include <perrno.h>
#include "buffalloc.h"
#endif
#include <stdlib.h> /* For malloc and free */
/* from the Prospero library. Also prototyped in <pfs.h> */
extern const char *unixerrstr(void);
static char Err_Connect[]="WAIS gateway unable to connect to: %s(%s)";
#define CHARS_PER_PAGE 10000 /* number of chars retrieved in each request */
#define RETURN(val) {retval = val; goto cleanup; }
#define WAIS_verbose FALSE
#define TIMEOUT_WAIS_READ 20
#ifdef COMMENT
main()
{
char* server = "server.wais.com";
char* service = "210";
char* database = "smithsonian-pictures";
char* query = "gorilla";
WAISSearchResponse* response;
WAISDocumentHeader* header;
any* text;
response = waisQuery(server, service, database, query);
printf("%s\n",
p_err_string;
);
if (response != NULL) {
header = response->DocHeaders[1];
text =
waisRetrieve(server, service, database,
header->DocumentID,
"TEXT", /* JFIF, THNL */
header->DocumentLength);
printf("%s", text->bytes);
printf("%s\n", p_err_string);
}
}
#endif
static void showDiags(diagnosticRecord **d);
static long interpret_message(char* request_message,
long request_length, /* length of the buffer */
char* response_message,
long response_buffer_length,
FILE* connection,
boolean verbose);
static long transport_message(FILE* connection,
char* request_message,
long request_length,
char* response_message,
long response_buffer_length);
static long initConnection(char* inBuffer,
char* outBuffer,
long bufferSize,
FILE* connection,
char* userInfo);
static char* generate_search_apdu(char* buff,
long* buff_len,
char* seed_words,
char* database_name,
DocObj** docobjs,
long maxDocsRetrieved);
static char* generate_retrieval_apdu(char* buff,
long* buff_len,
any* docID,
long chunk_type,
long start,
long end,
char* type,
char* database_name);
/* return NULL pointer in event of an error */
WAISSearchResponse* waisQuery (char* server_name,
char* service,
char* database,
char* keywords)
{
/*FIX:Mitra:leaks, malloc,p_err_string */
char userInfo[500];
char hostname[80];
char domainname[80];
WAISMSGBUFF request_msg = NULL; /* arbitrary message limit */
WAISMSGBUFF response_msg = NULL; /* arbitrary message limit */
char *request_message = NULL;
char *response_message = NULL;
long request_buffer_length; /* how of the request is left */
SearchResponseAPDU *query_response;
WAISSearchResponse *query_response_info;
long Max_Docs = 40, message_length = MAX_MESSAGE_LENGTH;
FILE *connection = NULL;
WAISSearchResponse *retval;
if (server_name[0] == '\0' && service[0] == '\0')
connection = NULL; /* do local searching */
else { /* remote search, fill in defaults*/
if (server_name[0] == '\0')
/*default to local machine*/
gethostname(server_name,MAX_SERVER_LENGTH);
if (service[0] == '\0')
strcpy(service, Z39_50_SERVICE); /* default */
if ((connection = connectToServer(server_name,atoi(service))) == NULL){
p_err_string = qsprintf_stcopyr(p_err_string,
Err_Connect,
server_name, service);
RETURN(NULL);
}
}
request_msg = waismsgbuff_alloc(); request_message = request_msg->buff;
response_msg = waismsgbuff_alloc(); response_message = response_msg->buff;
gethostname(hostname, 80);
getdomainname(domainname, 80);
sprintf(userInfo, "prospero gateway from host: %s.%s", hostname, domainname);
if((message_length =
initConnection(request_message,
response_message,
message_length,
connection,
userInfo)) <= 0) {
p_err_string = qsprintf_stcopyr(p_err_string, Err_Connect,
server_name, service);
RETURN(NULL);
}
request_buffer_length = message_length; /* how of the request is left */
if(NULL ==
generate_search_apdu(request_message + HEADER_LENGTH,
&request_buffer_length,
keywords, database, NULL, Max_Docs)) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Error creating search APDU: request too large");
RETURN(NULL);
}
if(0 ==
interpret_message(request_message,
message_length - request_buffer_length,
response_message,
message_length,
connection,
WAIS_verbose /* true verbose */
)) { /* perhaps the server shut down on us */
p_err_string = qsprintf_stcopyr(p_err_string,
"Unable to deliver message");
RETURN(NULL);
}
readSearchResponseAPDU(&query_response, response_message + HEADER_LENGTH);
query_response_info =
((WAISSearchResponse *)query_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( query_response);
RETURN (query_response_info);
cleanup:
if (connection) fclose(connection);
waismsgbuff_free(request_msg);
waismsgbuff_free(response_msg);
return(retval);
}
/* Retrieve next part of DocumentID, assumes open connection to host */
int
waisRequestNext(FILE *connection,
char *request_message, char *response_message,
long message_length, any *DocumentID,
char *DocumentType, char *database,
long count)
{
long request_buffer_length; /* how of the request is left */
request_buffer_length = message_length; /* how often the request is left */
if(0 ==
generate_retrieval_apdu(request_message + HEADER_LENGTH,
&request_buffer_length,
DocumentID,
CT_byte,
count * CHARS_PER_PAGE,
(count + 1) * CHARS_PER_PAGE,
DocumentType,
database)) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Error generating retrieval APDU: request too long");
return(-1);
}
if(0 ==
interpret_message(request_message,
message_length - request_buffer_length,
response_message,
message_length,
connection,
WAIS_verbose /* true verbose */
)) { /* perhaps the server shut down, let's see: */
p_err_string = qsprintf_stcopyr(p_err_string,
"Error delivering message");
return(-1);
}
return(0);
}
any* waisRetrieve(char* server_name,
char* service,
char* database,
any* DocumentID,
char* DocumentType,
long DocumentLength)
{
/* docHeader = query_info->DocHeaders[document_number]; */
char userInfo[500];
char hostname[80];
char domainname[80];
WAISMSGBUFF request_msg = NULL;
WAISMSGBUFF response_msg = NULL;
SearchResponseAPDU* retrieval_response = NULL;
WAISDocumentText* fragmentText;
any* fragment = NULL;
any* document_text = NULL;
long count = 0, message_length = MAX_MESSAGE_LENGTH;
FILE *connection = NULL;
any *retval;
if (server_name[0] == '\0' && service[0] == '\0')
connection = NULL; /* do local searching */
else /* remote search, fill in defaults*/
{ if (server_name[0] == '\0')
/*default to local machine*/
gethostname(server_name,MAX_SERVER_LENGTH);
if (service[0] == '\0')
strcpy(service, Z39_50_SERVICE); /* default */
if ((connection = connectToServer(server_name,atoi(service))) == NULL)
{ p_err_string = qsprintf_stcopyr(p_err_string, Err_Connect,
server_name, service);
RETURN (NULL);
}
}
request_msg = waismsgbuff_alloc();
response_msg = waismsgbuff_alloc();
gethostname(hostname, 80);
getdomainname(domainname, 80);
sprintf(userInfo, "prospero gateway from host: %s.%s", hostname, domainname);
if((message_length =
initConnection(request_msg->buff,
response_msg->buff,
message_length,
connection,
userInfo)) <= 0) {
p_err_string = qsprintf_stcopyr(p_err_string, Err_Connect,
server_name, service);
RETURN(NULL);
}
if (DocumentType == NULL) DocumentType = s_strdup("TEXT");
/* we must retrieve the document in parts since it might be very long*/
while (TRUE) {
if (waisRequestNext(connection, request_msg->buff,
response_msg->buff,
message_length, DocumentID, DocumentType, database, count)) {
freeAny(document_text);
RETURN(NULL);
}
readSearchResponseAPDU(&retrieval_response,
response_msg->buff + HEADER_LENGTH);
if(NULL ==
((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Text) {
p_err_string = qsprintf_stcopyr(p_err_string,
"No text was returned");
freeAny(document_text);
return(NULL);
} else {
fragmentText = ((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Text[0];
fragment = fragmentText->DocumentText;
if (count == 0) {
document_text = duplicateAny(fragment);
} else {
/* Increase document_text size to accomodate fragment. */
if (!(document_text->bytes =
s_realloc(document_text->bytes,
(size_t)(document_text->size + fragment->size) * sizeof(char)))) {
/* May never get here, since can abort if no memory */
p_err_string = qsprintf_stcopyr(p_err_string,
"Unable to allocate space for %d bytes",
document_text->size+fragment->size * sizeof(char));
freeAny(document_text);
RETURN(NULL);
}
/* Copy the fragment into the document_text. */
memcpy(&(document_text->bytes[document_text->size]),
fragment->bytes,
(size_t) fragment->size * sizeof(char));
/* Adjust the size field of document_text. */
document_text->size = fragment->size + document_text->size;
}
}
/* Under normal behaviour it will loop until it encounters a diagnostic
saying read beyond end of document, and then return */
if(((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Diagnostics != NULL) {
showDiags(((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Diagnostics);
p_err_string = qsprintf_stcopyr(p_err_string, "Diagnostic records received");
RETURN(document_text);
}
count++;
freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( retrieval_response);
retrieval_response = NULL;
}
RETURN(document_text);
cleanup:
freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( retrieval_response);
if (connection) fclose(connection);
waismsgbuff_free(request_msg);
waismsgbuff_free(response_msg);
return(retval);
}
int waisRetrieveFile(
char* server_name,
char* service,
char* database,
any* DocumentID,
char* DocumentType,
long DocumentLength,
char* local)
{
/* docHeader = query_info->DocHeaders[document_number]; */
char userInfo[500];
char hostname[80];
char domainname[80];
WAISMSGBUFF request_msg = NULL;
WAISMSGBUFF response_msg = NULL;
SearchResponseAPDU* retrieval_response = NULL;
WAISDocumentText* fragmentText;
any* fragment = NULL;
any* document_text = NULL;
long count = 0, message_length = MAX_MESSAGE_LENGTH;
FILE *connection = NULL;
int retval;
int fd = -1;
if (server_name[0] == '\0' && service[0] == '\0')
connection = NULL; /* do local searching */
else /* remote search, fill in defaults*/
{ if (server_name[0] == '\0')
/*default to local machine*/
gethostname(server_name,MAX_SERVER_LENGTH);
if (service[0] == '\0')
strcpy(service, Z39_50_SERVICE); /* default */
if ((connection = connectToServer(server_name,atoi(service))) == NULL)
{ p_err_string = qsprintf_stcopyr(p_err_string, Err_Connect,
server_name, service);
RETURN (-1);
}
}
request_msg = waismsgbuff_alloc();
response_msg = waismsgbuff_alloc();
gethostname(hostname, 80);
getdomainname(domainname, 80);
sprintf(userInfo, "prospero gateway from host: %s.%s", hostname, domainname);
if((message_length =
initConnection(request_msg->buff,
response_msg->buff,
message_length,
connection,
userInfo)) <= 0) {
p_err_string = qsprintf_stcopyr(p_err_string, Err_Connect,
server_name, service);
RETURN(-1);
}
if (DocumentType == NULL) DocumentType = s_strdup("TEXT");
/* we must retrieve the document in parts since it might be very long*/
while (TRUE) {
if (waisRequestNext(connection, request_msg->buff,
response_msg->buff,
message_length, DocumentID, DocumentType, database, count)) {
freeAny(document_text);
RETURN(-1);
}
readSearchResponseAPDU(&retrieval_response,
response_msg->buff + HEADER_LENGTH);
if(NULL ==
((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Text) {
p_err_string = qsprintf_stcopyr(p_err_string,
"No text was returned");
freeAny(document_text);
RETURN(-1);
} else {
fragmentText = ((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Text[0];
fragment = fragmentText->DocumentText;
if (fd == -1) {
if ((fd = open(local,O_WRONLY|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH))
== -1) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Unable to open %s: %s", local, unixerrstr());
RETURN(-1);
}
}
if ((write(fd,fragment->bytes,fragment->size * sizeof(char))) == -1) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Unable to write %d characters to %s: %s",
fragment->size,local,unixerrstr());
RETURN(-1);
}
}
/* Under normal behaviour it will loop until it encounters a diagnostic
saying read beyond end of document, and then return */
if(((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Diagnostics != NULL) {
showDiags(((WAISSearchResponse *)
retrieval_response->DatabaseDiagnosticRecords)->Diagnostics);
p_err_string = qsprintf_stcopyr(p_err_string, "Diagnostic records received");
RETURN(0);
}
count++;
freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( retrieval_response);
retrieval_response = NULL;
}
RETURN(0);
cleanup:
if (fd != -1) close(fd);
/* Dont check error - may fail if other error)*/
if (retrieval_response) {
freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( retrieval_response);
}
if (connection) fclose(connection);
waismsgbuff_free(request_msg);
waismsgbuff_free(response_msg);
return(retval);
}
/* returns a pointer into the buffer of the next free byte.
if it overflowed, then NULL is returned
*/
char *
generate_retrieval_apdu(buff,
buff_len,
docID,
chunk_type,
start,
end,
type,
database_name)
char *buff;
long *buff_len; /* length of the buffer changed to reflect new data written */
any *docID;
long chunk_type;
long start;
long end;
char *type;
char *database_name;
{
SearchAPDU *search;
char *end_ptr;
char *database_names[2];
char *element_names[3];
any refID;
DocObj *DocObjs[2];
any *query; /* changed from char* by brewster */
if(NULL == type)
type = s_strdup("TEXT");
database_names[0] = database_name;
database_names[1] = NULL;
element_names[0] = " ";
element_names[1] = ES_DocumentText;
element_names[2] = NULL;
refID.size = 1;
refID.bytes = "3";
switch(chunk_type){
case CT_line:
DocObjs[0] = makeDocObjUsingLines(docID, type, start, end);
break;
case CT_byte:
DocObjs[0] = makeDocObjUsingBytes(docID, type, start, end);
break;
}
DocObjs[1] = NULL;
query = makeWAISTextQuery(DocObjs);
search = makeSearchAPDU( 10L, 16L, 15L,
1L, /* replace indicator */
"FOO", /* result set name */
database_names, /* database name */
QT_TextRetrievalQuery, /* query_type */
element_names, /* element name */
&refID, /* reference ID */
query);
end_ptr = writeSearchAPDU(search, buff, buff_len);
/* s_free(DocObjs[0]->Type); it's a copy of the input, don't free it! */
CSTFreeDocObj(DocObjs[0]);
CSTFreeWAISTextQuery(query);
freeSearchAPDU(search);
return(end_ptr);
}
long initConnection(char* inBuffer, /*!! Large malloced buffer */
char* outBuffer, /*!! Large malloced bugger */
long bufferSize,
FILE* connection,
char* userInfo)
{
InitAPDU* init = NULL;
InitResponseAPDU* reply = NULL;
long result;
long retval;
/* construct an init APDU */
init = makeInitAPDU(true,false,false,false,false,bufferSize,bufferSize,
userInfo,defaultImplementationID(),
defaultImplementationName(),
defaultImplementationVersion(),
NULL,userInfo);
/* write it to the buffer */
if ((result =
writeInitAPDU(init,inBuffer+HEADER_LENGTH,&bufferSize) - inBuffer
) <0)
RETURN(-1);
if (interpret_message(inBuffer,
result - HEADER_LENGTH,
outBuffer,
bufferSize,
connection,
WAIS_verbose /* true verbose */
) == 0)
/* error making a connection */
RETURN (-1);
if ((readInitResponseAPDU(&reply,outBuffer + HEADER_LENGTH) == NULL) ||
(reply->Result == false))
RETURN(-1);
/* we got a response back */
result = reply->MaximumRecordSize;
RETURN(result);
cleanup:
if (reply) {
freeWAISInitResponse((WAISInitResponse*)reply->UserInformationField);
freeInitResponseAPDU(reply);
}
freeInitAPDU(init);
return(retval);
}
/* returns a pointer in the buffer of the first free byte.
if it overflows, then NULL is returned
*/
char*
generate_search_apdu(char* buff, /* buffer to hold the apdu */
long* buff_len, /* buffer length changed for new data */
char* seed_words, /* string of the seed words */
char* database_name, /* copied */
DocObj** docobjs,
long maxDocsRetrieved)
{
/* local variables */
SearchAPDU *search3;
char *end_ptr;
/* This is copied, nothing gained if static*/
char *database_names[2] = {"", 0};
any refID;
WAISSearch *query;
refID.size = 1;
refID.bytes = "3";
database_names[0] = database_name;
query = makeWAISSearch(seed_words, /*pointed at */
docobjs, /* DocObjsPtr */
0L,
1L, /* DateFactor */
0L, /* BeginDateRange */
0L, /* EndDateRange */
maxDocsRetrieved
);
search3 = makeSearchAPDU(30L,
5000L, /* should be large */
30L,
1L, /* replace indicator */
"", /* result set name */
database_names, /* database name (copied)*/
QT_RelevanceFeedbackQuery, /* query_type */
0L, /* element name */
NULL, /* reference ID */
query);
end_ptr = writeSearchAPDU(search3, buff, buff_len);
CSTFreeWAISSearch(query);
freeSearchAPDU(search3); /* frees copy of database_names */
return(end_ptr);
}
/* returns the number of bytes written. 0 if an error */
long
interpret_message(char* request_message,
long request_length, /* length of the buffer */
char* response_message,
long response_buffer_length,
FILE* connection,
boolean verbose)
{
long response_length;
writeWAISPacketHeader(request_message,
request_length,
(long)'z', /* Z39.50 */
"wais ", /* server name */
(long)NO_COMPRESSION, /* no compression */
(long)NO_ENCODING,(long)HEADER_VERSION);
if(connection != NULL) {
if(0 ==
(response_length =
transport_message(connection, request_message,
request_length,
response_message,
response_buffer_length)))
return(0);
}
else{
p_err_string = qsprintf_stcopyr(p_err_string,
"Local search not supported in this version");
return(0);
}
#if !defined(IN_RMG) && !defined(PFS_THREADS)
if(verbose){
printf ("decoded %ld bytes: \n", response_length);
twais_dsply_rsp_apdu(response_message + HEADER_LENGTH,
request_length);
}
#endif
return(response_length);
}
/* this is a safe version of unix 'read' it does all the checking
* and looping necessary
* to those trying to modify the transport code to use non-UNIX streams:
* This is the function to modify!
*/
long read_from_stream(d,buf,nbytes)
long d; /* this is the stream */
char *buf;
long nbytes;
{
long didRead;
long toRead = nbytes;
long totalRead = 0; /* paranoia */
while (toRead > 0){
didRead = quick_read (d, buf, toRead, TIMEOUT_WAIS_READ);
if(didRead == -1) /* error*/
return(-1);
if(didRead == 0) /* eof */
return(-2); /* maybe this should return 0? */
toRead -= didRead;
buf += didRead;
totalRead += didRead;
}
if(totalRead != nbytes) /* we overread for some reason */
return(- totalRead); /* bad news */
return(totalRead);
}
/* returns the length of the response, 0 if an error */
long
transport_message(FILE* connection,
char* request_message,
long request_length,
char* response_message,
long response_buffer_length)
{
WAISMessage header;
long response_length;
/* Write out message. Read back header. Figure out response length. */
if( request_length + HEADER_LENGTH
!= fwrite (request_message, 1L, request_length + HEADER_LENGTH, connection))
return 0;
fflush(connection);
/* read for the first '0' */
while(1){
if(0 > read_from_stream(fileno(connection), response_message, 1))
return 0;
if('0' == response_message[0])
break;
}
if(0 > read_from_stream(fileno(connection),
response_message + 1,
HEADER_LENGTH - 1))
return 0;
readWAISPacketHeader(response_message, &header);
{
char length_array[11];
strncpy(length_array, header.msg_len, 10);
length_array[10] = '\0';
response_length = atol(length_array);
/*
if(verbose){
printf("WAIS header: '%s' length_array: '%s'\n",
response_message, length_array);
}
*/
if(response_length > response_buffer_length){
/* we got a message that is too long, therefore empty the message out,
and return 0 */
long i;
for(i = 0; i < response_length; i++){
read_from_stream(fileno(connection),
response_message + HEADER_LENGTH,
1);
}
return(0);
}
}
if(0 > read_from_stream(fileno(connection),
response_message + HEADER_LENGTH,
response_length))
return 0;
return(response_length);
}
/* modified from Jonny G's version in ui/question.c */
void showDiags(d)
diagnosticRecord **d;
{
long i;
for (i = 0; d[i] != NULL; i++) {
if (d[i]->ADDINFO != NULL) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Code: %s, %s", d[i]->DIAG, d[i] ->ADDINFO);
}
}
}
/* Convert docid into newly stalloc-ed DocumentId */
any *
un_urlascii(char *docid)
{
int i=0;
int j=0; /* Pointer into string for writing */
any *DocumentId;
DocumentId = (any *)malloc(sizeof(any));
if (!DocumentId) out_of_memory();
/* Converted string cant be longer than docid */
DocumentId->bytes = stalloc(strlen(docid)+1);
while (docid[i]) {
if (docid[i] != '%') {
DocumentId->bytes[j++]=docid[i++];
} else {
int conv;
i++;
sscanf(&docid[i],"%2x",&conv);
DocumentId->bytes[j++] = (char)conv;
i += 2;
}
}
DocumentId->size = j;
return DocumentId;
}
int
waisRetrieveFileByHsoname(char *local,char *hsoname)
{
any *DocumentId = NULL;
char *host = NULL;
char *port = NULL;
char *type = NULL;
char *database = NULL;
char *query = NULL;
int tmp;
int retval;
tmp = qsscanf(hsoname, "WAIS-GW/%&[^(](%&[^)])/%&[^/]/%&[^/]/%&[^/]/%[^\n]",
&host, &port, &type, &database, &query);
if (tmp != 5) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Invalid WAIS hsoname: %s", hsoname);
RETURN(-1);
}
DocumentId = un_urlascii(query);
RETURN(waisRetrieveFile(host,port,database,
DocumentId,type,0,local));
cleanup:
if (DocumentId) {
stfree(DocumentId->bytes);
free(DocumentId);
}
stfree(host);
stfree(port);
stfree(type);
stfree(database);
stfree(query);
return(retval);
}

View File

@@ -0,0 +1,35 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
#ifndef interface_h
#define interface_h
#include "wprot.h" /* For WAISSearchResponse */
#define Z39_50_SERVICE "210"
#define MAX_MESSAGE_LENGTH 100000
#define MAX_SERVER_LENGTH 1000
WAISSearchResponse* waisQuery (char* server_name,
char* service,
char* database,
char* keywords);
any* waisRetrieve(char* server_name,
char* service,
char* database,
any* DocumentID,
char* DocumentType,
long DocumentLength);
extern any *un_urlascii(char *docid);
#endif
/*---------------------------------------------------------------------------*/

View File

@@ -0,0 +1,772 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
/********************************************************
* Writing and reading structures to files. *
* *
* These use the Lisp printer format with the *
* lisp naming conventions. You ask: "Why would *
* you want to use that?". Well, we need an *
* easily readable data syntax that can handle *
* a large number of different data types. *
* Further, we need it to be tagged so that *
* run time tagged languages can read it and *
* it is flexible. We need one that supports *
* optional fields so that the format can *
* grow backcompatibly. And (the kicker), *
* it must be read from many languages since *
* user interfaces may be written in anything *
* from smalltalk to hypercard. *
* *
* -brewster 5/10/90 *
********************************************************/
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <pfs.h>
#include <perrno.h>
#include "irfileio.h"
#include "cutil.h"
#define INDENT_SPACES (2L)
#define MAX_INDENT (40L)
#ifdef NOTUSEDANDNOTTHREADSAFE
static long indent_level;
#endif /*NOTUSEDANDNOTTHREADSAFE
#define RETURN(val) {retval = val; goto cleanup; }
/**********************/
/**********************/
#ifdef NOTUSEDANDNOTTHREADSAFE
static void indent(FILE* file);
static void indent(file)
FILE* file;
{
long i;
for(i = 0; i <= MIN(MAX_INDENT, MAX(0L, indent_level * INDENT_SPACES)); i++){
putc(' ', file);
}
}
long WriteStartOfList(file)
FILE* file;
{
indent_level++;
return(fprintf(file, " ( "));
}
long WriteEndOfList(file)
FILE* file;
{
indent_level--;
return(fprintf(file, " ) "));
}
long WriteStartOfStruct(name,file)
char* name;
FILE* file;
{
indent_level++;
return(fprintf(file, " (:%s ", name));
}
long WriteEndOfStruct(file)
FILE* file;
{
indent_level--;
return(fprintf(file, " ) "));
}
long WriteSymbol(name,file)
char* name;
FILE* file;
{
return(fprintf(file, " %s ", name));
}
long WriteNewline(file)
FILE* file;
{
long return_value = fprintf(file, "\n");
indent(file);
return(return_value);
}
long WriteLong(number,file)
long number;
FILE* file;
{
return(fprintf(file, " %ld ", number));
}
long WriteDouble(number,file)
double number;
FILE* file;
{
return(fprintf(file, " %f ", number));
}
long WriteString(string,file)
char* string;
FILE* file;
{
long i;
putc('\"', file);
for(i = 0; i < strlen(string); i++){
if(string[i] == '\\' || string[i] == '\"')
putc('\\', file);
putc(string[i], file);
}
putc('\"', file);
return(1);
}
long WriteAny(value,file)
any* value;
FILE* file;
{
WriteStartOfStruct("any", file);
WriteSymbol(":size", file); WriteLong(value->size, file);
WriteSymbol(":bytes", file);
Write8BitArray(value->size, value->bytes, file);
return(WriteEndOfStruct(file));
}
long Write8BitArray(length,array,file)
long length;
char* array;
FILE* file;
{
long i;
fprintf(file, " #( ");
for(i=0; i<length; i++){
WriteLong((long)array[i], file);
}
return(fprintf(file, " ) "));
}
long WriteTM(atime,file)
struct tm* atime;
FILE* file;
{
WriteStartOfStruct("tm", file);
WriteSymbol(":tm-sec", file); WriteLong(atime->tm_sec, file);
WriteSymbol(":tm-min", file); WriteLong(atime->tm_min, file);
WriteSymbol(":tm-hour", file); WriteLong(atime->tm_hour, file);
WriteSymbol(":tm-mday", file); WriteLong(atime->tm_mday, file);
WriteSymbol(":tm-mon", file); WriteLong(atime->tm_mon, file);
WriteNewline(file);
WriteSymbol(":tm-year", file); WriteLong(atime->tm_year, file);
WriteSymbol(":tm-wday", file); WriteLong(atime->tm_wday, file);
WriteNewline(file);
WriteSymbol(":tm-yday", file); WriteLong(atime->tm_yday, file);
WriteSymbol(":tm-isdst", file); WriteLong(atime->tm_isdst, file);
WriteEndOfStruct(file);
return(WriteNewline(file));
}
boolean
writeAbsoluteTime(atime,file)
struct tm* atime;
FILE* file;
{
WriteStartOfStruct("absolute-time",file);
WriteNewline(file);
WriteSymbol(":year",file); WriteLong((long)atime->tm_year,file);
WriteNewline(file);
WriteSymbol(":month",file); WriteLong((long)atime->tm_mon,file);
WriteNewline(file);
WriteSymbol(":mday",file); WriteLong((long)atime->tm_mday,file);
WriteNewline(file);
WriteSymbol(":hour",file); WriteLong((long)atime->tm_hour,file);
WriteNewline(file);
WriteSymbol(":minute",file); WriteLong((long)atime->tm_min,file);
WriteNewline(file);
WriteSymbol(":second",file); WriteLong((long)atime->tm_sec,file);
WriteNewline(file);
return(WriteEndOfStruct(file));
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/************************/
/************************/
#define BEFORE (1L)
#define DURING (2L)
#define HASH (3L)
#define S (4L)
#define QUOTE (5L)
#if !defined(IN_RMG)
boolean ReadStartOfList(file)
FILE* file;
{
long ch;
while(TRUE){
ch = getc(file);
if(ch == '(')
return(TRUE);
if(!isspace(ch)){
if(ch == 'N' || ch == 'n'){
ch = getc(file);
if(ch == 'I' || ch == 'i'){
ch = getc(file);
if(ch == 'L' || ch == 'l'){
ungetc(')', file);
return(TRUE);
}
}
}
return(FALSE);
}
}
}
boolean ReadEndOfList(file)
FILE* file;
{
long ch;
while(TRUE){
ch = getc(file);
if(ch == ')')
return(TRUE);
if(!isspace(ch))
return(FALSE);
}
}
#endif /*!IN_RMG*/
#define STRING_ESC '\\'
long
SkipObject(file)
FILE* file;
{
long ch;
while (true)
{ ch = getc(file);
if (ch == EOF)
return (EOF);
else
{ if (isspace(ch))
continue;
else if (ch == '"')
{ long escapeCount = 0;
while (true)
{ ch = getc(file);
if (ch == EOF)
return (EOF);
else
{ if (ch == STRING_ESC)
{ escapeCount++;
escapeCount = escapeCount % 2;
}
if (ch == '"' && escapeCount == 0)
break;
}
}
break;
}
else if ((isdigit(ch) || ch == '-' || ch == '.') ||
(ch == ':'))
{ while (!isspace(ch))
{ ch = getc(file);
if (ch == EOF)
return(EOF);
}
break;
}
else if ((ch == '#') ||
(ch == '('))
{ long parenCount = 1;
if (ch == '#')
ch = getc(file);
while (parenCount > 0)
{ ch = getc(file);
if (ch == EOF)
return(EOF);
else if (ch == '"')
{
ungetc(ch,file);
SkipObject(file);
}
else if (ch == '(')
parenCount++;
else if (ch == ')')
parenCount--;
}
break;
}
}
}
return(true);
}
long ReadLong(file,answer)
FILE* file;
long* answer;
{
long ch;
long state = BEFORE;
boolean isNegative = false;
long count = 0;
*answer = 0;
while(TRUE){
ch = getc(file);
if (ch == EOF){
break;
}
else if (isdigit(ch)){
if(state == BEFORE){
state = DURING;
}
count++;
if(count == 12){
return(false);
}
*answer = *answer * 10 + (ch - '0');
}
else if (ch == '-') {
if (isNegative)
return(false);
if (state == BEFORE) {
isNegative = true;
state = DURING;
}
else {
ungetc(ch,file);
break;
}
}
else if(ch == ')' && (state == DURING)){
ungetc(ch, file);
return(true);
}
else if(!isspace(ch)){
return(false);
}
else if(state == DURING){
ungetc(ch, file);
break;
}
}
if (isNegative)
*answer *= -1;
return(true);
}
long ReadDouble(file,answer)
FILE* file;
double* answer;
{
long ch;
long state = BEFORE;
long count = 0;
long decimal_count = 0;
*answer = 0.0;
while(TRUE){
ch = getc(file);
if (ch == EOF){
return(true);
}
else if (ch == '.'){
decimal_count ++;
}
else if (isdigit(ch)){
if(state == BEFORE){
state = DURING;
}
count++;
if(count == 12){
return(false);
}
if (decimal_count == 0){
*answer = *answer * 10 + (ch - '0');
}
else{
double fraction = (ch - '0');
long internal_count;
for(internal_count = 0; internal_count < decimal_count;
internal_count++){
fraction = fraction / 10.0;
}
*answer = *answer + fraction;
decimal_count++;
}
}
else if(!isspace(ch)){
return(false);
}
else if(state == DURING){
ungetc(ch, file);
return(true);
}
}
}
static boolean issymbolchar(long ch);
static
boolean issymbolchar(ch)
long ch;
{
return(!( isspace(ch) || ch == ')' || ch == '(' || ch == EOF));
}
long ReadSymbol(string,file,string_size)
char* string;
FILE* file;
long string_size;
{
long ch;
long state = BEFORE;
long position = 0;
while(TRUE){
ch = getc(file);
if((state == BEFORE) && (ch == ')'))
return(END_OF_STRUCT_OR_LIST);
if(issymbolchar((long)ch)){
if(state == BEFORE)
state = DURING;
string[position] = ch;
position++;
if(position >= string_size){
string[string_size - 1] = '\0';
return(FALSE);
}
}
else if((state == DURING) || ch == EOF){
if(ch != EOF) ungetc(ch, file);
string[position] = '\0';
return(TRUE);
}
}
}
#if !defined(IN_RMG)
long ReadEndOfListOrStruct(file)
FILE* file;
{
long ch;
while(TRUE){
ch = getc(file);
if (EOF == ch)
return(FALSE);
else if(')' == ch)
return(TRUE);
else if(!isspace(ch))
return(FALSE);
}
}
#endif
long ReadString(string,file,string_size)
char* string;
FILE* file;
long string_size;
{
long ch;
long state = BEFORE;
long position = 0;
string[0] = '\0';
while(TRUE){
ch = getc(file);
if((state == BEFORE) && (ch == '\"'))
state = DURING;
else if (EOF == ch){
string[position] = '\0';
return(FALSE);
}
else if ((state == BEFORE) && (ch == ')'))
return(END_OF_STRUCT_OR_LIST);
else if ((state == DURING) && (ch == '\\'))
state = QUOTE;
else if ((state == DURING) && (ch == '"')){
string[position] = '\0';
return(TRUE);
}
else if ((state == QUOTE) || (state == DURING)){
if(state == QUOTE)
state = DURING;
string[position] = ch;
position++;
if(position >= string_size){
string[string_size - 1] = '\0';
return(FALSE);
}
}
}
}
long ReadStartOfStruct(name,file)
char* name;
FILE* file;
{
int ch;
long state = BEFORE;
name[0] = '\0';
while(TRUE){
ch = getc(file);
if((state == BEFORE) && (ch == '#'))
state = HASH;
if((state == BEFORE) && (ch == '('))
state = DURING;
else if((state == BEFORE) && (ch == ')'))
return(END_OF_STRUCT_OR_LIST);
else if((state == BEFORE) && !isspace(ch))
return(FALSE);
else if(state == HASH){
if (ch == 's')
state = S;
else{
fprintf(stderr,"Expected an 's' but got an %c\n", ch);
return(FALSE);
}
}
else if(state == S){
if (ch == '(')
state = DURING;
else{
fprintf(stderr,"Expected an '(' but got an an %c\n",ch);
return(FALSE);
}
}
else if(state == DURING){
return(ReadSymbol(name, file, MAX_SYMBOL_SIZE));
}
}
}
long CheckStartOfStruct(name,file)
char* name;
FILE* file;
{
char temp_string[MAX_SYMBOL_SIZE];
long result = ReadStartOfStruct(temp_string, file);
if(result == END_OF_STRUCT_OR_LIST)
return(END_OF_STRUCT_OR_LIST);
else if(result == FALSE)
return(FALSE);
else if(0 == strcmp(temp_string, name))
return(TRUE);
else
return(FALSE);
}
#if !defined(IN_RMG)
long ReadAny(destination,file)
any* destination;
FILE* file;
{
char temp_string[MAX_SYMBOL_SIZE];
long retval;
destination->size = 0;
if(FALSE == CheckStartOfStruct("any", file)){
fprintf(stderr,"An 'any' structure was not read from the disk");
return(FALSE);
}
while(TRUE){
long check_result;
check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
if(FALSE == check_result)
return(FALSE);
if(END_OF_STRUCT_OR_LIST == check_result)
RETURN(TRUE);
if(0 == strcmp(temp_string, ":size")) {
long size;
ReadLong(file,&size);
destination->size = (unsigned long)size;
}
else if(0 == strcmp(temp_string, ":bytes")){
long result;
destination->bytes = (char*)s_malloc(destination->size);
if(NULL == destination->bytes){
/* May never get here, s_malloc may abort if no space */
p_err_string = qsprintf_stcopyr(p_err_string,
"Error on reading file. Malloc couldnt allocate %d bytes",
destination->size );
RETURN(FALSE);
}
result = Read8BitArray(destination->bytes, file, destination->size);
if(FALSE == result)
RETURN(FALSE);
}
else{
p_err_string = qsprintf_stcopyr(p_err_string,
"Unknown keyword for ANY %s\n", temp_string);
RETURN(FALSE);
}
} /*while*/
cleanup:
/* For now, not freeing destination->bytes on error, let caller do it*/
return(retval);
}
long
Read8BitArray(char *destination, FILE *file,long len)
{
int ch; /* don't use a long, because %c conversion
isn't defined for longs. */
long state = BEFORE;
while(TRUE){
ch = getc(file);
if((state == BEFORE) && ((ch == '#') || (ch == '('))) {
if (ch == '(') state = DURING;
else state = HASH;
}
else if((state == BEFORE) && !isspace(ch)){
fprintf(stderr,"error in reading array. Expected # and got %c", ch);
return(FALSE);
}
else if(state == HASH){
if (ch == '(')
state = DURING;
else{
fprintf(stderr,"Expected an '(' but got an %c\n", ch);
return(FALSE);
}
}
else if(state == DURING){
long i;
ungetc(ch, file);
for(i = 0; i < len; i++){
long value;
if(ReadLong(file,&value) == false){
fprintf(stderr,"Error in reading a number from the file.");
return(FALSE);
}
if(value > 255){
fprintf(stderr,"Error in reading file. Expected a byte in an ANY, but got %ld", value);
return(FALSE);
}
destination[i] = (char)value;
}
if(FALSE == ReadEndOfListOrStruct(file)){
fprintf(stderr,"array was wrong length");
return(FALSE);
}
return(TRUE);
}
}
}
boolean
readAbsoluteTime(atime,file)
struct tm* atime;
FILE* file;
{
if (CheckStartOfStruct("absolute-time",file) == FALSE)
return(false);
while (true)
{ long result;
long val;
char temp_string[MAX_SYMBOL_SIZE + 1];
result = ReadSymbol(temp_string,file,MAX_SYMBOL_SIZE);
if (result == END_OF_STRUCT_OR_LIST)
break;
else if (result == false)
return(false);
if (strcmp(temp_string,":second") == 0)
{ if (ReadLong(file,&val) == false)
return(false);
atime->tm_sec = val;
}
else if (strcmp(temp_string,":minute") == 0)
{ if (ReadLong(file,&val) == false)
return(false);
atime->tm_min = val;
}
else if (strcmp(temp_string,":hour") == 0)
{ if (ReadLong(file,&val) == false)
return(false);
atime->tm_hour = val;
}
else if (strcmp(temp_string,":mday") == 0)
{ if (ReadLong(file,&val) == false)
return(false);
atime->tm_mday = val;
}
else if (strcmp(temp_string,":month") == 0)
{ if (ReadLong(file,&val) == false)
return(false);
atime->tm_mon = val;
}
else if (strcmp(temp_string,":year") == 0)
{ if (ReadLong(file,&val) == false)
return(false);
atime->tm_year = val;
}
else
SkipObject(file);
}
return(true);
}
#endif

View File

@@ -0,0 +1,46 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
#ifndef IRCFILEIO_H
#define IRCFILEIO_H
#include "cdialect.h"
#include "futil.h"
#include "zprot.h"
#define MAX_SYMBOL_SIZE (255L)
#define END_OF_STRUCT_OR_LIST (6L)
long SkipObject(FILE* file);
long ReadLong(FILE* file,long* num);
long ReadDouble(FILE* file,double* num);
long ReadSymbol(char* string, FILE* file, long string_size);
long ReadString(char* string, FILE* file, long string_size);
long CheckStartOfStruct(char* name, FILE* file);
long ReadAny(any* destination, FILE* file);
long ReadTM(struct tm* /* time */, FILE* file);
long Read8BitArray(char* destination, FILE* file, long /* length */);
long ReadEndOfListOrStruct(FILE* file);
long ReadStartOfStruct(char* name, FILE* file);
boolean ReadStartOfList(FILE* file);
boolean ReadEndOfList(FILE* file);
boolean readAbsoluteTime(struct tm* /* time */,FILE* file);
long WriteStartOfStruct(char* name, FILE* file);
long WriteEndOfStruct(FILE* file);
long WriteSymbol(char* name, FILE* file);
long WriteString(char* string, FILE* file);
long WriteNewline(FILE* file);
long WriteLong(long number, FILE* file);
long WriteDouble(double number, FILE* file);
long WriteAny(any* value, FILE* file);
long Write8BitArray(long /* length */, char* array, FILE* file);
long WriteTM(struct tm* /* time */, FILE* file);
long WriteStartOfList(FILE* file);
long WriteEndOfList(FILE* file);
boolean writeAbsoluteTime(struct tm* /* time */,FILE* file);
#endif

View File

@@ -0,0 +1,217 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
#include "list.h"
/*---------------------------------------------------------------------------*/
void
mapcar(list l,void (*function)())
{
long i;
if (null(l))
return;
for (i = 0; i < length(l); i++)
{ (*function)(nth(l,i));
}
}
/*---------------------------------------------------------------------------*/
list
collecting(list l,void *item)
{
if (l == NULL)
if (!(l = (list)s_malloc(sizeof(listStruct))))
return NULL;
if (l->rlen < length(l) + 1)
{ l->rlen = length(l) + 2;
l->elems = (void**)s_realloc(l->elems,l->rlen * sizeof(void*));
}
l->elems[length(l)] = item;
l->len++;
return(l);
}
/*---------------------------------------------------------------------------*/
void
freeList(list l)
{
if (l != NULL)
{ s_free(l->elems);
s_free(l);
}
}
/*---------------------------------------------------------------------------*/
static long
cmpStrings(void* arg1,void* arg2)
{
return(strcmp(*(char**)arg1,*(char**)arg2));
}
/*---------------------------------------------------------------------------*/
void
sortList(list l,long (*cmp)())
{
if (cmp == NULL)
cmp = cmpStrings;
if (length(l) > 1)
qsort(l->elems,length(l),sizeof(void*),cmp);
}
/*---------------------------------------------------------------------------*/
list
insertNth(list l,long n,void* elem)
{
if (null(l))
return(NULL);
if (n > length(l))
return(NULL);
if (l->rlen < length(l) + 1)
{ l->rlen = length(l) + 2;
l->elems = (void**)s_realloc(l->elems,l->rlen*sizeof(void*));
}
memmove(l->elems+n+1,l->elems+n,(length(l)-n)*sizeof(void*));
l->elems[n] = elem;
l->len++;
return(l);
}
/*---------------------------------------------------------------------------*/
list
removeNth(list l,long n)
{
if (null(l))
return(NULL);
if (n >= length(l))
return(NULL);
memmove(l->elems+n,l->elems+n+1,(length(l)-n-1)*sizeof(void*));
l->len--;
if (l->rlen > 4 && l->rlen > length(l) * 2)
{ l->rlen = length(l);
l->elems = (void**)s_realloc(l->elems,l->rlen * sizeof(void*));
}
return(l);
}
/*---------------------------------------------------------------------------*/
boolean
lookupInSortedList(list l,void* val,long (*cmpFunc)(void* arg1,void* arg2),
long* posInList)
{
long pos;
long upperBound = length(l);
long lowerBound = 0;
long cmp;
void* data;
if (null(l))
{ if (posInList != NULL)
*posInList = 0;
return(false);
}
if (cmpFunc == NULL)
cmpFunc = cmpStrings;
while (upperBound >= lowerBound)
{
pos = lowerBound + ((upperBound - lowerBound) / 2);
if (pos == length(l))
cmp = -1;
else
{ data = nth(l,pos);
cmp = (*cmpFunc)(&val,&data);
}
if (cmp == 0)
{ if (posInList != NULL)
*posInList = pos;
return(true);
}
else if (cmp < 0)
{ if (pos == lowerBound)
{ if (posInList != NULL)
*posInList = pos;
return(false);
}
else
upperBound = pos;
}
else
{ if (pos >= length(l))
{ if (posInList != NULL)
*posInList = pos;
return(false);
}
else
lowerBound = pos + 1;
}
}
if (posInList != NULL)
*posInList = length(l);
return(false);
}
/*---------------------------------------------------------------------------*/
void*
pop(list* l)
{
void* ans;
if (l == NULL || *l == NULL)
return(NULL);
ans = first(*l);
*l = removeNth(*l,0);
return(ans);
}
/*---------------------------------------------------------------------------*/
void
push(list* l,void* elem)
{
if (l == NULL)
return;
*l = insertNth(*l,0,elem);
}
/*---------------------------------------------------------------------------*/

View File

@@ -0,0 +1,57 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
#ifndef list_h
#define list_h
#include "cutil.h"
/*---------------------------------------------------------------------------*/
typedef struct listStruct
{ void** elems;
long len;
long rlen;
} listStruct;
#define list listStruct*
#define length(l) (long)(((l) == NULL) ? 0L : (l)->len)
#define nth(l,n) \
(((l) == NULL || length((l)) <= (n)) ? NULL : (l)->elems[(n)])
#define car(l) (nth((l),0L))
#define cadr(l) (nth((l),2L))
#define cdr(l) (removeNth((l),0L))
#define first(l) (car(l))
#define last(l) (nth((l),length((l))-1L))
#define rest(l) (cdr(l))
#define setfNth(l,n,elem) \
(((l) == NULL || length((l)) <= (n)) ? 0 : ((l)->elems[(n)] = (elem)))
#define setfCar(l,elem) (setfNth((l),0L,(elem)))
#define null(l) (((l) == NULL || length((l)) == 0L) ? true : false)
void mapcar(list l,void function (void* argument));
list collecting(list l,void *item);
void freeList(list l);
void sortList(list l,long (*cmp)(void* arg1,void* arg2));
list insertNth(list l,long n,void* elem);
list removeNth(list l,long n);
boolean lookupInSortedList(list l,void* val,
long (*cmpFunc)(void* arg1,void* arg2),
long* posInList);
void* pop(list* l);
void push(list* l,void* elem);
/*---------------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,4 @@
main()
{
}

View File

@@ -0,0 +1,53 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
#include <ctype.h>
#include "panic.h"
#include "waislog.h"
#include "cutil.h"
#include <pfs.h> /* for stcopyr() */
#include <perrno.h>
extern int fault_count;
/*----------------------------------------------------------------------*/
void
panic(char* formatString,...)
/* something bad and unexpected has happened, print out a log message
and abort the program in such a way that it can be debugged.
*/
{
va_list ap;
char msg[2000];
va_start(ap,formatString);
vsprintf(msg,formatString,ap);
#if !defined(IN_RMG)
#if !defined(PFS_THREADS)
waislog(WLOG_HIGH,WLOG_ERROR,msg);
#else
#error NO WAY TO LOG - DONT COMPILE LIKE THIS
#endif
#else
p_err_string = stcopyr(p_err_string, msg);
/* restart_server(fault_count, msg); */
#endif
va_end(ap);
#ifdef THINK_C
Debugger();
#endif
abort();
}
/*----------------------------------------------------------------------*/

View File

@@ -0,0 +1,15 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
#ifndef panic_h
#define panic_h
#include "cdialect.h"
void panic(char* formatString,...);
#endif

View File

@@ -0,0 +1,184 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
#define sockets_c
#include "sockets.h"
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <posix_signal.h>
#include "panic.h"
#include "waislog.h"
/* In theory this is defined in stdio.h, but its hosed on SOLARIS */
extern FILE *fdopen(const int fd, const char *opt);
extern char *sys_errlist[];
#define QUEUE_SIZE (3L)
#define HOSTNAME_BUFFER_SIZE (120L)
#define MAX_RETRYS (10L)
#define TIMEOUT_CONNECT 5
/*---------------------------------------------------------------------------*/
#if !defined(IN_RMG) && !defined(PFS_THREADS)
static boolean
clrSocket(struct sockaddr_in *address,long portnumber,long *sock)
{
if (errno == EADDRINUSE)
{ if (connect(*sock, address, sizeof (struct sockaddr_in)) == 0)
{ close(*sock);
waislog(WLOG_HIGH,WLOG_ERROR,
"cannot bind port %ld (address already in use)",
portnumber);
waislog(WLOG_HIGH,WLOG_ERROR,
"waisserver is already running on this system");
panic("Exiting");
}
else
{ int one = 1;
close(*sock);
if ((*sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
panic("Open socket failed in trying to clear the port.");
if (setsockopt(*sock,SOL_SOCKET,SO_REUSEADDR,&one,sizeof(one)) < 0)
; /* do nothing? */
address->sin_family = AF_INET;
address->sin_addr.s_addr = INADDR_ANY;
address->sin_port = htons(portnumber);
if (bind(*sock, address, sizeof(*address)) == 0)
; /* do nothing? */
}
}
return(true);
}
/*---------------------------------------------------------------------------*/
void
openServer(long port,long* fd,long size)
{
struct sockaddr_in address;
memset(&address, 0, sizeof(address));
if ((*fd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{ panic("can't get file descriptor for socket: %s", sys_errlist[errno]);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(port);
if (bind(*fd,(struct sockaddr*)&address,sizeof(struct sockaddr)) < 0)
clrSocket(&address, port, fd);
if (listen(*fd,QUEUE_SIZE) < 0)
panic("can't open server: %s", sys_errlist[errno]);
}
/*---------------------------------------------------------------------------*/
void
fdAcceptClientConnection(long socket,long* fd)
{
struct sockaddr_in source;
int sourcelen;
#ifdef BSD
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
u_long S_addr;
} S_un;
} addr_p;
#endif
sourcelen = sizeof(struct sockaddr_in);
do {
errno = 0;
*fd = accept(socket, &source, &sourcelen);
} while (*fd < 0 && errno == EINTR);
if (source.sin_family == AF_INET)
{ struct hostent *peer = NULL;
peer = gethostbyaddr((char*)&source.sin_addr, 4, AF_INET);
waislog(WLOG_MEDIUM,WLOG_CONNECT,"accepted connection from: %s [%s]",
(peer == NULL) ? "" : peer->h_name,
#if defined(sparc) && defined(__GNUC__) && !defined(__svr4__)
inet_ntoa(&source.sin_addr));
#else
inet_ntoa(source.sin_addr));
#endif /* sparc */
}
if (*fd < 0)
panic("can't accept connection");
}
/*---------------------------------------------------------------------------*/
void
acceptClientConnection(long socket,FILE** file)
{
long fd;
fdAcceptClientConnection(socket,&fd);
if ((*file = fdopen(fd,"r+")) == NULL)
panic("can't accept connection");
}
/*---------------------------------------------------------------------------*/
void
closeClientConnection(FILE* file)
{
fclose(file);
}
/*---------------------------------------------------------------------------*/
void
closeServer(long socket)
{
close(socket);
}
#endif /*!IN_RMG && !PFS_THREADS*/
/*---------------------------------------------------------------------------*/
FILE *
connectToServer(char* host_name,long port)
{
FILE* file;
int fd;
if ((fd = quick_open_tcp_stream(host_name, port, TIMEOUT_CONNECT)) == -1)
return(NULL);
if ((file = fdopen(fd,"r+")) == NULL)
{ perror("Connect to socket did not work, fdopen failure");
close(fd);
return(NULL);
}
return(file);
}
/*---------------------------------------------------------------------------*/
void
closeConnectionToServer(FILE* file)
{
fclose(file);
}
/*---------------------------------------------------------------------------*/

View File

@@ -0,0 +1,37 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*---------------------------------------------------------------------------*/
#ifndef sockets_h
#define sockets_h
#include "cdialect.h"
#include "cutil.h"
#ifndef THINK_C
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#endif
/*---------------------------------------------------------------------------*/
void openServer(long port,long* socket,long size);
void acceptClientConnection(long socket,FILE** file);
void closeClientConnection(FILE* file);
void closeServer(long socket);
FILE *connectToServer(char* hostname,long port);
void closeConnectionToServer(FILE* file);
/*---------------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,835 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
This is part of the shell user-interface tools for the WAIS software.
*/
/*---------------------------------------------------------------------------*/
#define _C_SOURCE
#include <string_with_strcasecmp.h>
#include <stdio.h>
#include "cutil.h"
#include "futil.h"
#include "irfileio.h"
#include "source.h"
#include <list_macros.h> /* For TH_APPEND_LIST*/
#include <mitra_macros.h> /* For TH_FIND_LIST */
#include <psrv.h> /* includes global declarations of
waissource_count and waissource_max to be
read. */
#define DESC_SIZE 65535
extern int alphasort();
#if !defined(IN_RMG) && !defined(PFS_THREADS)
SList Sources;
/* I'm not sure why this is all commented out, looks like its been
superceeded by "SList Sources" */
char **Source_items = NULL;
#else
WAISSOURCE WaisSources = NULL;
#endif /*!IN_RMG && !PFS_THREADS*/
char *sourcepath = NULL;
#if !defined(IN_RMG) && !defined(PFS_THREADS)
void
freeSourceID(sid)
SourceID sid;
{
if (sid != NULL) {
if (sid->filename != NULL) s_free(sid->filename);
s_free(sid);
}
}
SourceID
copysourceID(sid)
SourceID sid;
{
SourceID result = NULL;
if(sid != NULL) {
if((result = (SourceID) s_malloc(sizeof(_SourceID))) != NULL) {
result->filename = s_strdup(sid->filename);
}
}
return result;
}
char **
buildSourceItemList(sourcelist)
SourceList sourcelist;
{
char **result;
int num, i;
SourceList source;
/* find the length of the sidlist in the question */
for (num = 0, source = sourcelist;
source != NULL && source->thisSource != NULL;
num++, source = source->nextSource);
result = (char**)s_malloc((1+num)*sizeof(char*));
if(num > 0)
for(i =0, source = sourcelist; i<num; i++, source = source->nextSource)
result[i] = source->thisSource->filename;
result[num] = NULL;
return(result);
}
char **
buildSItemList(sourcelist)
SList sourcelist;
{
char **result;
int num, i;
SList source;
/* find the length of the sidlist in the question */
for(num = 0, source = sourcelist;
source != NULL;
num++, source = source->nextSource);
result = (char**) s_malloc((1+num)*sizeof(char*));
if(num > 0)
for(i =0, source = sourcelist; i<num; i++, source = source->nextSource)
if(source->thisSource != NULL)
result[i] = source->thisSource->name;
result[num] = NULL;
return(result);
}
static short
ReadSourceID(file, sid)
FILE *file;
SourceID sid;
{
char temp_string[MAX_SYMBOL_SIZE];
char filename[MAX_SYMBOL_SIZE];
short check_result;
check_result = CheckStartOfStruct("source-id", file);
filename[0] = '\0';
if(FALSE == check_result){
return(false);
}
if(END_OF_STRUCT_OR_LIST == check_result)
{
return(FALSE);
}
/* read the slots: */
while(TRUE){
short check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
if(END_OF_STRUCT_OR_LIST == check_result) break;
if(FALSE == check_result){
return(false);
}
if(0 == strcmp(temp_string, ":filename")) {
if (FALSE == ReadString(filename, file, MAX_SYMBOL_SIZE))
return(false);
sid->filename = s_strdup(filename);
}
else
SkipObject(file);
}
return(TRUE);
}
SourceList ReadListOfSources(file)
FILE *file;
{
short check_result;
SourceID sid = NULL;
SourceList result, this, last;
/* initialize */
this = last = result = NULL;
if(ReadStartOfList(file) == FALSE)
return(NULL);
while(TRUE) {
sid = (SourceID)s_malloc(sizeof(_SourceID));
check_result = ReadSourceID(file, sid);
if(check_result == END_OF_STRUCT_OR_LIST) {
s_free(sid);
return(result);
}
else if(check_result == FALSE)
return(result);
else if(check_result == TRUE) {
if(result == NULL)
result = this = (SourceList)s_malloc(sizeof(_SourceList));
else
this = (SourceList)s_malloc(sizeof(_SourceList));
this->thisSource = sid;
if(last != NULL)
last->nextSource = this;
last = this;
}
}
}
#endif /*!defined(IN_RMG) && !defined(PFS_THREADS)*/
/* from util.c */
void find_value(source, key, value, value_size)
char *source, *key, *value;
int value_size;
{
char ch;
long position = 0; /* position in value */
char *pos =(char*)strstr(source, key); /* address into source */
value[0] = '\0'; /* initialize to nothing */
if(NULL == pos)
return;
pos = pos + strlen(key);
ch = *pos;
/* skip leading quotes and spaces */
while((ch == '\"') || (ch == ' ')) {
pos++; ch = *pos;
}
for(position = 0; pos < source + strlen(source); pos++){
if((ch = *pos) == ' ') {
value[position] = '\0';
return;
}
value[position] = ch;
position++;
if(position >= value_size){
value[value_size - 1] = '\0';
return;
}
}
value[position] = '\0';
}
static boolean
ReadSource(WAISSOURCE source, FILE *file)
{
char temp_string[MAX_SYMBOL_SIZE];
char desc_string[DESC_SIZE];
short check_result;
long port;
long version;
/* make sure it's a Source */
check_result = CheckStartOfStruct("source", file);
if(FALSE == check_result){
return(false);
}
if(END_OF_STRUCT_OR_LIST == check_result)
{
return(FALSE);
}
strcpy(source->server, "");
strcpy(source->service, "");
/* read the slots: */
while(TRUE){
short check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
if((END_OF_STRUCT_OR_LIST == check_result) ||
(EOF == check_result))
break;
if(FALSE == check_result){
return(false);
}
if(0 == strcmp(temp_string, ":version")) {
if(FALSE == ReadLong(file, &version))
return(false);
}
else if(0 == strcmp(temp_string, ":ip-name")) {
if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
return(false);
strcpy(source->server, temp_string);
}
else if(0 == strcmp(temp_string, ":ip-address")) {
if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
return(false);
strcpy(source->server, temp_string);
}
else if(0 == strcmp(temp_string, ":configuration")) {
if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
return(false);
find_value(temp_string, "IPAddress", source->server, STRINGSIZE);
find_value(temp_string, "RemotePort", source->service, STRINGSIZE);
}
else if(0 == strcmp(temp_string, ":tcp-port")) {
if(FALSE == ReadLong(file, &port))
return(false);
sprintf(source->service,"%d", port);
}
else if(0 == strcmp(temp_string, ":port")) {
if(FALSE == ReadLong(file, &port))
return(false);
sprintf(source->service,"%d", port);
}
else if(0 == strcmp(temp_string, ":maintainer")) {
if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
return(false);
if(source->maintainer != NULL) s_free(source->maintainer);
source->maintainer = s_strdup(temp_string);
}
else if(0 == strcmp(temp_string, ":database-name")) {
if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
return(false);
strcpy(source->database, temp_string);
}
else if(0 == strcmp(temp_string, ":cost")) {
double cost;
if(FALSE == ReadDouble(file, &cost))
return(false);
sprintf(source->cost, "%.2f", cost);
}
else if(0 == strcmp(temp_string, ":cost-unit")) {
if(FALSE == ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE))
return(false);
strcpy(source->units, temp_string);
}
else if(0 == strcmp(temp_string, ":subjects")) {
if(FALSE == ReadString(desc_string, file, DESC_SIZE))
return(false);
if(source->subjects != NULL) s_free(source->subjects);
source->subjects = s_strdup(desc_string);
}
else if(0 == strcmp(temp_string, ":description")) {
if(FALSE == ReadString(desc_string, file, DESC_SIZE))
return(false);
if(source->description != NULL) s_free(source->description);
source->description = s_strdup(desc_string);
}
else if(0 == strcmp(temp_string, ":update-time")) {
if(EOF == SkipObject(file)) break;
}
else
if(EOF == SkipObject(file)) break; /* we don't know the key, so we don't know how
to interpret the value, skip it */
}
return(TRUE);
}
static boolean
ReadSourceFile(WAISSOURCE asource, char *filename, char *directory)
{
FILE *fp;
char pathname[MAX_FILENAME_LEN+1];
boolean result;
strncpy(pathname, directory, MAX_FILENAME_LEN);
strncat(pathname, filename, MAX_FILENAME_LEN);
if((fp = locked_fopen(pathname, "r")) == NULL)
return FALSE;
asource->name = s_strdup(filename);
asource->directory = s_strdup(directory);
result = ReadSource(asource, fp);
locked_fclose_A(fp,pathname,TRUE);
return(result);
}
/* Read sourcefile "name" from one of the directories in "sourcepath"
and add to Sources (creating that if neccessary). Return source found
to make it quicker next time */
static WAISSOURCE
loadSource(name, sourcepath)
char *name;
char *sourcepath;
{
char *i, *p, source_dir[MAX_FILENAME_LEN];
WAISSOURCE source = waissource_alloc();
/*
if(sourcepath == NULL || sourcepath[0] == 0) {
if((sourcepath = (char*)getenv("WAISSOURCEPATH")) == NULL)
return NULL;
}
*/
for (p = sourcepath, i = p;
i != NULL;
p = i+1) {
if((i = (char*)strchr(p, ':')) == NULL)
strcpy(source_dir, p);
else {
strncpy(source_dir, p, i-p);
source_dir[i-p] = 0;
}
if(ReadSourceFile(source, name, source_dir)) {
set_connection(source);
TH_APPEND_ITEM(source,WaisSources,WAISSOURCE);
return (source);
}
}
s_free(source);
source = NULL;
return (source);
}
static int
match_connection(WAISSOURCE asource, WAISSOURCE bsource)
{
return (!strcmp(asource->server,bsource->server) &&
!strcmp(asource->service,bsource->service));
}
/* Try and copy parameters from another source we've already looked at */
static void
set_connection(WAISSOURCE source)
{
WAISSOURCE s = WaisSources;
TH_FIND_OBJFNCTN_LIST(s,source,match_connection,WAISSOURCE)
if (s) {
source->connection = s->connection;
source->buffer_length = s->buffer_length;
source->initp = s->initp;
}
}
#if !defined(IN_RMG) && !defined(PFS_THREADS)
#ifdef NEVERDEFINED
boolean newSourcep(name)
char *name;
{
SList s;
for (s = Sources; s != NULL; s = s->nextSource)
if((s->thisSource != NULL) &&
!strcmp(name, s->thisSource->name))
return FALSE;
return TRUE;
}
#endif
boolean is_source(name, test)
char *name;
boolean test;
{
char lastchar;
lastchar = name[strlen(name)-1];
if(test)
return ((strlen(name) > 4) &&
strstr(name, ".src") &&
(!strcmp(".src", strstr(name, ".src"))));
else
return (lastchar != '~' &&
lastchar != '#' &&
strcmp(name, ".") &&
strcmp(name, ".."));
}
#ifdef USINGSOURCEITEMS
static boolean newSource(name)
char *name;
{
int i;
for(i =0; i < NumSources; i++)
if(!strcmp(name, Source_items[i]))
return FALSE;
return TRUE;
}
static int
issfile(dp)
struct dirent *dp;
{
return(is_source(dp->d_name, TRUE) &&
newSource(dp->d_name));
}
void SortSourceNames(n)
int n;
{
boolean Changed = TRUE;
int i;
char *qi;
while(Changed) {
Changed = FALSE;
for(i = 0; i < n-1; i++)
if(0 < strcasecmp(Source_items[i], Source_items[i+1])) {
Changed = TRUE;
qi = Source_items[i];
Source_items[i] = Source_items[i+1];
Source_items[i+1] = qi;
}
}
}
void
GetSourceNames(directory)
char *directory;
{
/* Note result is returned in global Source_items */
struct dirent **list;
int i, j;
assert(P_IS_THIS_THREAD_MASTER());
if ((j = scandir(directory, &list, issfile, alphasort)) < 0) {
PrintStatus(STATUS_INFO, STATUS_HIGH, "Error on open of source directory: %s.\n", directory);
return;
}
if(NumSources > 0)
Source_items = (char**) s_realloc(Source_items, (NumSources+j+1) * sizeof(char*));
else {
if(Source_items != NULL) {
for (i = 0; Source_items[i] != NULL; i++) s_free(Source_items[i]);
s_free(Source_items);
}
Source_items = (char**) s_malloc((j+1) * sizeof(char*));
}
for (i = 0; i < j; i++) {
Source_items[i+NumSources] = s_strdup(list[i]->d_name);
s_free(list[i]);
}
NumSources+=j;
SortSourceNames(NumSources);
Source_items[NumSources] = NULL;
s_free(list);
}
#endif /*USINGSOURCEITEMS*/
/* read all the sources from a directory. If test is true, only files ending
in .src are valid
*/
/* Not used */
#if !defined(IN_RMG)
static void
ReadSourceDirectory(directory, test)
char *directory;
boolean test;
{
char filename[MAX_FILENAME_LEN];
FILE *fp;
int i, j , newNumSources;
SList Last;
Source source;
struct dirent **list;
assert(P_IS_THIS_THREAD_MASTER());
if ((j = scandir(directory, &list, NULL, NULL)) < 0) {
return;
}
if(Sources == NULL)
Sources = makeSList(NULL, NULL);
for(Last = Sources; Last->nextSource != NULL; Last = Last->nextSource);
for (i = 0; i < j; i++) {
if (is_source(list[i]->d_name, test)) {
if(newSourcep(list[i]->d_name)) {
strcpy(filename, directory);
strcat(filename, list[i]->d_name);
if ((fp = locked_fopen(filename, "r")) != NULL) {
source = (Source)s_malloc(sizeof(_Source));
memset(source, 0, sizeof(_Source));
source->initp = FALSE;
source->name = s_strdup(list[i]->d_name);
source->directory = s_strdup(directory);
ReadSource(source, fp);
locked_fclose_A(fp,filename,TRUE);
if(Last->thisSource == NULL)
Last->thisSource = source;
else {
Last->nextSource = makeSList(source, NULL);
Last = Last->nextSource;
}
NumSources++;
}
}
}
}
free((char *)list);
}
#endif
void WriteSource(directory, source, overwrite)
char *directory;
Source source;
boolean overwrite;
{
char filename[MAX_FILENAME_LEN];
FILE *fp;
strcpy(filename, directory);
strcat(filename, source->name);
if (overwrite == FALSE)
if ((fp = locked_fopen(filename, "r")) != NULL) {
PrintStatus(STATUS_INFO, STATUS_HIGH,
"File %s exists, click again to overwrite.\n", filename);
locked_fclose_A(fp,filename,TRUE);
return;
}
if ((fp = locked_fopen(filename, "w")) == NULL) {
PrintStatus(STATUS_INFO, STATUS_HIGH, "Error opening %s.\n", filename);
return;
}
fprintf(fp, "(:source\n :version 3\n");
if(source->server != NULL)
if(source->server[0] != 0)
if(isdigit(source->server[0]))
fprintf(fp, " :ip-address \"%s\"\n", source->server);
else
fprintf(fp, " :ip-name \"%s\"\n", source->server);
if(source->service != NULL)
if(source->service[0] != 0)
fprintf(fp, " :tcp-port %s\n", source->service);
fprintf(fp, " :database-name \"%s\"\n", source->database);
if(source->cost != NULL)
if(source->cost[0] != 0)
fprintf(fp, " :cost %s \n", source->cost);
else
fprintf(fp, " :cost 0.00 \n");
if(source->units != NULL)
if(source->units[0] != 0)
fprintf(fp, " :cost-unit %s \n", source->units);
else
fprintf(fp, " :cost-unit :free \n");
if(source->maintainer != NULL)
if(source->maintainer[0] != 0)
fprintf(fp, " :maintainer \"%s\"\n",
source->maintainer);
else
fprintf(fp, " :maintainer \"%s\"\n",
current_user_name());
if(source->description != NULL)
if(source->description[0] != 0) {
fprintf(fp, " :description ");
WriteString(source->description, fp);
}
else
fprintf(fp, " :description \"Created with %s by %s on %s.\"\n",
command_name, current_user_name(), printable_time());
fprintf(fp, "\n)");
locked_fclose_A(fp,filename,FALSE);
}
SourceList
makeSourceList(source, rest)
SourceID source;
SourceList rest;
{
SourceList result;
if((result = (SourceList)s_malloc(sizeof(_SourceList))) != NULL) {
result->thisSource = source;
result->nextSource = rest;
}
return(result);
}
SList
makeSList(source, rest)
Source source;
SList rest;
{
SList result;
if((result = (SList)s_malloc(sizeof(_SList))) != NULL) {
result->thisSource = source;
result->nextSource = rest;
}
return(result);
}
void FreeSource(source)
Source source;
{
if (source != NULL) {
if(source->name != NULL)
s_free (source->name);
if(source->directory != NULL)
s_free (source->directory);
if(source->description != NULL)
s_free (source->description);
if(source->maintainer != NULL)
s_free (source->maintainer);
s_free(source);
}
}
#endif /*!IN_RMG && !PFS_THREADS*/
/* Find the source name, in either Sources, or it not found try and load it
from anywhere in sourcepath */
WAISSOURCE
findsource(char *name, char *sourcepath)
{
WAISSOURCE asource = WaisSources;
TH_FIND_STRING_LIST(asource,name,name,WAISSOURCE);
if (asource)
return asource;
return (loadSource(name, sourcepath));
}
#if !defined(IN_RMG) && !defined(PFS_THREADS)
void
format_source_cost(str,source)
char *str;
Source source;
{
sprintf(str,"Free");
if ((source->units != NULL) && (source->cost != NULL)) {
if(0 == strcmp(source->units, ":dollars-per-query"))
sprintf(str,"$%s/query",source->cost);
if(0 == strcmp(source->units, ":dollars-per-minute"))
sprintf(str,"$%s/minute",source->cost);
if(0 == strcmp(source->units, ":dollars-per-retrieval"))
sprintf(str,"$%s/retrieval",source->cost);
if(0 == strcmp(source->units, ":dollars-per-session"))
sprintf(str,"$%s/session",source->cost);
if(0 == strcmp(source->units, ":other"))
sprintf(str,"Special",source->cost);
}
}
void
freeSourceList(slist)
SourceList slist;
{
SourceList sl;
while(slist != NULL) {
sl = slist;
freeSourceID(sl->thisSource);
slist = sl->nextSource;
s_free(sl);
}
}
/*
#include <sockets.h>
*/
/*#define FORWARDER_SERVER "quake"*/
/* send an init message to the source. A side effect is that the
negotiation of buffer sizes. The final size is put in
source->buffer_length
*/
#ifdef NEVERDEFINED
boolean init_for_source(source, request, length, response)
Source source;
char *request;
long length;
char *response;
{
char userInfo[500];
char message[500];
char hostname[80];
char domain[80];
gethostname(hostname, 80);
getdomainname(domain, 80);
#ifdef TELL_USER
sprintf(userInfo, "%s %s, from host: %s.%s, user: %s",
command_name, VERSION, hostname, domain, getenv("USER"));
#else
sprintf(userInfo, "%s %s, from host: %s.%s",
command_name, VERSION, hostname, domain);
#endif
if(source->initp == FALSE) {
if(source->server[0] == 0)
source->connection = NULL;
else {
source->connection = connect_to_server(source->server,
atoi(source->service));
#ifdef FORWARDER_SERVER
#ifndef FORWARDER_SERVICE
#define FORWARDER_SERVICE "210"
#endif
if(source->connection == NULL) {
strncat(source->database, "@", STRINGSIZE);
strncat(source->database, source->server, STRINGSIZE);
strncat(source->database, ":", STRINGSIZE);
strncat(source->database, source->service, STRINGSIZE);
strncpy(source->server, FORWARDER_SERVER, STRINGSIZE);
strncpy(source->service, FORWARDER_SERVICE, STRINGSIZE);
source->connection = connect_to_server(source->server,
atoi(source->service));
}
#endif
if (source->connection == NULL) {
PrintStatus(STATUS_URGENT, STATUS_HIGH, "Bad Connection to server.");
source->initp = FALSE;
return source->initp;
}
}
source->buffer_length =
init_connection(request, response,
length,
source->connection,
userInfo);
if (source->buffer_length < 0) {
PrintStatus(STATUS_URGENT, STATUS_HIGH,
"\nError connecting to server: %s service: %s.",
source->server, source->service);
source->initp = FALSE;
}
else {
SList s;
source->initp = TRUE;
for (s = Sources; s != NULL; s = s->nextSource) {
if (s->thisSource != source) {
if (strcmp(s->thisSource->server, source->server) == 0 &&
strcmp(s->thisSource->service, source->service) == 0) {
s->thisSource->connection = source->connection;
s->thisSource->buffer_length = source->buffer_length;
s->thisSource->initp = TRUE;
}
}
}
}
return source->initp;
}
return source->initp;
}
#endif
#endif /*!IN_RMG && PFS_THREADS*/

View File

@@ -0,0 +1,104 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
This is part of the user-interface for the WAIS software.
*/
/*---------------------------------------------------------------------------*/
#ifndef _H_SOURCE
#define _H_SOURCE
#define STRINGSIZE 256
#ifndef boolean
#define boolean int
#endif
/* #include <cdialect.h> */
#ifdef IN_RMG
#include <pfs.h> /* for ALLOCATOR_CONSISTENCY_CHECK*/
#endif
typedef struct SourceID {
char *filename;
} _SourceID, *SourceID;
struct waissource{
#ifdef ALLOCATOR_CONSISTENCY_CHECK
int consistency;
#endif
char *name;
char *directory;
char server[STRINGSIZE];
char service[STRINGSIZE];
char database[STRINGSIZE];
char cost[STRINGSIZE];
char units[STRINGSIZE];
char *description;
FILE *connection;
long buffer_length;
boolean initp;
char *maintainer;
char *subjects;
#ifdef IN_RMG
struct waissource *next;
struct waissource *previous;
#endif
};
typedef struct waissource *WAISSOURCE;
typedef struct waissource WAISSOURCE_ST;
/* functions */
extern WAISSOURCE waissource_alloc();
extern void waissource_free(WAISSOURCE source);
extern void waissource_lfree(WAISSOURCE source);
extern void waissource_freespares();
#ifdef PFS_THREADS
extern p_th_mutex p_th_mutexWAISSOURCE;
#endif
#ifdef NEVERDEFINED
/* Uses SourceList which is obsoleted by waissource
rebuild if need these functions in Prospero */
#if !defined(IN_RMG) && !defined(PFS_THREADS)
void freeSourceID (SourceID sid);
SourceID copysourceID (SourceID sid);
char** buildSourceItemList (SourceList sourcelist);
char** buildSItemList (SList sourcelist);
static short ReadSourceID (FILE* file, SourceID sid);
SourceList ReadListOfSources (FILE* fp);
#endif
#endif
static boolean ReadSource (WAISSOURCE source, FILE* file);
static boolean ReadSourceFile (WAISSOURCE asource, char* filename, char* directory);
static WAISSOURCE loadSource (char* name, char* sourcepath);
static void set_connection (WAISSOURCE source);
#ifdef NEVERDEFINED
#if !defined(IN_RMG) && !defined(PFS_THREADS)
boolean newSourcep (char* name);
boolean is_source (char* name, boolean test);
void SortSourceNames (int n);
void GetSourceNames (char* directory);
static void ReadSourceDirectory (char* directory, boolean test);
void WriteSource (char* directory, Source source, boolean overwrite);
SourceList makeSourceList (SourceID source, SourceList rest);
SList makeSList (Source source, SList rest);
void FreeSource (Source source);
void FreeSources (SList sources);
#endif
#endif
WAISSOURCE findsource (char* name, char* sourcepath);
#ifdef NEVERDEFINED
#if !defined(IN_RMG) && !defined(PFS_THREADS)
Source findSource (int n);
void format_source_cost (char* str, Source source);
void freeSource (SourceID sourceID);
void freeSourceList (SourceList slist);
boolean init_for_source (Source source, char* request,
long length, char* response);
#endif /*!IN_RMG && !PFS_THREADS */
#endif
#endif

View File

@@ -0,0 +1,138 @@
/* Copyright (c) 1993, by Pandora Systems */
/* Author: Mitra <mitra@path.net> */
/* Allocation code copied and adapted from:
prospero/alpha.5.2a+/lib/pfs/flalloc */
#include "buffalloc.h"
#include <pfs.h>
#include <pfs_threads.h>
#include <mitra_macros.h>
#include "source.h"
#define Channel_Illegal 0;
EXTERN_ALLOC_DECL(WAISSOURCE);
static WAISSOURCE lfree = NULL; /* Free waissources */
/* These are global variables which will be read by dirsrv.c
Too bad C doesn't have better methods for structuring such global data. */
int waissource_count = 0;
int waissource_max = 0;
/************* Standard routines to alloc, free and copy *************/
/*
* waissource_alloc - allocate and initialize WAISSOURCE structure
*
* returns a pointer to an initialized structure of type
* WAISSOURCE. If it is unable to allocate such a structure, it
* signals out_of_memory();
*/
WAISSOURCE
waissource_alloc()
{
WAISSOURCE awaissource;
TH_STRUC_ALLOC(waissource,WAISSOURCE,awaissource);
awaissource->name = NULL;
awaissource->directory = NULL;
awaissource->description = NULL;
awaissource->connection = NULL;
awaissource->maintainer = NULL;
awaissource->subjects = NULL;
return(awaissource);
}
/*
* waissource_free - free a WAISSOURCE structure
*
* waissource_free takes a pointer to a WAISSOURCE structure and adds it to
* the free list for later reuse.
*/
void
waissource_free(WAISSOURCE awaissource)
{
stfree(awaissource->name); awaissource->name = NULL;
stfree(awaissource->directory); awaissource->directory = NULL;
stfree(awaissource->description); awaissource->description = NULL;
stfree(awaissource->connection); awaissource->connection = NULL;
stfree(awaissource->maintainer); awaissource->maintainer = NULL;
stfree(awaissource->subjects); awaissource->subjects = NULL;
TH_STRUC_FREE(waissource,WAISSOURCE,awaissource);
}
/*
* waissource_lfree - free a linked list of WAISSOURCE structures.
*
* waissource_lfree takes a pointer to a waissource structure frees it and
* any linked
* WAISSOURCE structures. It is used to free an entire list of WAISSOURCE
* structures.
*/
void
waissource_lfree(awaissource)
WAISSOURCE awaissource;
{
TH_STRUC_LFREE(WAISSOURCE,awaissource,waissource_free);
}
void
waissource_freespares()
{
TH_FREESPARES(waissource,WAISSOURCE);
}
#ifdef NEVERDEFINED
/*
* waissource_copy - allocates a new waissource structure and
* initializes it with a copy of another
* waissource, v.
*
* If r is non-zero, successive waissources will be
* iteratively copied.
*
* awaissource-previous will always be null on the first link, and
* will be appropriately filled in for iteratively copied links.
*
* waissource_copy returns a pointer to the new structure of type
* WAISSOURCE. If it is unable to allocate such a structure, it
* returns NULL.
*
* waissource_copy will recursively copy the link associated with
* a waissource and
* its associated attributes.
*/
WAISSOURCE
waissource_copy(f,r)
WAISSOURCE f;
int r; /* Currently ignored. */
{
WAISSOURCE nf;
WAISSOURCE snf; /* Start of the chain of new links */
WAISSOURCE tf; /* Temporary link pointer */
nf = waissource_alloc();
snf = nf;
copyeach:
/* Copy f into nf */
#ifdef ALLOCATOR_CONSISTENCY_CHECK
assert(f->consistency == INUSE_PATTERN);
#endif
LOCAL STUFF NOT DEFINED
if(r && f->next) {
f = f->next;
tf = nf;
nf = waissource_alloc();
nf->previous = tf;
tf->next = nf;
goto copyeach;
}
return(snf);
}
#endif

Binary file not shown.

View File

@@ -0,0 +1,20 @@
#include <sys/types.h>
#include <stdio.h>
#include "source.h"
void
main(int argc, char *argv[])
{
char sourcename[512];
WAISSOURCE source = waissource_alloc();
sprintf(sourcename,"%s.src", argv[1]);
source = findsource(sourcename,
"/usr/local/wais/wais-sources/");
if (source == NULL) { fprintf(stderr,"Error finding source.\n"); }
else {
printf("%s %s %s\n",source->server, source->name, source->service);
}
}

View File

@@ -0,0 +1,186 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
#ifndef lint
static char *RCSid = "$Header: /buzza/cvsroot/technologies/archie-support/prospero/lib/psrv/wais_gw/ustubs.c,v 1.1.1.1 1999/03/18 16:50:52 pedro Exp $";
#endif
/* Change log:
* $Log: ustubs.c,v $
* Revision 1.1.1.1 1999/03/18 16:50:52 pedro
* This modules includes the prosper server and the berkeley db code used
* in Archie
*
* Revision 1.1.1.1 1994/08/31 16:33:09 bajan
* New Prospero release
*
* Revision 1.2 94/04/19 00:29:17 swa
* (mitra) assert(P_IS_THIS_THREAD_MASTER()) added in places.
* Added tests for SOLARIS
*
* Revision 1.1 93/11/10 13:35:08 swa
* Initial revision
*
* Revision 1.4 92/05/06 17:35:13 jonathan
* Modified some #if's for NeXT and Mach.
*
* Revision 1.3 92/03/06 11:08:49 jonathan
* fixed incompatible return type error in HP version of getwd. Thanks to
* cshotton@oac.hsc.uth.tmc.edu.
*
* Revision 1.2 92/02/12 13:54:29 jonathan
* Added "$Log" so RCS will put the log message in the header
*
*
*/
/*----------------------------------------------------------------------*/
/* stubs for silly non-ansi c compilers */
/*----------------------------------------------------------------------*/
#include "ustubs.h"
#include "futil.h" /* for MAX_FILENAME_LEN */
#include "cutil.h" /* for substrcmp and NULL */
#include <pmachine.h> /* For Solaris */
#include <stdlib.h> /* SOLARIS: for rand and srand */
#include <pfs_threads.h> /* For P_IS_THIS_THREAD_MASTER */
/*----------------------------------------------------------------------*/
#if (defined(__svr4__) || defined(hpux) || defined(SCOUNIX)) && !defined(SOLARIS)
char*
getwd(char* pathname)
{
return((char*)getcwd(pathname, MAX_FILENAME_LEN));
}
long
random(void)
{
assert(P_IS_THIS_THREAD_MASTER()); /*SOLARIS: rand, srand & random MT-Unsafe */
return(rand());
}
long
srandom(unsigned long seed)
{
assert(P_IS_THIS_THREAD_MASTER()); /*SOLARIS: rand, srand & random MT-Unsafe */
srand(seed);
return(0);
}
long
sigmask(long sig)
{
}
long
sigblock(long mask)
{
}
long
sigsetmask(long mask)
{
}
#endif
#if (defined(__svr4__) || defined(hpux))
#include <sys/systeminfo.h>
long
gethostname(char* hostname,long len)
{
return(sysinfo(SI_HOSTNAME,hostname,len));
}
#endif /* def SYSV */
/*----------------------------------------------------------------------*/
#ifndef ANSI_LIKE /* memmove is an ANSI function not defined by K&R */
#ifndef hpux /* but HP defines it */
void*
memmove(void* str1,void* str2,size_t n)
{
#ifdef M_XENIX
memcpy((char*)str2,(char*)str1,(long)n); /* hope it works! */
#else /* ndef M_XENIX */
bcopy((char*)str2,(char*)str1,(long)n);
#endif /* ndef M_XENIX */
return(str1);
}
#endif /* ndef hpux */
#else /* ansi is defined */
#ifdef __GNUC__ /* we are ansi like, are we gcc */
#if !(defined(NeXT) || defined(Mach) || defined(__svr4__))
/* and we are not on a next or solaris ! */
void*
memmove(void* str1,void* str2,size_t n)
{
bcopy((char*)str2,(char*)str1,(long)n);
return(str1);
}
#endif /* not NeXT or Mach */
#endif /* __GNUC__ */
#endif /* else ndef ANSI_LIKE */
/*----------------------------------------------------------------------*/
#ifndef ANSI_LIKE
/* atoi is not defined k&r. copied from the book */
long
atol(char* s)
{
long i, n, sign;
for(i=0; s[i]==' ' || s[i]== 'n' || s[i]=='t'; i++)
; /* skip white space */
sign = 1;
if (s[i] == '+' || s[i] == '-')
sign = (s[i++]=='+') ? 1 : -1;
for (n=0; s[i] >= '0' && s[i] <= '9'; i++)
n= 10 * n + s[i] - '0';
return(sign * n);
}
/*----------------------------------------------------------------------*/
char*
strstr(char* src,char* sub)
{
/* this is a poor implementation until the ANSI version catches on */
char *ptr;
for(ptr = src; (long)ptr <= (long)src + strlen(src) - strlen(sub); ptr++){
if(substrcmp(ptr, sub))
return(ptr);
}
return(NULL);
}
/*----------------------------------------------------------------------*/
int
remove(char* filename)
{
return(unlink(filename));
}
/*----------------------------------------------------------------------*/
#endif /* ndef ANSI_LIKE */

View File

@@ -0,0 +1,94 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
/* definitions that non-ansi (aka sun) C doesn't provide */
#ifndef USTUBS_H
#define USTUBS_H
#include "cdialect.h"
#ifndef ANSI_LIKE
#include <sys/types.h>
#ifdef M_XENIX
#include <string.h>
#endif /* ndef M_XENIX */
#ifndef size_t
#ifndef M_XENIX
#define size_t unsigned long
#endif /* ndf M_XENIX */
#endif /* ndef size_t */
#ifndef ANSI_LIKE
#ifndef M_XENIX
#define time_t long
#endif /* ndef M_XENIX */
#endif /* ndef ANSI_LIKE */
#ifdef K_AND_R /* this might be too general, but it is needed on vaxen */
#define void char
#endif /* ndef K_AND_R */
#ifdef __cplusplus
/* declare these as C style functions */
extern "C"
{
#endif /* def __cplusplus */
#ifndef SCOUNIX
char *strstr(char *src, char *sub);
#endif
#ifdef SYSV
char *getwd (char *pathname);
long random(void);
long srandom(unsigned long seed);
#ifndef SCOUNIX
#define rename(f1,f2) {link((f1),(f2)); unlink((f1)); }
#endif /*SCOUNIX*/
#endif /* defu SYSV */
#if !(defined(NeXT) || defined(Mach))
#ifndef M_XENIX
#ifndef cstar
char* malloc(size_t size);
char* calloc(size_t nelem,size_t elsize);
#ifndef SCOUNIX
void free(char* ptr);
#endif
char* realloc(char* ptr,size_t size);
#ifndef mips
#ifndef hpux
#ifndef vax
#ifndef SCOUNIX
char* memcpy(char* s1,char* s2,size_t c);
#endif
void* memmove(void* s1,void* s2,size_t n);
#endif /* ndef vax */
#endif /* ndef hpux */
#endif /* ndef mips */
char *strcat(char *s1, char *s2);
#endif /* ndef cstar */
#endif /* ndef M_XENIX */
#endif /* not NeXT or Mach */
long atol(char *s);
#ifdef __cplusplus
}
#endif /* def __cplusplus */
#else /* def ANSI_LIKE */
#endif /* else ndef ANSI_LIKE */
/*----------------------------------------------------------------------*/
#endif /* ndef USTUBS_H */

View File

@@ -0,0 +1,331 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-license.h>.
*/
#include <string.h>
#include <pmachine.h>
#include <psite.h> /* for WAIS_SOURCE_DIR */
#include <ardp.h>
#include <pfs.h>
#include <pserver.h>
#include <psrv.h>
#include <perrno.h>
#include <plog.h>
/* Could be local files. */
#include "wprot.h"
#include "zutil.h" /* for "any" */
#include "source.h" /* for Source */
#include "inface.h"
#include "wais_gw_dsdb.h"
#include "ietftype.h"
#include "ietftype_parse.h"
/* Definitions of constants */
#define MAX_NUM_WAIS_LINKS 3000 /* maximum # of directory links to
return before giving up. */
/* ======= Some forward definitions ============ */
static void
wsr_to_dirobj(WAISSearchResponse *wsr, P_OBJECT ob, char *host, char *port);
static VLINK DocHeader2vl(WAISDocumentHeader *wdh, char *host, char *port);
char *
read_wais_contents(char *host, char *port, char *type,
char *database, char *docid);
/* This function is passed an empty object which has been initialized with
oballoc(). It returns a possibly populated directory and
DIRSRV_NOT_FOUND or PSUCCESS. Note that the directory will need
to have links within it freed, even if an error code is returned. */
/* This sets p_warn_string and pwarn if a unrecognized record
or diagnostic record is received. That is good. */
/* Currently this routine doesnt handle all possible combinations of arguments*/
/* It handles:
Do a search
hsoname= "WAIS-GW/<host>(<port>)/QUERY/<database>/<query>"
Do a search - alternative
hsoname= "WAIS-GW/<host>(<port>)/QUERY/<database>"
listopts.thiscompp[0] = <query>
Retrieve a document
hsoname= "WAIS-GW/<host>(<port>)/<type>/<database>/<docid>"
listopts.requested_attrs="+CONTENTS+"
Get attribute information about database
hsoname= "WAIS-GW/<host>(<port>)/QUERY/<database>"
listopts.requested_attrs="+#ALL+"
listopts.thiscompp[0] = NULL
*/
int
wais_gw_dsdb(RREQ req, /* Request pointer (unused) */
char *hsoname, /* Name of the directory */
long version, /* Version #; currently ignored */
long magic_no, /* Magic #; currently ignored */
int flags, /* Currently only recognize DRO_VERIFY */
struct dsrobject_list_options *listopts, /* options (use *remcompp
and *thiscompp) */
P_OBJECT ob) /* Object to be filled in */
{
int tmp;
AUTOSTAT_CHARPP(hostp);
AUTOSTAT_CHARPP(portp);
AUTOSTAT_CHARPP(queryp);
AUTOSTAT_CHARPP(typep);
AUTOSTAT_CHARPP(databasep);
WAISSearchResponse *wsr;
char *str = NULL;
ob->version = 0; /* unversioned */
ob->magic_no = 0;
ob->inc_native = VDIN_PSEUDO;
ob->acl = NULL;
tmp = qsscanf(hsoname, "WAIS-GW/%&[^(](%&[^)])/%&[^/]/%&[^/]/%&[^/]/%[^\n]",
hostp, portp, typep, databasep, queryp);
if (requested_contents(listopts)) {
if (tmp == 4 && stequal(*typep,"HELP")) {
char *db_src = NULL;
WAISSOURCE thissource;
db_src = qsprintf_stcopyr(db_src,"%s.src",*databasep);
/* Dont free the source, its on a linked list for the duration*/
if (!(thissource = findsource(db_src,WAIS_SOURCE_DIR)))
return DIRSRV_WAIS;
ob_atput(ob,"CONTENTS","DATA",
thissource->description, (char *)0);
stfree(db_src);
return PSUCCESS;
}
if (tmp <5)
return DIRSRV_WAIS;
ob->flags = P_OBJECT_FILE;
if (!(str = read_wais_contents(*hostp,*portp,*typep,*databasep,*queryp)))
return DIRSRV_WAIS;
/* (char *)1 prevents copying of potentially huge str*/
ob_atput(ob, "CONTENTS", "DATA", (char *)1, str, (char *)0);
return PSUCCESS;
}
ob->flags = P_OBJECT_DIRECTORY;
if (tmp < 4)
return DIRSRV_NOT_FOUND;
/* For now only handle QUERY */
if (strcmp(*typep,"QUERY") != 0)
return DIRSRV_NOT_FOUND;
if (tmp <5) { /* look for query in components */
if (!listopts || !listopts->thiscompp || !*listopts->thiscompp ||
strequal(*listopts->thiscompp, "")
|| strequal(*listopts->thiscompp, "*")) {
/* last test against * might be inappropriate */
if (listopts->requested_attrs) {
char *w_db_src = NULL;
WAISSOURCE thissource; /* DONT free this */
w_db_src = qsprintf_stcopyr(w_db_src,"%s.src",*databasep);
ob_atput(ob,"OBJECT-INTERPRETATION", "SEARCH", NULL);
if (thissource = findsource(w_db_src,WAIS_SOURCE_DIR)) {
if (thissource->subjects)
ob_atput(ob,"WAIS-SUBJECTS", thissource->subjects, NULL);
if (thissource->cost)
ob_atput(ob,"WAIS-COST-NUM", thissource->cost, NULL);
if (thissource->units)
ob_atput(ob,"WAIS-COST-UNIT", thissource->units, NULL);
if (thissource->maintainer)
ob_atput(ob,"WAIS-MAINTAINER", thissource->maintainer, NULL);
ob_atput(ob, "QUERY-METHOD", "wais-query(search-words)",
"${search-words}", "", (char *) 0);
ob_atput(ob, "QUERY-ARGUMENT", "search-words",
"Index word(s) to search for", "mandatory char*",
"%s", "", (char *) 0);
if (thissource->description)
ob_atput(ob, "QUERY-DOCUMENTATION", "wais-query()",
thissource->description, (char *) 0);
ob_atput(ob, "QUERY-DOCUMENTATION", "search-words",
"This string says \
what you're searching for or what information you're specifying.",
"Type any string. Sometimes SPACEs are treated as implied \
'and' operators. Sometimes the words 'and', 'or', and 'not' are recognized \
as boolean operators.", (char *) 0);
}
stfree(w_db_src);
}
return PSUCCESS; /* Display no contents for the directory */
}
/* Set the selector. */
*queryp = stcopyr(*listopts->thiscompp, *queryp);
/* We just used up thiscompp, so we'd better reset it. */
if (listopts->remcompp && *listopts->remcompp) {
*listopts->thiscompp = (*listopts->remcompp)->token;
*listopts->remcompp = (*listopts->remcompp)->next;
} else {
*listopts->thiscompp = NULL;
}
}
if (flags & DRO_VERIFY) return PSUCCESS;
if ((wsr = waisQuery(*hostp,*portp,*databasep,*queryp)) == NULL)
return DIRSRV_WAIS; /* Need to decode wais errors sensibly */
wsr_to_dirobj(wsr,ob,*hostp,*portp);
freeWAISSearchResponse(wsr); wsr=NULL;
return PSUCCESS;
}
static void
wsr_to_dirobj(WAISSearchResponse *wsr, P_OBJECT ob, char *host, char *port)
{
/* Dont need to fuss around with magic numbers, these cant be replicas*/
PATTRIB at = atalloc();
VLINK vl = NULL;
int i;
long current_magic_no = 0L; /* set magic starting hash */
VLINK tempvl = NULL;
ob_atput(ob,"WAIS_SEED_WORDS",wsr->SeedWordsUsed, (char *)0);
if ( wsr->ShortHeaders
|| wsr->LongHeaders
|| wsr->Text
|| wsr->Headlines
|| wsr->Codes
|| wsr->Diagnostics
) {
pwarn = PWARNING;
p_warn_string = qsprintf_stcopyr(p_warn_string,
"Unrecognized search response");
}
/*!! Need to handle diagnostics - ignore others */
if (wsr->DocHeaders) {
for (i=0; wsr->DocHeaders[i]; i++) {
if (vl = DocHeader2vl(wsr->DocHeaders[i],host,port)) {
/* Add new magic no to all the links returned */
current_magic_no = generate_magic(vl);
while (magic_no_in_list(++current_magic_no, ob->links));
for (tempvl = vl; tempvl != NULL; tempvl= tempvl->next)
#ifdef NEVERDEFINED
tempvl->f_magic_no = current_magic_no;
#else
tempvl->f_magic_no = 0; /*clients dont understand result !!*/
#endif
APPEND_LISTS(ob->links, vl);
}
}
}
}
char *
urlascii(any *docid) {
char *str = stalloc(3 * docid->size);
int i;
int j;
for (i=0, j=0; i< docid->size; i++)
{
int c = docid->bytes[i];
if ((c < ' ') || (c > (char)126) || strchr("/\\{}|[]^~<>#%'",c)) {
str[j++] = '%' ;
sprintf(str+(j++),"%02x",c);
j++;
} else
str[j++] = c;
}
str[j] = '\0'; /* Null terminated */
return str;
};
static VLINK
DocHeader2vl(WAISDocumentHeader *wdh, char *host, char *port)
{
int i; /* Index into types */
VLINK vl;
VLINK head = NULL; /* Head of links being constructed */
char *str = NULL; /* thisstring can be stalloc-ed or stfree-ed*/
char *cp = NULL; /* this one cant */
IETFTYPE it;
PATTRIB at;
for (i=0; wdh->Types[i]; i++) {
vl = vlalloc();
vl->host = stcopy(hostwport);
str = urlascii(wdh->DocumentID); /* stalloc's string */
if ((cp=strrchr(wdh->Source,'/')) == NULL) {
cp = wdh->Source;
} else {
cp++;
}
vl->hsoname = qsprintf_stcopyr(vl->hsoname,"WAIS-GW/%s(%s)/%s/%s/%s",
host, port, wdh->Types[i], cp, str);
/*!! Check that Source always has a reasonable format */
if (it = wais_2_ietftype(wdh->Types[i])) {
if (at = atcopy(it->prosperotype)) {
APPEND_ITEM(at,vl->lattrib);
}
}
vl->name = stcopy(wdh->Headline);
if (wdh->VersionNumber)
vl->version = wdh->VersionNumber;
if (wdh->Score) {
vl_atput(vl, "WAIS-SCORE",
(str = qsprintf_stcopyr(str,"%d",wdh->Score)), (char *)0);
vl_atput(vl, "COLLATION-ORDER",
(str = qsprintf_stcopyr(str,"-%d",wdh->Score)), (char *)0);
}
if (wdh->BestMatch)
vl_atput(vl, "WAIS-BESTMATCH",
(str = qsprintf_stcopyr(str,"%d",wdh->BestMatch)), (char *)0);
vl_atput(vl, "SIZE",
(str = qsprintf_stcopyr(str,"%d",wdh->BestMatch)), (char *)0);
if (wdh->Lines)
vl_atput(vl, "WAIS-LINES",
(str = qsprintf_stcopyr(str,"%d",wdh->Lines)), (char *)0);
/*!! Should convert this date to asn (timetoasn & lib/psrv/dsrfinfo*/
/* and stuff in LAST-MODIFIED */
if (wdh->Date)
vl_atput(vl, "WAIS-DATE", wdh->Date, (char *)0);
if (wdh->OriginCity)
vl_atput(vl, "WAIS-ORIGINCITY", wdh->OriginCity, (char *)0);
/* Route all accesses through the host for now */
vl_atput(vl,"ACCESS-METHOD","WAIS","","","","", (char *)0);
/*vl_atput(vl,"ACCESS-METHOD","PROSPERO-CONTENTS","","","","", (char *)0);*/
if (strncmp("Search produced no result. Here's the Catalog",
vl->name, 45) == 0) {
vlfree(vl);
} else {
APPEND_ITEM(vl,head);
}
stfree(str);
} /*for*/
return(head);
}
char *
read_wais_contents(char *host, char *port, char *type,
char *database, char *docid)
{
any *dt;
char *str = NULL;
int len;
any *DocumentId;
DocumentId = un_urlascii(docid); /* Allocates DocumentID (throws length)*/
len = 0 ;
if (dt = waisRetrieve(host,port,database,DocumentId,type,len)) {
str = dt->bytes;
dt->bytes = NULL;
freeAny(dt);
}
stfree(DocumentId->bytes);
free(DocumentId);
return (str);
}

View File

@@ -0,0 +1,8 @@
extern int wais_gw_dsdb(RREQ req, /* Request pointer (unused) */
char *hsoname, /* Name of the directory */
long version, /* Version #; currently ignored */
long magic_no, /* Magic #; currently ignored */
int flags, /* Currently only recognize DRO_VERIFY */
struct dsrobject_list_options *listopts, /* options (use *remcompp
and *thiscompp) */
P_OBJECT ob); /* Object to be filled in */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 1991-1994 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-license.h>.
*/
#include <usc-license.h>
#include <pfs_threads.h>
#include "ietftype_parse.h"
#ifdef PFS_THREADS
p_th_mutex p_th_mutexWAISMSGBUFF; /* declaration */
p_th_mutex p_th_mutexIETFTYPE; /* declaration */
p_th_mutex p_th_mutexWAISSOURCE; /* declaration */
#endif
void
wais_gw_init_mutexes(void)
{
#ifdef PFS_THREADS
p_th_mutex_init(p_th_mutexWAISMSGBUFF);
p_th_mutex_init(p_th_mutexIETFTYPE);
p_th_mutex_init(p_th_mutexWAISSOURCE);
ietftype_init(); /* Safer than mutexing it */
#endif
}
#ifndef NDEBUG
void
wais_gw_diagnose_mutexes(void)
{
#ifdef PFS_THREADS
DIAGMUTEX(WAISMSGBUFF,"WAISMSGBUFF");
DIAGMUTEX(IETFTYPE,"IETFTYPE");
DIAGMUTEX(WAISSOURCE,"WAISSOURCE");
#endif
}
#endif /*NDEBUG*/

View File

@@ -0,0 +1,84 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
#define waislog_c
#if !defined(IN_RMG) && !defined(PFS_THREADS)
#include "waislog.h"
#include "futil.h"
void waisLogInternal(long priority,long pid,long lineNum,long code,
char* format,va_list ap);
long log_line = 0;
long wais_log_level = 10;
char* logFile = NULL;
boolean expertUser = false;
/*----------------------------------------------------------------------*/
void
waislog(long priority,long code,char* format,...)
{
va_list ap;
va_start(ap,format);
initMyPID();
waisLogInternal(priority,myPID,log_line++,code,format,ap);
va_end(ap);
}
/*----------------------------------------------------------------------*/
void
waisLogDetailed(long priority,long pid,long lineNum,long code,
char* format,...)
{
va_list ap;
va_start(ap,format);
waisLogInternal(priority,pid,lineNum,code,format,ap);
va_end(ap);
}
/*----------------------------------------------------------------------*/
void
waisLogInternal(long priority,long pid,long lineNum,long code,
char* format,va_list ap)
{
if (priority <= wais_log_level)
{
FILE* log = NULL;
if (logToStderr(logFile))
log = stderr;
else if (logToStdout(logFile))
log = stdout;
else
log = locked_fopen(logFile,"a");
if (log)
{
fprintf(log,"%d: %d: %s: %d: ",pid,lineNum,
printable_time(),code);
vfprintf(log,format,ap);
fprintf(log,"\n");
fflush(log);
if (logToStderr(logFile) == false && logToStdout(logFile) == false)
locked_fclose(log,logFile,FALSE);
}
}
}
#endif /* !defined(IN_RMG) && !defined(PFS_THREADS)*/
/*-------------------------------------------------------------------------- */

View File

@@ -0,0 +1,58 @@
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
#ifndef waislog_h
#define waislog_h
#include <stdarg.h>
#include "cutil.h"
/*-------------------------------------------------------------------------- */
/*-------------------------------------------------------------------------- */
#define WLOG_HIGH (1L)
#define WLOG_MEDIUM (5L)
#define WLOG_LOW (9L)
#define WLOG_CONNECT (1L)
#define WLOG_CLOSE (2L)
#define WLOG_SEARCH (3L)
#define WLOG_RESULTS (4L)
#define WLOG_RETRIEVE (5L)
#define WLOG_INDEX (6L)
#define WLOG_PARSE (7L)
#define WLOG_INFO (100L)
#define WLOG_ERROR (-1L)
#define WLOG_WARNING (-2L)
#define logToStderr(log) (log == NULL || log[0] == '\0')
#define logToStdout(log) (log[0] == '-' && log[1] == '\0')
#define dbg (expertUser && (logToStderr(logFile) || logToStdout(logFile)))
void waislog(long priority, long code, char* format,...);
void waisLogDetailed(long priority,long pid,long lineNum,long code,
char* format,...);
#ifndef waislog_c
extern long log_line;
extern wais_log_level;
extern char* logFile;
extern boolean expertUser;
#endif /* ndef waislog_c */
/*-------------------------------------------------------------------------- */
#endif /* ndef waislog_h */

View File

@@ -0,0 +1,109 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#include <string.h>
#include "wmessage.h"
#include "cutil.h"
/*---------------------------------------------------------------------*/
void
readWAISPacketHeader(msgBuffer,header_struct)
char* msgBuffer;
WAISMessage *header_struct;
{
memmove(header_struct->msg_len,msgBuffer,(size_t)10);
header_struct->msg_type = char_downcase((unsigned long)msgBuffer[10]);
header_struct->hdr_vers = char_downcase((unsigned long)msgBuffer[11]);
memmove(header_struct->server,(void*)(msgBuffer + 12),(size_t)10);
header_struct->compression = char_downcase((unsigned long)msgBuffer[22]);
header_struct->encoding = char_downcase((unsigned long)msgBuffer[23]);
header_struct->msg_checksum = char_downcase((unsigned long)msgBuffer[24]);
}
/*---------------------------------------------------------------------*/
long
getWAISPacketLength(header)
WAISMessage* header;
{
char lenBuf[11];
memmove(lenBuf,header->msg_len,(size_t)10);
lenBuf[10] = '\0';
return(atol(lenBuf));
}
/*---------------------------------------------------------------------*/
#ifdef NOTUSEDYET
static char checkSum _AP((char* string,long len));
static char
checkSum(string,len)
char* string;
long len;
{
register long i;
register char chSum = '\0';
for (i = 0; i < len; i++)
chSum = chSum ^ string[i];
return(chSum);
}
#endif
void
writeWAISPacketHeader(header,
dataLen,
type,
server,
compression,
encoding,
version)
char* header;
long dataLen;
long type;
char* server;
long compression;
long encoding;
long version;
{
char lengthBuf[11];
char serverBuf[11];
long serverLen = strlen(server);
if (serverLen > 10)
serverLen = 10;
sprintf(lengthBuf, "%010ld", dataLen);
strncpy(header,lengthBuf,10);
header[10] = type & 0xFF;
header[11] = version & 0xFF;
strncpy(serverBuf,server,serverLen);
strncpy((char*)(header + 12),serverBuf,serverLen);
header[22] = compression & 0xFF;
header[23] = encoding & 0xFF;
header[24] = '0';
}
/*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,58 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#ifndef WMESSAGE_H
#define WMESSAGE_H
#include "cdialect.h"
typedef struct wais_header {
char msg_len[10];
char msg_type;
char hdr_vers;
char server[10];
char compression;
char encoding;
char msg_checksum;
} WAISMessage;
#define HEADER_LENGTH 25
#define HEADER_VERSION (long)'2'
#define Z3950 'z'
#define ACK 'a'
#define NAK 'n'
#define NO_COMPRESSION ' '
#define UNIX_COMPRESSION 'u'
#define NO_ENCODING ' '
#define HEX_ENCODING 'h'
#define IBM_HEXCODING 'i'
#define UUENCODE 'u'
#ifdef __cplusplus
extern "C"
{
#endif
void readWAISPacketHeader _AP((char* msgBuffer,WAISMessage *header_struct));
long getWAISPacketLength _AP((WAISMessage* header));
void writeWAISPacketHeader _AP((char* header,long dataLen,long type,
char* server,long compression,
long encoding,long version));
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,298 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#ifndef _H_WAIS_protocol_
#define _H_WAIS_protocol_
#include "cdialect.h"
#include "zprot.h"
#include "ztype1.h"
/*----------------------------------------------------------------------*/
#ifndef DF_INDEPENDENT
#define DF_INDEPENDENT 1
#define DF_LATER 2
#define DF_EARLIER 3
#define DF_SPECIFIED_RANGE 4
#endif
#define CT_document 0
#define CT_byte 1
#define CT_line 2
#define CT_paragraph 3
#define QT_RelevanceFeedbackQuery "3"
#define QT_TextRetrievalQuery QT_BooleanQuery
#define DT_UserInformationLength (data_tag)99
#define DT_ChunkCode (data_tag)100
#define DT_ChunkIDLength (data_tag)101
#define DT_ChunkMarker (data_tag)102
#define DT_HighlightMarker (data_tag)103
#define DT_DeHighlightMarker (data_tag)104
#define DT_NewlineCharacters (data_tag)105
#define DT_SeedWords (data_tag)106
#define DT_DocumentIDChunk (data_tag)107
#define DT_ChunkStartID (data_tag)108
#define DT_ChunkEndID (data_tag)109
#define DT_TextList (data_tag)110
#define DT_DateFactor (data_tag)111
#define DT_BeginDateRange (data_tag)112
#define DT_EndDateRange (data_tag)113
#define DT_MaxDocumentsRetrieved (data_tag)114
#define DT_SeedWordsUsed (data_tag)115
#define DT_DocumentID (data_tag)116
#define DT_VersionNumber (data_tag)117
#define DT_Score (data_tag)118
#define DT_BestMatch (data_tag)119
#define DT_DocumentLength (data_tag)120
#define DT_Source (data_tag)121
#define DT_Date (data_tag)122
#define DT_Headline (data_tag)123
#define DT_OriginCity (data_tag)124
#define DT_PresentStartByte (data_tag)125
#define DT_TextLength (data_tag)126
#define DT_DocumentText (data_tag)127
#define DT_StockCodes (data_tag)128
#define DT_CompanyCodes (data_tag)129
#define DT_IndustryCodes (data_tag)130
#define DT_DocumentHeaderGroup (data_tag)150
#define DT_DocumentShortHeaderGroup (data_tag)151
#define DT_DocumentLongHeaderGroup (data_tag)152
#define DT_DocumentTextGroup (data_tag)153
#define DT_DocumentHeadlineGroup (data_tag)154
#define DT_DocumentCodeGroup (data_tag)155
#define DT_Lines (data_tag)131
#define DT_TYPE_BLOCK (data_tag)132
#define DT_TYPE (data_tag)133
#define ES_DocumentHeader "Document Header"
#define ES_DocumentShortHeader "Document Short Header"
#define ES_DocumentLongHeader "Document Long Header"
#define ES_DocumentText "Document Text"
#define ES_DocumentHeadline "Document Headline"
#define ES_DocumentCodes "Document Codes"
typedef struct DocObj {
any* DocumentID;
char* Type;
long ChunkCode;
union {
long Pos;
any* ID;
} ChunkStart;
union {
long Pos;
any* ID;
} ChunkEnd;
} DocObj;
/*----------------------------------------------------------------------*/
typedef struct WAISInitResponse {
long ChunkCode;
long ChunkIDLength;
char* ChunkMarker;
char* HighlightMarker;
char* DeHighlightMarker;
char* NewlineCharacters;
} WAISInitResponse;
typedef struct WAISSearch {
char* SeedWords;
DocObj** Docs;
char** TextList;
long DateFactor;
char* BeginDateRange;
char* EndDateRange;
long MaxDocumentsRetrieved;
} WAISSearch;
typedef struct WAISDocumentHeader {
any* DocumentID;
long VersionNumber;
long Score;
long BestMatch;
long DocumentLength;
long Lines;
char** Types;
char* Source;
char* Date;
char* Headline;
char* OriginCity;
} WAISDocumentHeader;
typedef struct WAISDocumentShortHeader {
any* DocumentID;
long VersionNumber;
long Score;
long BestMatch;
long DocumentLength;
long Lines;
} WAISDocumentShortHeader;
typedef struct WAISDocumentLongHeader {
any* DocumentID;
long VersionNumber;
long Score;
long BestMatch;
long DocumentLength;
long Lines;
char** Types;
char* Source;
char* Date;
char* Headline;
char* OriginCity;
char* StockCodes;
char* CompanyCodes;
char* IndustryCodes;
} WAISDocumentLongHeader;
typedef struct WAISDocumentText {
any* DocumentID;
long VersionNumber;
any* DocumentText;
} WAISDocumentText;
typedef struct WAISDocumentHeadlines {
any* DocumentID;
long VersionNumber;
char* Source;
char* Date;
char* Headline;
char* OriginCity;
} WAISDocumentHeadlines;
typedef struct WAISDocumentCodes {
any* DocumentID;
long VersionNumber;
char* StockCodes;
char* CompanyCodes;
char* IndustryCodes;
} WAISDocumentCodes;
typedef struct WAISSearchResponse {
char* SeedWordsUsed;
WAISDocumentHeader** DocHeaders;
WAISDocumentShortHeader** ShortHeaders;
WAISDocumentLongHeader** LongHeaders;
WAISDocumentText** Text;
WAISDocumentHeadlines** Headlines;
WAISDocumentCodes** Codes;
diagnosticRecord** Diagnostics;
} WAISSearchResponse;
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C"
{
#endif
DocObj* makeDocObjUsingWholeDocument _AP((any* aDocID,char* type));
DocObj* makeDocObjUsingBytes _AP((any* aDocID,char* type,long start,long end));
DocObj* makeDocObjUsingLines _AP((any* aDocID,char* type,long start,long end));
DocObj* makeDocObjUsingParagraphs _AP((any* aDocID,char* type,any* start,any* end));
void freeDocObj _AP((DocObj* doc));
WAISInitResponse* makeWAISInitResponse _AP((long chunkCode,long chunkIDLen,
char* chunkMarker,char* highlightMarker,
char* deHighlightMarker,char* newLineChars));
void freeWAISInitResponse _AP((WAISInitResponse* init));
WAISSearch* makeWAISSearch _AP((
char* seedWords,DocObj** docs,char** textList,
long dateFactor,char* beginDateRange,char* endDateRange,
long maxDocsRetrieved));
void freeWAISSearch _AP((WAISSearch* query));
WAISDocumentHeader* makeWAISDocumentHeader _AP((
any* aDocID,long versionNumber,long score,long bestMatch,long docLen,
long lines,char** types,char* source,char* theDate,char* headline,char* originCity));
void freeWAISDocumentHeader _AP((WAISDocumentHeader* header));
char* writeWAISDocumentHeader _AP((WAISDocumentHeader* header,char* buffer,long* len));
char* readWAISDocumentHeader _AP((WAISDocumentHeader** header,char* buffer));
WAISDocumentShortHeader* makeWAISDocumentShortHeader _AP((
any* aDocID,long versionNumber,long score,long bestMatch,long docLen,long lines));
void freeWAISDocumentShortHeader _AP((WAISDocumentShortHeader* header));
char* writeWAISDocumentShortHeader _AP((WAISDocumentShortHeader* header,
char* buffer,long* len));
char* readWAISDocumentShortHeader _AP((WAISDocumentShortHeader** header,char* buffer));
WAISDocumentLongHeader* makeWAISDocumentLongHeader _AP((
any* aDocID,long versionNumber,long score,long bestMatch,long docLen,
long lines,char** types,char* source,char* theDate, char* headline,char* originCity,
char* stockCodes,char* companyCodes,char* industryCodes));
void freeWAISDocumentLongHeader _AP((WAISDocumentLongHeader* header));
char* writeWAISDocumentLongHeader _AP((WAISDocumentLongHeader* header,char* buffer,long* len));
char* readWAISDocumentLongHeader _AP((WAISDocumentLongHeader** header,char* buffer));
WAISSearchResponse* makeWAISSearchResponse _AP((
char* seedWordsUsed,WAISDocumentHeader** docHeaders,
WAISDocumentShortHeader** shortHeaders,
WAISDocumentLongHeader** longHeaders,
WAISDocumentText** text,WAISDocumentHeadlines** headlines,
WAISDocumentCodes** codes,
diagnosticRecord** diagnostics));
void freeWAISSearchResponse _AP((WAISSearchResponse* response));
WAISDocumentText* makeWAISDocumentText _AP((any* aDocID,long versionNumber,
any* documentText));
void freeWAISDocumentText _AP((WAISDocumentText* docText));
char* writeWAISDocumentText _AP((WAISDocumentText* docText,char* buffer,long* len));
char* readWAISDocumentText _AP((WAISDocumentText** docText,char* buffer));
WAISDocumentHeadlines* makeWAISDocumentHeadlines _AP((
any* aDocID,long versionNumber,char* source,char* theDate,
char* headline,char* originCity));
void freeWAISDocumentHeadlines _AP((WAISDocumentHeadlines* docHeadline));
char* writeWAISDocumentHeadlines _AP((WAISDocumentHeadlines* docHeadline,char* buffer,long* len));
char* readWAISDocumentHeadlines _AP((WAISDocumentHeadlines** docHeadline,char* buffer));
WAISDocumentCodes* makeWAISDocumentCodes _AP((
any* aDocID,long versionNumber,char* stockCodes,char* companyCodes,
char* industryCodes));
void freeWAISDocumentCodes _AP((WAISDocumentCodes* docCodes));
char* writeWAISDocumentCodes _AP((WAISDocumentCodes* docCodes,char* buffer,long* len));
char* readWAISDocumentCodes _AP((WAISDocumentCodes** docCodes,char* buffer));
any* makeWAISTextQuery _AP((DocObj** docs));
DocObj** readWAISTextQuery _AP((any* terms));
void CSTFreeWAISInitResponse _AP((WAISInitResponse* init));
void CSTFreeWAISSearch _AP((WAISSearch* query));
void CSTFreeDocObj _AP((DocObj* doc));
void CSTFreeWAISDocumentHeader _AP((WAISDocumentHeader* header));
void CSTFreeWAISDocumentShortHeader _AP((WAISDocumentShortHeader* header));
void CSTFreeWAISDocumentLongHeader _AP((WAISDocumentLongHeader* header));
void CSTFreeWAISSearchResponse _AP((WAISSearchResponse* response));
void CSTFreeWAISDocumentText _AP((WAISDocumentText* docText));
void CSTFreeWAISDocumentHeadlines _AP((WAISDocumentHeadlines* docHeadline));
void CSTFreeWAISDocumentCodes _AP((WAISDocumentCodes* docCodes));
void CSTFreeWAISTextQuery _AP(( any* query));
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------*/
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#ifndef _H_WAIS_util_
#define _H_WAIS_util_
#include "cdialect.h"
#include "cutil.h"
#ifdef __cplusplus
extern "C"
{
#endif
void twais_format_req_apdu _AP(( boolean use_template, char* apdu_buff, long* len));
void twais_dsply_rsp_apdu _AP(( char* rsp_buff, long rsp_len));
void twais_free_apdu _AP((char* apdu_buff));
long twais_format_init_apdu _AP(( boolean use_template, char* apdu_buff));
long twais_format_typ3_srch_apdu _AP(( boolean use_template, char* apdu_buff));
long twais_format_typ1_srch_apdu _AP(( boolean use_template, char* apdu_buff));
void twais_dsply_init_rsp_apdu _AP(( char* buffer));
void twais_dsply_init_apdu _AP(( char* buffer));
void twais_dsply_srch_rsp_apdu _AP(( char* buffer));
void twais_dsply_srch_apdu _AP(( char* buffer));
void twais_tmplt_init_apdu _AP((char* buff, long* buff_len));
void twais_tmplt_init_rsp_apdu _AP((char* buff, long* buff_len));
void twais_tmplt_typ1_srch_apdu _AP(( char* buff, long* buff_len));
void twais_tmplt_typ3_srch_rsp_apdu _AP(( char* buff, long* buff_len));
#endif
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,178 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#ifndef _H_Z39_50
#define _H_Z39_50
#include "cdialect.h"
#include "zutil.h"
/*----------------------------------------------------------------------*/
typedef struct InitAPDU {
pdu_type PDUType;
boolean willSearch,willPresent,willDelete;
boolean supportAccessControl,supportResourceControl;
long PreferredMessageSize;
long MaximumRecordSize;
char* IDAuthentication;
char* ImplementationID;
char* ImplementationName;
char* ImplementationVersion;
any* ReferenceID;
void* UserInformationField;
} InitAPDU;
typedef struct InitResponseAPDU {
pdu_type PDUType;
boolean Result;
boolean willSearch,willPresent,willDelete;
boolean supportAccessControl,supportResourceControl;
long PreferredMessageSize;
long MaximumRecordSize;
char* IDAuthentication;
char* ImplementationID;
char* ImplementationName;
char* ImplementationVersion;
any* ReferenceID;
void* UserInformationField;
} InitResponseAPDU;
typedef struct SearchAPDU {
pdu_type PDUType;
long SmallSetUpperBound;
long LargeSetLowerBound;
long MediumSetPresentNumber;
boolean ReplaceIndicator;
char* ResultSetName;
char** DatabaseNames;
char* QueryType;
char** ElementSetNames;
any* ReferenceID;
void* Query;
} SearchAPDU;
typedef struct SearchResponseAPDU {
pdu_type PDUType;
long SearchStatus;
long ResultCount;
long NumberOfRecordsReturned;
long NextResultSetPosition;
long ResultSetStatus;
long PresentStatus;
any* ReferenceID;
void* DatabaseDiagnosticRecords;
} SearchResponseAPDU;
typedef struct PresentAPDU {
pdu_type PDUType;
long NumberOfRecordsRequested;
long ResultSetStartPosition;
char* ResultSetID;
char* ElementSetNames;
any* ReferenceID;
void* PresentInfo;
} PresentAPDU;
typedef struct PresentResponseAPDU {
pdu_type PDUType;
boolean PresentStatus;
long NumberOfRecordsReturned;
long NextResultSetPosition;
any* ReferenceID;
void* DatabaseDiagnosticRecords;
} PresentResponseAPDU;
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C"
{
#endif
InitAPDU* makeInitAPDU _AP((boolean search,boolean present,boolean deleteIt,
boolean accessControl,boolean resourceControl,
long prefMsgSize,long maxMsgSize,
char* auth,char* id,char* name, char* version,
any* refID,void* userInfo));
void freeInitAPDU _AP((InitAPDU* init));
char* writeInitAPDU _AP((InitAPDU* init,char* buffer,long* len));
char* readInitAPDU _AP((InitAPDU** init,char* buffer));
InitResponseAPDU* makeInitResponseAPDU _AP((boolean result,
boolean search,boolean present,boolean deleteIt,
boolean accessControl,boolean resourceControl,
long prefMsgSize,long maxMsgSize,
char* auth,char* id,char* name, char* version,
any* refID,void* userInfo));
void freeInitResponseAPDU _AP((InitResponseAPDU* init));
char* writeInitResponseAPDU _AP((InitResponseAPDU* init,char* buffer,long* len));
char* readInitResponseAPDU _AP((InitResponseAPDU** init,char* buffer));
InitResponseAPDU* replyToInitAPDU _AP((InitAPDU* init,boolean result,void* userInfo));
SearchAPDU* makeSearchAPDU _AP((long small,long large, long medium,
boolean replace,char* name,char** databases,
char* type,char** elements,any* refID,void* queryInfo));
void freeSearchAPDU _AP((SearchAPDU* query));
char* writeSearchAPDU _AP((SearchAPDU* query,char* buffer,long* len));
char* readSearchAPDU _AP((SearchAPDU** query,char* buffer));
SearchResponseAPDU* makeSearchResponseAPDU _AP((long result,long count,
long recordsReturned,long nextPos,
long resultStatus,long presentStatus,
any* refID,void* records));
void freeSearchResponseAPDU _AP((SearchResponseAPDU* queryResponse));
char* writeSearchResponseAPDU _AP((SearchResponseAPDU* queryResponse,char* buffer,long* len));
char* readSearchResponseAPDU _AP((SearchResponseAPDU** queryResponse,char* buffer));
PresentAPDU* makePresentAPDU _AP((long recsReq, long startPos,
char* resultID,any* refID,void* info));
void freePresentAPDU _AP((PresentAPDU* present));
char* writePresentAPDU _AP((PresentAPDU* present,char* buffer,long* len));
char* readPresentAPDU _AP((PresentAPDU** present,char* buffer));
PresentResponseAPDU* makePresentResponseAPDU _AP((boolean status,long recsRet,
long nextPos,any* refID,
void* records));
void freePresentResponseAPDU _AP((PresentResponseAPDU* present));
char* writePresentResponseAPDU _AP((PresentResponseAPDU* present,char* buffer,long* len));
char* readPresentResponseAPDU _AP((PresentResponseAPDU** present,char* buffer));
/*----------------------------------------------------------------------*/
extern char* writeInitInfo _AP((InitAPDU* init,char* buffer,long* len));
extern char* readInitInfo _AP((void** info,char* buffer));
extern char* writeInitResponseInfo _AP((InitResponseAPDU* init,char* buffer,long* len));
extern char* readInitResponseInfo _AP((void** info,char* buffer));
extern char* writeSearchInfo _AP((SearchAPDU* query,char* buffer,long* len));
extern char* readSearchInfo _AP((void** info,char* buffer));
extern char* writeSearchResponseInfo _AP((SearchResponseAPDU* query,char* buffer,long* len));
extern char* readSearchResponseInfo _AP((void** info,char* buffer));
extern char* writePresentInfo _AP((PresentAPDU* present,char* buffer,long* len));
extern char* readPresentInfo _AP((void** info,char* buffer));
extern char* writePresentResponseInfo _AP((PresentResponseAPDU* present,char* buffer,long* len));
extern char* readPresentResponseInfo _AP((void** info,char* buffer));
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,319 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#define _C_Type_1_Query_
#include "ztype1.h"
#include "cutil.h"
#include "panic.h"
#include "waislog.h"
#include <string.h>
/*----------------------------------------------------------------------*/
query_term*
makeAttributeTerm(use,
relation,
position,
structure,
truncation,
completeness,
term)
char* use;
char* relation;
char* position;
char* structure;
char* truncation;
char* completeness;
any* term;
{
query_term* qt = (query_term*)s_malloc((size_t)sizeof(query_term));
qt->TermType = TT_Attribute;
strncpy(qt->Use,use,ATTRIBUTE_SIZE);
strncpy(qt->Relation,relation,ATTRIBUTE_SIZE);
strncpy(qt->Position,position,ATTRIBUTE_SIZE);
strncpy(qt->Structure,structure,ATTRIBUTE_SIZE);
strncpy(qt->Truncation,truncation,ATTRIBUTE_SIZE);
strncpy(qt->Completeness,completeness,ATTRIBUTE_SIZE);
qt->Term = duplicateAny(term);
qt->ResultSetID = NULL;
return(qt);
}
/*----------------------------------------------------------------------*/
query_term*
makeResultSetTerm(resultSet)
any* resultSet;
{
query_term* qt = (query_term*)s_malloc((size_t)sizeof(query_term));
qt->TermType = TT_ResultSetID;
qt->ResultSetID = duplicateAny(resultSet);
qt->Term = NULL;
return(qt);
}
/*----------------------------------------------------------------------*/
query_term*
makeOperatorTerm(operatorCode)
char* operatorCode;
{
query_term* qt = (query_term*)s_malloc((size_t)sizeof(query_term));
qt->TermType = TT_Operator;
strncpy(qt->Operator,operatorCode,OPERATOR_SIZE);
qt->Term = NULL;
qt->ResultSetID = NULL;
return(qt);
}
/*----------------------------------------------------------------------*/
void
freeTerm(qt)
query_term* qt;
{
switch (qt->TermType)
{ case TT_Attribute:
freeAny(qt->Term);
break;
case TT_ResultSetID:
freeAny(qt->ResultSetID);
break;
case TT_Operator:
break;
default:
panic("Implementation error: Unknown term type %ld",
qt->TermType);
break;
}
s_free(qt);
}
/*----------------------------------------------------------------------*/
#define ATTRIBUTE_LIST_SIZE ATTRIBUTE_SIZE * 6
#define AT_DELIMITER " "
char*
writeQueryTerm(qt,buffer,len)
query_term* qt;
char* buffer;
long* len;
{
char* buf = buffer;
char attributes[ATTRIBUTE_LIST_SIZE];
switch (qt->TermType)
{ case TT_Attribute:
strncpy(attributes,qt->Use,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,AT_DELIMITER,sizeof(AT_DELIMITER) + 1,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,qt->Relation,ATTRIBUTE_SIZE,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,AT_DELIMITER,sizeof(AT_DELIMITER) + 1,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,qt->Position,ATTRIBUTE_SIZE,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,AT_DELIMITER,sizeof(AT_DELIMITER) + 1,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,qt->Structure,ATTRIBUTE_SIZE,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,AT_DELIMITER,sizeof(AT_DELIMITER) + 1,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,qt->Truncation,ATTRIBUTE_SIZE,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,AT_DELIMITER,sizeof(AT_DELIMITER) + 1,ATTRIBUTE_LIST_SIZE);
s_strncat(attributes,qt->Completeness,ATTRIBUTE_SIZE,ATTRIBUTE_LIST_SIZE);
buf = writeString(attributes,DT_AttributeList,buf,len);
buf = writeAny(qt->Term,DT_Term,buf,len);
break;
case TT_ResultSetID:
buf = writeAny(qt->ResultSetID,DT_ResultSetID,buf,len);
break;
case TT_Operator:
buf = writeString(qt->Operator,DT_Operator,buf,len);
break;
default:
panic("Implementation error: Unknown term type %ld",
qt->TermType);
break;
}
return(buf);
}
/*----------------------------------------------------------------------*/
#if !defined(IN_RMG) && !defined(PFS_THREADS)
/* Note uses strtok - not thread-safe */
static char*
readQueryTerm(qt,buffer)
query_term** qt;
char* buffer;
{
char* buf = buffer;
char *attributeList = NULL;
char* operator = NULL;
any* term;
char* use = NULL;
char* relation = NULL;
char* position = NULL;
char* structure = NULL;
char* truncation = NULL;
char* completeness;
any* resultSetID = NULL;
data_tag tag;
if (buffer == NULL)
{ waislog(WLOG_ERROR,WLOG_HIGH,"null buffer in readQueryTerm");
return(NULL);
}
tag = peekTag(buffer);
switch(tag)
{ case DT_AttributeList:
buf = readString(&attributeList,buf);
buf = readAny(&term,buf);
assert(P_IS_THIS_THREAD_MASTER()); /* strtok is thread unsafe */
use = strtok(attributeList,AT_DELIMITER);
relation = strtok(NULL,AT_DELIMITER);
position = strtok(NULL,AT_DELIMITER);
structure = strtok(NULL,AT_DELIMITER);
truncation = strtok(NULL,AT_DELIMITER);
completeness = strtok(NULL,AT_DELIMITER);
*qt = makeAttributeTerm(use,relation,position,structure,
truncation,completeness,term);
s_free(attributeList);
freeAny(term);
break;
case DT_ResultSetID:
buf = readAny(&resultSetID,buf);
*qt = makeResultSetTerm(resultSetID);
freeAny(resultSetID);
break;
case DT_Operator:
buf = readString(&operator,buf);
*qt = makeOperatorTerm(operator);
s_free(operator);
break;
default:
REPORT_READ_ERROR(buf);
break;
}
return(buf);
}
#endif
/*----------------------------------------------------------------------*/
static unsigned long getQueryTermSize _AP((query_term* qt));
static unsigned long
getQueryTermSize(qt)
query_term* qt;
{
unsigned long size;
static char attributes[] = "11 22 33 44 55 66";
switch (qt->TermType)
{ case TT_Attribute:
size = writtenStringSize(DT_AttributeList,attributes);
size += writtenAnySize(DT_Term,qt->Term);
break;
case TT_ResultSetID:
size = writtenAnySize(DT_ResultSetID,qt->ResultSetID);
break;
case TT_Operator:
size = writtenStringSize(DT_Operator,qt->Operator);
break;
default:
panic("Implementation error: Unknown term type %ld",
qt->TermType);
break;
}
return(size);
}
/*----------------------------------------------------------------------*/
any*
writeQuery(terms)
query_term** terms;
{
any* info = NULL;
char* writePos = NULL;
char* data = NULL;
unsigned long size = 0;
long remaining = 0;
long i;
query_term* qt = NULL;
if (terms == NULL)
return(NULL);
for (i = 0,qt = terms[i]; qt != NULL; qt = terms[++i])
size += getQueryTermSize(qt);
data = (char*)s_malloc((size_t)size);
writePos = data;
remaining = size;
for (i = 0,qt = terms[i]; qt != NULL; qt = terms[++i])
writePos = writeQueryTerm(qt,writePos,&remaining);
info = makeAny(size,data);
return(info);
}
/*----------------------------------------------------------------------*/
#if !defined(IN_RMG) && !defined(PFS_THREADS)
query_term**
readQuery(info)
any *info;
{
char* readPos = info->bytes;
query_term** terms = NULL;
query_term* qt = NULL;
long numTerms = 0;
while (readPos != NULL &&
readPos < info->bytes + info->size)
{ readPos = readQueryTerm(&qt,readPos);
if (terms == NULL)
{ terms = (query_term**)s_malloc((size_t)(sizeof(query_term*)*2));
}
else
{ terms =
(query_term**)s_realloc((char*)terms,
(size_t)(sizeof(query_term*)*(numTerms+2)));
}
terms[numTerms++] = qt;
terms[numTerms] = NULL;
}
return(terms);
}
#endif /* !defined(IN_RMG) && !defined(PFS_THREADS) */
/*----------------------------------------------------------------------*/

View File

@@ -0,0 +1,138 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#ifndef _H_Type_1_Query_
#define _H_Type_1_Query_
#include "cdialect.h"
#include "zutil.h"
/*----------------------------------------------------------------------*/
#define DT_AttributeList (data_tag)44
#define DT_Term (data_tag)45
#define DT_Operator (data_tag)46
#define QT_BooleanQuery "1"
#define IGNORE "ig"
#define UV_ISBN "ub"
#define CORPORATE_NAME "uc"
#define ISSN "us"
#define PERSONAL_NAME "up"
#define SUBJECT "uj"
#define TITLE "ut"
#define GEOGRAPHIC_NAME "ug"
#define CODEN "ud"
#define SUBJECT_SUBDIVISION "ue"
#define SERIES_TITLE "uf"
#define MICROFORM_GENERATION "uh"
#define PLACE_OF_PUBLICATION "ui"
#define NUC_CODE "uk"
#define LANGUAGE "ul"
#define COMBINATION_OF_USE_VALUES "um"
#define SYSTEM_CONTROL_NUMBER "un"
#define DATE "uo"
#define LC_CONTROL_NUMBER "ur"
#define MUSIC_PUBLISHERS_NUMBER "uu"
#define GOVERNMENT_DOCUMENTS_NUMBER "uv"
#define SUBJECT_CLASSIFICATION "uw"
#define RECORD_TYPE "uy"
#define EQUAL "re"
#define GREATER_THAN "rg"
#define GREATER_THAN_OR_EQUAL "ro"
#define LESS_THAN "rl"
#define LESS_THAN_OR_EQUAL "rp"
#define NOT_EQUAL "rn"
#define FIRST_IN_FIELD "pf"
#define FIRST_IN_SUBFIELD "ps"
#define FIRST_IN_A_SUBFIELD "pa"
#define FIRST_IN_NOT_A_SUBFIELD "pt"
#define ANY_POSITION_IN_FIELD "py"
#define PHRASE "sp"
#define WORD "sw"
#define KEY "sk"
#define WORD_LIST "sl"
#define NO_TRUNCATION "tn"
#define RIGHT_TRUNCATION "tr"
#define PROC_NUM_INCLUDED_IN_SEARCH_ARG "ti"
#define INCOMPLETE_SUBFIELD "ci"
#define COMPLETE_SUBFIELD "cs"
#define COMPLETEFIELD "cf"
#define AND "a"
#define OR "o"
#define AND_NOT "n"
#define TT_Attribute 1
#define TT_ResultSetID 2
#define TT_Operator 3
#define ATTRIBUTE_SIZE 3
#define OPERATOR_SIZE 2
typedef struct query_term {
long TermType;
char Use[ATTRIBUTE_SIZE];
char Relation[ATTRIBUTE_SIZE];
char Position[ATTRIBUTE_SIZE];
char Structure[ATTRIBUTE_SIZE];
char Truncation[ATTRIBUTE_SIZE];
char Completeness[ATTRIBUTE_SIZE];
any* Term;
any* ResultSetID;
char Operator[OPERATOR_SIZE];
} query_term;
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C"
{
#endif
query_term* makeAttributeTerm _AP((
char* use,char* relation,char* position,char* structure,
char* truncation,char* completeness,any* term));
query_term* makeResultSetTerm _AP((any* resultSet));
query_term* makeOperatorTerm _AP((char* operatorCode));
void freeTerm _AP((query_term* qt));
char* writeQueryTerm _AP((query_term* qt,char* buffer,long* len));
char* readQueryTerm _AP((query_term** qt,char* buffer));
any* writeQuery _AP((query_term** terms));
query_term** readQuery _AP((any* info));
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------*/
#endif

View File

@@ -0,0 +1,891 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#define _C_utils_Z39_50_
#include <math.h>
#include "zutil.h"
#include <string.h>
#include <pfs_threads.h>
EXTERN_CHARP_DEF(readErrorPosition);
/* Lets hope these get initialized to NULL or that noone cares*/
#define readErrorPosition p_th_arreadErrorPosition[p__th_self_num()]
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
diagnosticRecord*
makeDiag(surrogate,code,addInfo)
boolean surrogate;
char* code;
char* addInfo;
{
diagnosticRecord* diag =
(diagnosticRecord*)s_malloc((size_t)sizeof(diagnosticRecord));
diag->SURROGATE = surrogate;
memcpy(diag->DIAG,code,DIAGNOSTIC_CODE_SIZE);
diag->ADDINFO = s_strdup(addInfo);
return(diag);
}
/*----------------------------------------------------------------------*/
void
freeDiag(diag)
diagnosticRecord* diag;
{
if (diag != NULL)
{ if (diag->ADDINFO != NULL)
s_free(diag->ADDINFO);
s_free(diag);
}
}
/*----------------------------------------------------------------------*/
#define END_OF_RECORD 0x1D
char*
writeDiag(diag,buffer,len)
diagnosticRecord* diag;
char* buffer;
long* len;
{
char* buf = buffer;
long length;
if (diag == NULL)
return(buf);
buf = writeTag(DT_DatabaseDiagnosticRecords,buf,len);
CHECK_FOR_SPACE_LEFT(0L,len);
length = 3;
if (diag->ADDINFO != NULL)
length += strlen(diag->ADDINFO);
if (length >= 0xFFFF )
{ length = 0xFFFF - 1;
diag->ADDINFO[0xFFFF - 3 - 1] = '\0';
}
buf = writeBinaryInteger(length,2L,buf,len);
CHECK_FOR_SPACE_LEFT(1L,len);
buf[0] = diag->DIAG[0];
buf++;
CHECK_FOR_SPACE_LEFT(1L,len);
buf[0] = diag->DIAG[1];
buf++;
if (length > 3)
{ CHECK_FOR_SPACE_LEFT(3L,len);
memcpy(buf,diag->ADDINFO,(size_t)length - 3);
buf += length - 3;
}
CHECK_FOR_SPACE_LEFT(1L,len);
buf[0] = diag->SURROGATE;
buf++;
CHECK_FOR_SPACE_LEFT(1L,len);
buf[0] = END_OF_RECORD;
buf++;
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readDiag(diag,buffer) /*!!ALLOCS - diag */
diagnosticRecord** diag;
char* buffer;
{
char* buf = buffer;
diagnosticRecord* d
= (diagnosticRecord*)s_malloc((size_t)sizeof(diagnosticRecord));
data_tag tag;
long len;
buf = readTag(&tag,buf);
buf = readBinaryInteger(&len,2L,buf);
d->DIAG[0] = buf[0];
d->DIAG[1] = buf[1];
d->DIAG[2] = '\0';
if (len > 3)
{ d->ADDINFO = (char*)s_malloc((size_t)(len - 3 + 1));
memcpy(d->ADDINFO,(char*)(buf + 2),(size_t)(len - 3));
d->ADDINFO[len - 3] = '\0';
}
else
d->ADDINFO = NULL;
d->SURROGATE = buf[len - 1];
*diag = d;
return(buf + len + 1);
}
/*----------------------------------------------------------------------*/
#define continueBit 0x80
#define dataMask 0x7F
#define dataBits 7
char*
writeCompressedInteger(num,buf,len)
unsigned long num;
char* buf;
long* len;
{
char aByte;
long i;
unsigned long size;
size = writtenCompressedIntSize(num);
CHECK_FOR_SPACE_LEFT(size,len);
for (i = size - 1; i >= 0; i--)
{ aByte = num & dataMask;
if (i != (size-1))
aByte = (char)(aByte | continueBit);
buf[i] = aByte;
num = num >> dataBits;
}
return(buf + size);
}
/*----------------------------------------------------------------------*/
char*
readCompressedInteger(num,buf)
unsigned long *num;
char* buf;
{
long i = 0;
unsigned char aByte;
*num = 0;
do
{ aByte = buf[i++];
*num = *num << dataBits;
*num += (aByte & dataMask);
}
while (aByte & continueBit);
return(buf + i);
}
/*----------------------------------------------------------------------*/
#define pad 128
char*
writeCompressedIntWithPadding(num,size,buffer,len)
unsigned long num;
unsigned long size;
char* buffer;
long* len;
{
char* buf = buffer;
unsigned long needed,padding;
long i;
CHECK_FOR_SPACE_LEFT(size,len);
needed = writtenCompressedIntSize(num);
padding = size - needed;
i = padding - 1;
for (i = padding - 1;i >= 0;i--)
{ buf[i] = pad;
}
buf = writeCompressedInteger(num,buf + padding,len);
return(buf);
}
/*----------------------------------------------------------------------*/
unsigned long
writtenCompressedIntSize(num)
unsigned long num;
{
if (num < CompressedInt1Byte)
return(1);
else if (num < CompressedInt2Byte)
return(2);
else if (num < CompressedInt3Byte)
return(3);
else
return(4);
}
/*----------------------------------------------------------------------*/
char*
writeTag(tag,buf,len)
data_tag tag;
char* buf;
long* len;
{
return(writeCompressedInteger(tag,buf,len));
}
/*----------------------------------------------------------------------*/
char*
readTag(tag,buf)
data_tag* tag;
char* buf;
{
return(readCompressedInteger(tag,buf));
}
/*----------------------------------------------------------------------*/
unsigned long
writtenTagSize(tag)
data_tag tag;
{
return(writtenCompressedIntSize(tag));
}
/*----------------------------------------------------------------------*/
data_tag
peekTag(buf)
char* buf;
{
data_tag tag;
readTag(&tag,buf);
return(tag);
}
/*----------------------------------------------------------------------*/
any*
makeAny(size,data)
unsigned long size;
char* data;
{
any* a = (any*)s_malloc((size_t)sizeof(any));
a->size = size;
a->bytes = data;
return(a);
}
/*----------------------------------------------------------------------*/
void
freeAny(a)
any* a;
{
if (a != NULL)
{ if (a->bytes != NULL)
s_free(a->bytes);
s_free(a);
}
}
/*----------------------------------------------------------------------*/
any*
duplicateAny(a)
any* a;
{
any* copy = NULL;
if (a == NULL)
return(NULL);
copy = (any*)s_malloc((size_t)sizeof(any));
copy->size = a->size;
if (a->bytes == NULL)
copy->bytes = NULL;
else
{ copy->bytes = (char*)s_malloc((size_t)copy->size);
memcpy(copy->bytes,a->bytes,(size_t)copy->size);
}
return(copy);
}
/*----------------------------------------------------------------------*/
char*
writeAny(a,tag,buffer,len)
any* a;
data_tag tag;
char* buffer;
long* len;
{
char* buf = buffer;
if (a == NULL)
return(buf);
buf = writeTag(tag,buf,len);
buf = writeCompressedInteger(a->size,buf,len);
CHECK_FOR_SPACE_LEFT(a->size,len);
memcpy(buf,a->bytes,(size_t)a->size);
return(buf+a->size);
}
/*----------------------------------------------------------------------*/
char*
readAny(anAny,buffer) /*!!ALLOCS at anAny */
any** anAny;
char* buffer;
{
char* buf = buffer;
any* a = (any*)s_malloc((size_t)sizeof(any));
data_tag tag;
buf = readTag(&tag,buf);
buf = readCompressedInteger(&a->size,buf);
a->bytes = (char*)s_malloc((size_t)a->size);
memcpy(a->bytes,buf,(size_t)a->size);
*anAny = a;
return(buf+a->size);
}
/*----------------------------------------------------------------------*/
unsigned long
writtenAnySize(tag,a)
data_tag tag;
any* a;
{
unsigned long size;
if (a == NULL)
return(0);
size = writtenTagSize(tag);
size += writtenCompressedIntSize(a->size);
size += a->size;
return(size);
}
/*----------------------------------------------------------------------*/
any*
stringToAny(s)
char* s;
{
any* a = NULL;
if (s == NULL)
return(NULL);
a = (any*)s_malloc((size_t)sizeof(any));
a->size = strlen(s);
a->bytes = (char*)s_malloc((size_t)a->size);
memcpy(a->bytes,s,(size_t)a->size);
return(a);
}
/*----------------------------------------------------------------------*/
char*
anyToString(a)
any* a;
{
char* s = NULL;
if (a == NULL)
return(NULL);
s = s_malloc((size_t)(a->size + 1));
memcpy(s,a->bytes,(size_t)a->size);
s[a->size] = '\0';
return(s);
}
/*----------------------------------------------------------------------*/
char*
writeString(s,tag,buffer,len)
char* s;
data_tag tag;
char* buffer;
long* len;
{
char* buf = buffer;
any* data = NULL;
if (s == NULL)
return(buffer);
data = (any*)s_malloc((size_t)sizeof(any));
data->size = strlen(s);
data->bytes = s;
buf = writeAny(data,tag,buf,len);
s_free(data);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readString(s ,buffer)
char** s ;
char* buffer;
{
any* data = NULL;
char* buf = readAny(&data,buffer);
*s = anyToString(data);
freeAny(data);
return(buf);
}
/*----------------------------------------------------------------------*/
unsigned long
writtenStringSize(tag,s)
data_tag tag;
char* s;
{
unsigned long size;
if (s == NULL)
return(0);
size = writtenTagSize(tag);
size += writtenCompressedIntSize(size);
size += strlen(s);
return(size);
}
/*----------------------------------------------------------------------*/
any*
longToAny(num)
long num;
{
char s[40];
sprintf(s,"%ld",num);
return(stringToAny(s));
}
/*----------------------------------------------------------------------*/
long
anyToLong(a)
any* a;
{
long num;
char* str = NULL;
str = anyToString(a);
sscanf(str,"%ld",&num);
s_free(str);
return(num);
}
/*----------------------------------------------------------------------*/
#define bitsPerByte 8
bit_map*
makeBitMap(unsigned long numBits,...)
{
va_list ap;
long i,j;
bit_map* bm = NULL;
va_start(ap,numBits);
bm = (bit_map*)s_malloc((size_t)sizeof(bit_map));
bm->size = (unsigned long)ceil((double)numBits / bitsPerByte);
bm->bytes = (char*)s_malloc((size_t)bm->size);
for (i = 0; i < bm->size; i++)
{ char aByte = 0;
for (j = 0; j < bitsPerByte; j++)
{ if ((i * bitsPerByte + j) < numBits)
{ boolean bit = false;
bit = (boolean)va_arg(ap,boolean);
if (bit)
{ aByte = aByte | (1 << (bitsPerByte - j - 1));
}
}
}
bm->bytes[i] = aByte;
}
va_end(ap);
return(bm);
}
/*----------------------------------------------------------------------*/
void
freeBitMap(bm)
bit_map* bm;
{
s_free(bm->bytes);
s_free(bm);
}
/*----------------------------------------------------------------------*/
boolean
bitAtPos(pos,bm)
long pos;
bit_map* bm;
{
if (pos > bm->size*bitsPerByte)
return false;
else
return((bm->bytes[(pos / bitsPerByte)] &
(0x80>>(pos % bitsPerByte))) ?
true : false);
}
/*----------------------------------------------------------------------*/
char*
writeBitMap(bm,tag,buffer,len)
bit_map* bm;
data_tag tag;
char* buffer;
long* len;
{
return(writeAny((any*)bm,tag,buffer,len));
}
/*----------------------------------------------------------------------*/
char*
readBitMap(bm,buffer)
bit_map** bm;
char* buffer;
{
return(readAny((any**)bm,buffer));
}
/*----------------------------------------------------------------------*/
char*
writeByte(aByte,buf,len)
unsigned long aByte;
char* buf;
long* len;
{
CHECK_FOR_SPACE_LEFT(1L,len);
buf[0] = aByte & 0xFF;
return(buf + 1);
}
/*----------------------------------------------------------------------*/
char*
readByte(aByte,buf)
unsigned char* aByte;
char* buf;
{
*aByte = buf[0];
return(buf + 1);
}
/*----------------------------------------------------------------------*/
char*
writeBoolean(flag,buf,len)
boolean flag;
char* buf;
long* len;
{
return(writeByte(flag,buf,len));
}
/*----------------------------------------------------------------------*/
char*
readBoolean(flag,buffer)
boolean* flag;
char* buffer;
{
unsigned char aByte;
char* buf = readByte(&aByte,buffer);
*flag = (aByte == true) ? true : false;
return(buf);
}
/*----------------------------------------------------------------------*/
char*
writePDUType(pduType,buf,len)
pdu_type pduType;
char* buf;
long* len;
{
return(writeBinaryInteger((long)pduType,(unsigned long)1,buf,len));
}
/*----------------------------------------------------------------------*/
char*
readPDUType(pduType,buf)
pdu_type* pduType;
char* buf;
{
return(readBinaryInteger((long*)pduType,(unsigned long)1,buf));
}
/*----------------------------------------------------------------------*/
pdu_type
peekPDUType(buf)
char* buf;
{
pdu_type pdu;
readPDUType(&pdu,buf + HEADER_LEN);
return(pdu);
}
/*----------------------------------------------------------------------*/
#define BINARY_INTEGER_BYTES sizeof(long)
/* Writes an integer num into the buf (which has len bytes left) in a width
of size, returns buff, and updates len */
char*
writeBinaryInteger(num,size,buf,len)
long num;
unsigned long size;
char* buf;
long* len;
{
long i;
char aByte;
if (size < 1 || size > BINARY_INTEGER_BYTES)
return(NULL);
CHECK_FOR_SPACE_LEFT(size,len);
for (i = size - 1; i >= 0; i--)
{ aByte = (char)(num & 255);
buf[i] = aByte;
num = num >> bitsPerByte;
}
return(buf + size);
}
/*----------------------------------------------------------------------*/
char*
readBinaryInteger(num,size,buf)
long* num;
unsigned long size;
char* buf;
{
long i;
unsigned char aByte;
if (size < 1 || size > BINARY_INTEGER_BYTES)
return(buf);
*num = 0;
for (i = 0; i < size; i++)
{ aByte = buf[i];
*num = *num << bitsPerByte;
*num += aByte;
}
return(buf + size);
}
/*----------------------------------------------------------------------*/
unsigned long
writtenCompressedBinIntSize(num)
long num;
{
if (num < 0L)
return(4);
else if (num < 256L)
return(1);
else if (num < 65536L)
return(2);
else if (num < 16777216L)
return(3);
else
return(4);
}
/*----------------------------------------------------------------------*/
char*
writeNum(num,tag,buffer,len)
long num;
data_tag tag;
char* buffer;
long* len;
{
char* buf = buffer;
long size = writtenCompressedBinIntSize(num);
if (num == UNUSED)
return(buffer);
buf = writeTag(tag,buf,len);
buf = writeCompressedInteger(size,buf,len);
buf = writeBinaryInteger(num,(unsigned long)size,buf,len);
return(buf);
}
/*----------------------------------------------------------------------*/
char*
readNum(num,buffer)
long* num;
char* buffer;
{
char* buf = buffer;
data_tag tag;
unsigned long size;
unsigned long val;
buf = readTag(&tag,buf);
buf = readCompressedInteger(&val,buf);
size = (unsigned long)val;
buf = readBinaryInteger(num,size,buf);
return(buf);
}
/*----------------------------------------------------------------------*/
unsigned long
writtenNumSize(tag,num)
data_tag tag;
long num;
{
long dataSize = writtenCompressedBinIntSize(num);
long size;
size = writtenTagSize(tag);
size += writtenCompressedIntSize(dataSize);
size += dataSize;
return(size);
}
/*----------------------------------------------------------------------*/
typedef void (voidfunc)();
void
doList(theList,func)
void** theList;
voidfunc *func;
{
register long i;
register void* ptr = NULL;
if (theList == NULL)
return;
for (i = 0,ptr = theList[i]; ptr != NULL; ptr = theList[++i])
(*func)(ptr);
}
/*----------------------------------------------------------------------*/
char*
writeProtocolVersion(buf,len)
char* buf;
long* len;
{
static bit_map* version = NULL;
if (version == NULL)
/* While this only NEEDS doing once, dont really care if done twice
simultaneously by different threads*/
{ version = makeBitMap((unsigned long)1,true);
}
return(writeBitMap(version,DT_ProtocolVersion,buf,len));
}
/*----------------------------------------------------------------------*/
char*
defaultImplementationID()
{
static char ImplementationID[] = "WAIS Inc";
return(ImplementationID);
}
/*----------------------------------------------------------------------*/
char*
defaultImplementationName()
{
static char ImplementationName[] = "Wide Area Information Servers Inc Z39.50";
return(ImplementationName);
}
/*----------------------------------------------------------------------*/
char*
defaultImplementationVersion()
{
static char ImplementationVersion[] = "2.0A";
return(ImplementationVersion);
}
/*----------------------------------------------------------------------*/

View File

@@ -0,0 +1,293 @@
/* WIDE AREA INFORMATION SERVER SOFTWARE:
Developed by Thinking Machines Corporation and put into the public
domain with no guarantees or restrictions.
*/
/*----------------------------------------------------------------------*/
#ifndef _H_utils_Z39_50
#define _H_utils_Z39_50
#include "cdialect.h"
#include "cutil.h"
#include <pfs_threads.h>
/*----------------------------------------------------------------------*/
#define HEADER_LEN (size_t)2
typedef long pdu_type;
#define initAPDU (pdu_type)20
#define initResponseAPDU (pdu_type)21
#define searchAPDU (pdu_type)22
#define searchResponseAPDU (pdu_type)23
#define presentAPDU (pdu_type)24
#define presentResponseAPDU (pdu_type)25
#define deteteAPDU (pdu_type)26
#define deleteResponseAPDU (pdu_type)27
#define accessControlAPDU (pdu_type)28
#define accessControlResponseAPDU (pdu_type)29
#define resourceControlAPDU (pdu_type)30
#define resourceControlResponseAPDU (pdu_type)31
typedef struct any {
unsigned long size;
char* bytes;
} any;
typedef any bit_map;
typedef unsigned long data_tag;
#define DT_PDUType (data_tag)1
#define DT_ReferenceID (data_tag)2
#define DT_ProtocolVersion (data_tag)3
#define DT_Options (data_tag)4
#define DT_PreferredMessageSize (data_tag)5
#define DT_MaximumRecordSize (data_tag)6
#define DT_IDAuthentication (data_tag)7
#define DT_ImplementationID (data_tag)8
#define DT_ImplementationName (data_tag)9
#define DT_ImplementationVersion (data_tag)10
#define DT_UserInformationField (data_tag)11
#define DT_Result (data_tag)12
#define DT_SmallSetUpperBound (data_tag)13
#define DT_LargeSetLowerBound (data_tag)14
#define DT_MediumSetPresentNumber (data_tag)15
#define DT_ReplaceIndicator (data_tag)16
#define DT_ResultSetName (data_tag)17
#define DT_DatabaseNames (data_tag)18
#define DT_ElementSetNames (data_tag)19
#define DT_QueryType (data_tag)20
#define DT_Query (data_tag)21
#define DT_SearchStatus (data_tag)22
#define DT_ResultCount (data_tag)23
#define DT_NumberOfRecordsReturned (data_tag)24
#define DT_NextResultSetPosition (data_tag)25
#define DT_ResultSetStatus (data_tag)26
#define DT_PresentStatus (data_tag)27
#define DT_DatabaseDiagnosticRecords (data_tag)28
#define DT_NumberOfRecordsRequested (data_tag)29
#define DT_ResultSetStartPosition (data_tag)30
#define DT_ResultSetID (data_tag)31
#define DT_DeleteOperation (data_tag)32
#define DT_DeleteStatus (data_tag)33
#define DT_NumberNotDeleted (data_tag)34
#define DT_BulkStatuses (data_tag)35
#define DT_DeleteMSG (data_tag)36
#define DT_SecurityChallenge (data_tag)37
#define DT_SecurityChallengeResponse (data_tag)38
#define DT_SuspendedFlag (data_tag)39
#define DT_ResourceReport (data_tag)40
#define DT_PartialResultsAvailable (data_tag)41
#define DT_ContinueFlag (data_tag)42
#define DT_ResultSetWanted (data_tag)43
#define UNUSED -1
#define CompressedInt1Byte 128
#define CompressedInt2Byte 16384
#define CompressedInt3Byte 2097152
#define QT_0 "0"
#define WILL_USE TRUE
#define WILL_NOT_USE FALSE
#define WILL_SUPPORT TRUE
#define WILL_NOT_SUPPORT FALSE
#define ACCEPT TRUE
#define REJECT FALSE
#define ON TRUE
#define OFF FALSE
#define SUCCESS 0
#define FAILURE 1
#define SUBSET 1
#define INTERIM 2
#define NONE 3
#define PARTIAL_1 1
#define PARTIAL_2 2
#define PARTIAL_3 3
#define PARTIAL_4 4
#define PS_NONE 5
#define DIAGNOSTIC_CODE_SIZE (size_t)3
typedef struct diagnosticRecord
{ boolean SURROGATE;
char DIAG[DIAGNOSTIC_CODE_SIZE];
char* ADDINFO;
} diagnosticRecord;
#define D_PermanentSystemError "S1"
#define D_TemporarySystemError "S2"
#define D_UnsupportedSearch "S3"
#define D_TermsOnlyStopWords "S5"
#define D_TooManyArgumentWords "S6"
#define D_TooManyBooleanOperators "S7"
#define D_TooManyTruncatedWords "S8"
#define D_TooManyIncompleteSubfields "S9"
#define D_TruncatedWordsTooShort "SA"
#define D_InvalidFormatForRecordNumber "SB"
#define D_TooManyCharactersInSearch "SC"
#define D_TooManyRecordsRetrieved "SD"
#define D_PresentRequestOutOfRange "SF"
#define D_SystemErrorInPresentRecords "SG"
#define D_RecordNotAuthorizedToBeSent "SH"
#define D_RecordExceedsPrefMessageSize "SI"
#define D_RecordExceedsMaxRecordSize "SJ"
#define D_ResultSetNotSuppAsSearchTerm "SK"
#define D_OnlyOneRsltSetAsSrchTermSupp "SL"
#define D_OnlyANDingOfASnglRsltSetSupp "SM"
#define D_RsltSetExistsNoReplace "SN"
#define D_ResultSetNamingNotSupported "SO"
#define D_CombinationDatabasesNotSupp "SP"
#define D_ElementSetNamesNotSupported "SQ"
#define D_ElementSetNameNotValid "SR"
#define D_OnlyASingleElmntSetNameSupp "SS"
#define D_ResultSetDeletedByTarget "ST"
#define D_ResultSetIsInUse "SU"
#define D_DatabasesIsLocked "SV"
#define D_TerminatedByNoContinueResp "SW"
#define D_ResultSetDoesNotExist "SX"
#define D_ResExNoResultsAvailable "SY"
#define D_ResExUnpredictableResults "SZ"
#define D_ResExValidSubsetOfResults "T1"
#define D_AccessControlFailure "T2"
#define D_SecurityNotIssuedReqTerm "T3"
#define D_SecurityNotBeIssuedRecNotInc "T4"
/*----------------------------------------------------------------------*/
#ifndef _C_utils_Z39_50_
EXTERN_CHARP_DECL(readErrorPosition);
#define readErrorPosition p_th_arreadErrorPosition[p__th_self_num()]
#endif
#define RETURN(val) {retval = val; goto cleanup; }
#define RETURN_ON_NULL(var) \
if (var == NULL) \
return(NULL);
#define CLEAN_RETURN_ON_NULL(var) \
if (var == NULL) \
RETURN(NULL);
#define REPORT_READ_ERROR(pos) \
{ readErrorPosition = (pos); \
return(NULL); \
}
#define CLEAN_REPORT_READ_ERROR(pos) \
{ readErrorPosition = (pos); \
RETURN(NULL); \
}
#define CHECK_FOR_SPACE_LEFT(spaceNeeded,spaceLeft) \
{ if (*spaceLeft >= spaceNeeded) \
(*spaceLeft) -= spaceNeeded; \
else \
{ *spaceLeft = 0; \
return(NULL); \
} \
}
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C"
{
#endif
diagnosticRecord* makeDiag _AP((boolean surrogate,char* code,char* addInfo));
void freeDiag _AP((diagnosticRecord* diag));
char* writeDiag _AP((diagnosticRecord* diag,char* buffer,long* len));
char* readDiag _AP((diagnosticRecord** diag,char* buffer));
char* writeCompressedInteger _AP((unsigned long num,char* buf,long* len));
char* readCompressedInteger _AP((unsigned long *num,char* buf));
char* writeCompressedIntWithPadding _AP((unsigned long num,unsigned long size,
char* buffer,long* len));
unsigned long writtenCompressedIntSize _AP((unsigned long num));
char* writeTag _AP((data_tag tag,char* buf,long* len));
char* readTag _AP((data_tag* tag,char* buf));
data_tag peekTag _AP((char* buf));
unsigned long writtenTagSize _AP((data_tag tag));
any* makeAny _AP((unsigned long size,char* data));
void freeAny _AP((any* a));
any* duplicateAny _AP((any* a));
char* writeAny _AP((any* a,data_tag tag,char* buffer,long* len));
char* readAny _AP((any** anAny,char* buffer));
unsigned long writtenAnySize _AP((data_tag tag,any* a));
any* stringToAny _AP((char* s));
char* anyToString _AP((any* a));
unsigned long writtenStringSize _AP((data_tag tag,char* s));
any* longToAny _AP((long Num));
long anyToLong _AP((any* a));
char* writeString _AP((char* s,data_tag tag,char* buffer,long* len));
char* readString _AP((char** s,char* buffer));
bit_map* makeBitMap(unsigned long numBits,...);
void freeBitMap _AP((bit_map* bm));
boolean bitAtPos _AP((long pos,bit_map* bm));
char* writeBitMap _AP((bit_map* bm,data_tag tag,char* buffer,long* len));
char* readBitMap _AP((bit_map** bm,char* buffer));
char* writeByte _AP((unsigned long aByte,char* buf,long* len));
char* readByte _AP((unsigned char* aByte,char* buf));
char* writeBoolean _AP((boolean flag,char* buf,long* len));
char* readBoolean _AP((boolean* flag,char* buf));
char* writePDUType _AP((pdu_type pduType,char* buf,long* len));
char* readPDUType _AP((pdu_type* pduType,char* buf));
pdu_type peekPDUType _AP((char* buf));
char* writeBinaryInteger _AP((long num,unsigned long size,
char* buf,long* len));
char* readBinaryInteger _AP((long* num,unsigned long size,char* buf));
unsigned long writtenCompressedBinIntSize _AP((long num));
char* writeNum _AP((long num,data_tag tag,char* buffer,long* len));
char* readNum _AP((long* num,char* buffer));
unsigned long writtenNumSize _AP((data_tag tag,long num));
void doList _AP((void** theList,void (*func)()));
char* writeProtocolVersion _AP((char* buf,long* len));
char* defaultImplementationID _AP((void));
char* defaultImplementationName _AP((void));
char* defaultImplementationVersion _AP((void));
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------*/
#endif