moved a separate directory. MSV5.0 project server.dsp created.
As an option, the server can now operate as an NT service.
-# Copyright (C) 1994, Index Data I/S
+# Copyright (C) 1994-1997, Index Data I/S
# All rights reserved.
# Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile,v 1.31 1996-10-08 10:45:05 quinn Exp $
+# $Id: Makefile,v 1.32 1997-09-01 08:52:58 adam Exp $
LIBDIR=../lib
$(LIBDIR)/libcomstack.a $(LIBMOSI) $(LIBDIR)/libutil.a $(ELIBS)
PO = eventl.o seshigh.o statserv.o requestq.o
CPP=$(CC) -E
-PROG=ztest
-PROGO=ztest.o read-grs.o
RANLIB=ranlib
-all: $(LIBDIR) $(LIB) $(PROG)
-
-$(PROG): $(LIB) $(PROGO)
- $(CC) $(CFLAGS) $(LIBINCLUDE) -o $(PROG) $(PROGO) $(LIBS)
-
-alll:
+all: $(LIBDIR) $(LIB)
$(LIB): $(PO)
rm -f $(LIB)
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: eventl.c,v $
- * Revision 1.22 1996-07-06 19:58:35 quinn
+ * Revision 1.23 1997-09-01 08:52:59 adam
+ * New windows NT/95 port using MSV5.0. The test server 'ztest' was
+ * moved a separate directory. MSV5.0 project server.dsp created.
+ * As an option, the server can now operate as an NT service.
+ *
+ * Revision 1.22 1996/07/06 19:58:35 quinn
* System headerfiles gathered in yconfig
*
* Revision 1.21 1996/02/21 12:55:51 quinn
#include <yconfig.h>
#include <stdio.h>
#include <assert.h>
+#ifdef WINDOWS
+#include <winsock.h>
+#else
#include <unistd.h>
+#endif
#include <stdlib.h>
#include <errno.h>
#include <string.h>
-#include <eventl.h>
-
+#include "eventl.h"
+#include "log.h"
+#include "comstack.h"
+#include "session.h"
+#include "statserv.h"
#include <xmalloc.h>
+#ifndef WINDOWS
+
static IOCHAN iochans = 0;
IOCHAN iochan_getchan(void)
return iochans;
}
+#endif /* WINDOWS */
+
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
{
- IOCHAN new;
+ IOCHAN new_iochan;
- if (!(new = xmalloc(sizeof(*new))))
+ if (!(new_iochan = xmalloc(sizeof(*new_iochan))))
return 0;
- new->destroyed = 0;
- new->fd = fd;
- new->flags = flags;
- new->fun = cb;
- new->next = iochans;
- new->force_event = 0;
- new->last_event = new->max_idle = 0;
- iochans = new;
- return new;
+ new_iochan->destroyed = 0;
+ new_iochan->fd = fd;
+ new_iochan->flags = flags;
+ new_iochan->fun = cb;
+ new_iochan->force_event = 0;
+ new_iochan->last_event = new_iochan->max_idle = 0;
+
+#ifdef WINDOWS
+ /* For windows we don't have a linklist of iochans */
+ new_iochan->next = NULL;
+#else /* WINDOWS */
+ new_iochan->next = iochans;
+ iochans = new_iochan;
+#endif /* WINDOWS */
+
+ return new_iochan;
}
-int event_loop()
+/* Event loop now takes an iochan as a parameter */
+#ifdef WINDOWS
+int __stdcall event_loop(IOCHAN iochans)
+#else
+int event_loop(IOCHAN dummylistener)
+#endif
{
do /* loop as long as there are active associations to process */
{
IOCHAN p, nextp;
- fd_set in, out, except;
- int res, max;
- static struct timeval nullto = {0, 0}, to;
- struct timeval *timeout;
-
- FD_ZERO(&in);
- FD_ZERO(&out);
- FD_ZERO(&except);
- timeout = &to; /* hang on select */
- to.tv_sec = 5*60;
- to.tv_usec = 0;
- max = 0;
- for (p = iochans; p; p = p->next)
- {
- if (p->force_event)
- timeout = &nullto; /* polling select */
- if (p->flags & EVENT_INPUT)
- FD_SET(p->fd, &in);
- if (p->flags & EVENT_OUTPUT)
- FD_SET(p->fd, &out);
- if (p->flags & EVENT_EXCEPT)
- FD_SET(p->fd, &except);
- if (p->fd > max)
- max = p->fd;
- }
- if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
- {
- if (errno == EINTR)
- continue;
- return 1;
- }
+ fd_set in, out, except;
+ int res, max;
+ static struct timeval nullto = {0, 0}, to;
+ struct timeval *timeout;
+
+ FD_ZERO(&in);
+ FD_ZERO(&out);
+ FD_ZERO(&except);
+ timeout = &to; /* hang on select */
+ to.tv_sec = 5*60;
+ to.tv_usec = 0;
+ max = 0;
for (p = iochans; p; p = p->next)
{
- int force_event = p->force_event;
- time_t now = time(0);
-
- p->force_event = 0;
- if (!p->destroyed && (FD_ISSET(p->fd, &in) || force_event ==
- EVENT_INPUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_INPUT);
+ if (p->force_event)
+ timeout = &nullto; /* polling select */
+ if (p->flags & EVENT_INPUT)
+ FD_SET(p->fd, &in);
+ if (p->flags & EVENT_OUTPUT)
+ FD_SET(p->fd, &out);
+ if (p->flags & EVENT_EXCEPT)
+ FD_SET(p->fd, &except);
+ if (p->fd > max)
+ max = p->fd;
}
- if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
- force_event == EVENT_OUTPUT))
+ if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
{
- p->last_event = now;
- (*p->fun)(p, EVENT_OUTPUT);
+ if (errno == EINTR)
+ continue;
+ else
+ {
+ /* Destroy the first member in the chain, and try again */
+ association *assoc = iochan_getdata(iochans);
+ COMSTACK conn = assoc->client_link;
+
+ cs_close(conn);
+ destroy_association(assoc);
+ iochan_destroy(iochans);
+ logf(LOG_DEBUG, "error while selecting, destroying iochan %p", iochans);
+ }
}
- if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
- force_event == EVENT_EXCEPT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_EXCEPT);
+ for (p = iochans; p; p = p->next)
+ {
+ int force_event = p->force_event;
+ time_t now = time(0);
+
+ p->force_event = 0;
+ if (!p->destroyed && (FD_ISSET(p->fd, &in) || force_event == EVENT_INPUT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_INPUT);
+ }
+ if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
+ force_event == EVENT_OUTPUT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_OUTPUT);
+ }
+ if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
+ force_event == EVENT_EXCEPT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_EXCEPT);
+ }
+ if (!p->destroyed && ((p->max_idle && now - p->last_event >
+ p->max_idle) || force_event == EVENT_TIMEOUT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_TIMEOUT);
+ }
}
- if (!p->destroyed && ((p->max_idle && now - p->last_event >
- p->max_idle) || force_event == EVENT_TIMEOUT))
+ for (p = iochans; p; p = nextp)
{
- p->last_event = now;
- (*p->fun)(p, EVENT_TIMEOUT);
- }
- }
- for (p = iochans; p; p = nextp)
- {
- nextp = p->next;
+ nextp = p->next;
- if (p->destroyed)
- {
- IOCHAN tmp = p, pr;
-
- if (p == iochans)
- iochans = p->next;
- else
- {
- for (pr = iochans; pr; pr = pr->next)
- if (pr->next == p)
- break;
- assert(pr); /* grave error if it weren't there */
- pr->next = p->next;
- }
- if (nextp == p)
- nextp = p->next;
- xfree(tmp);
+ if (p->destroyed)
+ {
+ IOCHAN tmp = p, pr;
+
+ /* We need to inform the threadlist that this channel has been destroyed */
+ statserv_remove(p);
+
+ /* Now reset the pointers */
+ if (p == iochans)
+ iochans = p->next;
+ else
+ {
+ for (pr = iochans; pr; pr = pr->next)
+ if (pr->next == p)
+ break;
+ assert(pr); /* grave error if it weren't there */
+ pr->next = p->next;
+ }
+ if (nextp == p)
+ nextp = p->next;
+ xfree(tmp);
+ }
}
- }
}
while (iochans);
return 0;
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: requestq.c,v $
- * Revision 1.2 1995-11-01 13:54:57 quinn
+ * Revision 1.3 1997-09-01 08:53:00 adam
+ * New windows NT/95 port using MSV5.0. The test server 'ztest' was
+ * moved a separate directory. MSV5.0 project server.dsp created.
+ * As an option, the server can now operate as an NT service.
+ *
+ * Revision 1.2 1995/11/01 13:54:57 quinn
* Minor adjustments
*
* Revision 1.1 1995/05/15 12:12:22 quinn
#include <stdlib.h>
#include <xmalloc.h>
-#include <session.h>
-
-static request *request_list = 0; /* global freelist for requests */
+#include "session.h"
void request_enq(request_q *q, request *r)
{
void request_initq(request_q *q)
{
- q->head = q->tail = 0;
+ q->head = q->tail = q->list = 0;
q->num = 0;
}
-request *request_get(void)
+void request_delq(request_q *q)
+{
+ request *r1, *r = q->list;
+ while (r)
+ {
+ r1 = r;
+ r = r->next;
+ xfree (r1);
+ }
+}
+
+request *request_get(request_q *q)
{
- request *r = request_list;
+ request *r = q->list;
if (r)
- request_list = r->next;
+ q->list = r->next;
else
{
if (!(r = xmalloc(sizeof(*r))))
r->response = 0;
r->size_response = 0;
}
+ r->q = q;
r->len_refid = 0;
r->request = 0;
r->request_mem = 0;
void request_release(request *r)
{
- r->next = request_list;
- request_list = r;
+ request_q *q = r->q;
+ r->next = q->list;
+ q->list = r;
}
--- /dev/null
+# Microsoft Developer Studio Project File - Name="server" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 5.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Static Library" 0x0104\r
+\r
+CFG=server - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "server.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "server.mak" CFG="server - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "server - Win32 Release" (based on "Win32 (x86) Static Library")\r
+!MESSAGE "server - Win32 Debug" (based on "Win32 (x86) Static Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+\r
+!IF "$(CFG)" == "server - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WINDOWS" /FD /c\r
+# SUBTRACT CPP /YX\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo\r
+# Begin Special Build Tool\r
+OutDir=.\Release\r
+ProjDir=.\r
+TargetName=server\r
+SOURCE=$(InputPath)\r
+PostBuild_Desc=Copy lib\r
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).lib $(ProjDir)\..\lib\r
+# End Special Build Tool\r
+\r
+!ELSEIF "$(CFG)" == "server - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c\r
+# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WINDOWS" /FR /FD /c\r
+# SUBTRACT CPP /YX\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LIB32=link.exe -lib\r
+# ADD BASE LIB32 /nologo\r
+# ADD LIB32 /nologo\r
+# Begin Special Build Tool\r
+OutDir=.\Debug\r
+ProjDir=.\r
+TargetName=server\r
+SOURCE=$(InputPath)\r
+PostBuild_Desc=Copy lib\r
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).lib $(ProjDir)\..\lib\r
+# End Special Build Tool\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "server - Win32 Release"\r
+# Name "server - Win32 Debug"\r
+# Begin Source File\r
+\r
+SOURCE=.\eventl.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\requestq.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\seshigh.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\session.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\statserv.c\r
+# End Source File\r
+# End Target\r
+# End Project\r
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: seshigh.c,v $
- * Revision 1.64 1997-04-30 08:52:11 quinn
+ * Revision 1.65 1997-09-01 08:53:01 adam
+ * New windows NT/95 port using MSV5.0. The test server 'ztest' was
+ * moved a separate directory. MSV5.0 project server.dsp created.
+ * As an option, the server can now operate as an NT service.
+ *
+ * Revision 1.64 1997/04/30 08:52:11 quinn
* Null
*
* Revision 1.63 1996/10/11 11:57:26 quinn
#include <yconfig.h>
#include <stdlib.h>
#include <stdio.h>
+#ifdef WINDOWS
+#include <process.h>
+#else
#include <unistd.h>
+#endif
#include <assert.h>
#include <xmalloc.h>
#include <comstack.h>
-#include <eventl.h>
-#include <session.h>
+#include "eventl.h"
+#include "session.h"
#include <proto.h>
#include <oid.h>
#include <log.h>
bend_close(h->backend);
while (request_deq(&h->incoming));
while (request_deq(&h->outgoing));
- xfree(h);
+ request_delq(&h->incoming);
+ request_delq(&h->outgoing);
+ xfree(h);
}
static void do_close(association *a, int reason, char *message)
{
Z_APDU apdu;
Z_Close *cls = zget_Close(a->encode);
- request *req = request_get();
+ request *req = request_get(&a->outgoing);
/* Purge request queue */
while (request_deq(&a->incoming));
/* we got a complete PDU. Let's decode it */
logf(LOG_DEBUG, "Got PDU, %d bytes", res);
- req = request_get(); /* get a new request structure */
+ req = request_get(&assoc->incoming); /* get a new request structure */
odr_reset(assoc->decode);
odr_setbuf(assoc->decode, assoc->input_buffer, res, 0);
if (!z_APDU(assoc->decode, &req->request, 0))
{
logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
- odr_errlist[odr_geterror(assoc->decode)],
+ odr_errmsg(odr_geterror(assoc->decode)),
odr_offset(assoc->decode));
logf(LOG_LOG, "PDU dump:");
odr_dumpBER(log_file(), assoc->input_buffer, res);
if (assoc->print && !z_APDU(assoc->print, &req->request, 0))
{
logf(LOG_WARN, "ODR print error: %s",
- odr_errlist[odr_geterror(assoc->print)]);
+ odr_errmsg(odr_geterror(assoc->print)));
odr_reset(assoc->print);
}
request_enq(&assoc->incoming, req);
if (!z_APDU(assoc->encode, &res, 0))
{
logf(LOG_WARN, "ODR error when encoding response: %s",
- odr_errlist[odr_geterror(assoc->decode)]);
+ odr_errmsg(odr_geterror(assoc->decode)));
odr_reset(assoc->encode);
return -1;
}
if (assoc->print && !z_APDU(assoc->print, &res, 0))
{
logf(LOG_WARN, "ODR print error: %s",
- odr_errlist[odr_geterror(assoc->print)]);
+ odr_errmsg(odr_geterror(assoc->print)));
odr_reset(assoc->print);
}
/* change this when we make the backend reentrant */
/*
* nonsurrogate diagnostic record.
*/
-static Z_Records *diagrec(oid_proto proto, int error, char *addinfo)
+static Z_Records *diagrec(association *assoc, int error, char *addinfo)
{
- static Z_Records rec;
+ Z_Records *rec = odr_malloc (assoc->encode, sizeof(*rec));
oident bib1;
- static int err;
-#ifdef Z_95
- static Z_DiagRec drec;
- static Z_DefaultDiagFormat dr;
-#else
- static Z_DiagRec dr;
-#endif
+ int *err = odr_malloc (assoc->encode, sizeof(*err));
+ Z_DiagRec *drec = odr_malloc (assoc->encode, sizeof(*drec));
+ Z_DefaultDiagFormat *dr = odr_malloc (assoc->encode, sizeof(*dr));
- bib1.proto = proto;
+ bib1.proto = assoc->proto;
bib1.oclass = CLASS_DIAGSET;
bib1.value = VAL_BIB1;
logf(LOG_DEBUG, "Diagnostic: %d -- %s", error, addinfo ? addinfo :
"NULL");
- err = error;
- rec.which = Z_Records_NSD;
+ *err = error;
+ rec->which = Z_Records_NSD;
#ifdef Z_95
- rec.u.nonSurrogateDiagnostic = &drec;
- drec.which = Z_DiagRec_defaultFormat;
- drec.u.defaultFormat = &dr;
+ rec->u.nonSurrogateDiagnostic = drec;
+ drec->which = Z_DiagRec_defaultFormat;
+ drec->u.defaultFormat = dr;
#else
- rec.u.nonSurrogateDiagnostic = &dr;
+ rec->u.nonSurrogateDiagnostic = dr;
#endif
- dr.diagnosticSetId = oid_getoidbyent(&bib1);
- dr.condition = &err;
- dr.which = Z_DiagForm_v2AddInfo;
- dr.addinfo = addinfo ? addinfo : "";
- return &rec;
+ dr->diagnosticSetId = oid_getoidbyent(&bib1);
+ dr->condition = err;
+ dr->which = Z_DiagForm_v2AddInfo;
+ dr->addinfo = addinfo ? addinfo : "";
+ return rec;
}
/*
* surrogate diagnostic.
*/
-static Z_NamePlusRecord *surrogatediagrec(oid_proto proto, char *dbname,
+static Z_NamePlusRecord *surrogatediagrec(association *assoc, char *dbname,
int error, char *addinfo)
{
- static Z_NamePlusRecord rec;
- static int err;
+ Z_NamePlusRecord *rec = odr_malloc (assoc->encode, sizeof(*rec));
+ int *err = odr_malloc (assoc->encode, sizeof(*err));
oident bib1;
-#ifdef Z_95
- static Z_DiagRec drec;
- static Z_DefaultDiagFormat dr;
-#else
- static Z_DiagRec dr;
-#endif
+ Z_DiagRec *drec = odr_malloc (assoc->encode, sizeof(*drec));
+ Z_DefaultDiagFormat *dr = odr_malloc (assoc->encode, sizeof(*dr));
- bib1.proto = proto;
+ bib1.proto = assoc->proto;
bib1.oclass = CLASS_DIAGSET;
bib1.value = VAL_BIB1;
logf(LOG_DEBUG, "SurrogateDiagnotic: %d -- %s", error, addinfo);
- err = error;
- rec.databaseName = dbname;
- rec.which = Z_NamePlusRecord_surrogateDiagnostic;
-#ifdef Z_95
- rec.u.surrogateDiagnostic = &drec;
- drec.which = Z_DiagRec_defaultFormat;
- drec.u.defaultFormat = &dr;
-#else
- rec.u.surrogateDiagnostic = &dr;
-#endif
- dr.diagnosticSetId = oid_getoidbyent(&bib1);
- dr.condition = &err;
- dr.which = Z_DiagForm_v2AddInfo;
- dr.addinfo = addinfo ? addinfo : "";
- return &rec;
+ *err = error;
+ rec->databaseName = dbname;
+ rec->which = Z_NamePlusRecord_surrogateDiagnostic;
+ rec->u.surrogateDiagnostic = drec;
+ drec->which = Z_DiagRec_defaultFormat;
+ drec->u.defaultFormat = dr;
+ dr->diagnosticSetId = oid_getoidbyent(&bib1);
+ dr->condition = err;
+ dr->which = Z_DiagForm_v2AddInfo;
+ dr->addinfo = addinfo ? addinfo : "";
+ return rec;
}
/*
* multiple nonsurrogate diagnostics.
*/
-static Z_DiagRecs *diagrecs(oid_proto proto, int error, char *addinfo)
+static Z_DiagRecs *diagrecs(association *assoc, int error, char *addinfo)
{
- static Z_DiagRecs recs;
- static int err;
+ Z_DiagRecs *recs = odr_malloc (assoc->encode, sizeof(*recs));
+ int *err = odr_malloc (assoc->encode, sizeof(*err));
oident bib1;
-#ifdef Z_95
- static Z_DiagRec *recp[1], drec;
- static Z_DefaultDiagFormat rec;
-#else
- static Z_DiagRec *recp[1], rec;
-#endif
+ Z_DiagRec **recp = odr_malloc (assoc->encode, sizeof(*recp));
+ Z_DiagRec *drec = odr_malloc (assoc->encode, sizeof(*drec));
+ Z_DefaultDiagFormat *rec = odr_malloc (assoc->encode, sizeof(*rec));
logf(LOG_DEBUG, "DiagRecs: %d -- %s", error, addinfo);
- bib1.proto = proto;
+ bib1.proto = assoc->proto;
bib1.oclass = CLASS_DIAGSET;
bib1.value = VAL_BIB1;
- err = error;
- recs.num_diagRecs = 1;
- recs.diagRecs = recp;
-#ifdef Z_95
- recp[0] = &drec;
- drec.which = Z_DiagRec_defaultFormat;
- drec.u.defaultFormat = &rec;
-#else
- recp[0] = &rec;
-#endif
- rec.diagnosticSetId = oid_getoidbyent(&bib1);
- rec.condition = &err;
- rec.which = Z_DiagForm_v2AddInfo;
- rec.addinfo = addinfo ? addinfo : "";
- return &recs;
+ *err = error;
+ recs->num_diagRecs = 1;
+ recs->diagRecs = recp;
+ recp[0] = drec;
+ drec->which = Z_DiagRec_defaultFormat;
+ drec->u.defaultFormat = rec;
+
+ rec->diagnosticSetId = oid_getoidbyent(&bib1);
+ rec->condition = err;
+ rec->which = Z_DiagForm_v2AddInfo;
+ rec->addinfo = addinfo ? addinfo : "";
+ return recs;
}
-#define MAX_RECORDS 256
-
static Z_Records *pack_records(association *a, char *setname, int start,
int *num, Z_RecordComposition *comp,
int *next, int *pres, oid_value format)
{
int recno, total_length = 0, toget = *num, dumped_records = 0;
- static Z_Records records;
- static Z_NamePlusRecordList reclist;
- static Z_NamePlusRecord *list[MAX_RECORDS];
+ Z_Records *records = odr_malloc (a->encode, sizeof(*records));
+ Z_NamePlusRecordList *reclist = odr_malloc (a->encode, sizeof(*reclist));
+ Z_NamePlusRecord **list = odr_malloc (a->encode, sizeof(*list) * toget);
oident recform;
- records.which = Z_Records_DBOSD;
- records.u.databaseOrSurDiagnostics = &reclist;
- reclist.num_records = 0;
- reclist.records = list;
+ records->which = Z_Records_DBOSD;
+ records->u.databaseOrSurDiagnostics = reclist;
+ reclist->num_records = 0;
+ reclist->records = list;
*pres = Z_PRES_SUCCESS;
*num = 0;
*next = 0;
logf(LOG_DEBUG, "Request to pack %d+%d", start, toget);
logf(LOG_DEBUG, "pms=%d, mrs=%d", a->preferredMessageSize,
a->maximumRecordSize);
- for (recno = start; reclist.num_records < toget; recno++)
+ for (recno = start; reclist->num_records < toget; recno++)
{
bend_fetchrequest freq;
bend_fetchresult *fres;
* idea of the total size of the data so far.
*/
total_length = odr_total(a->encode) - dumped_records;
- if (reclist.num_records == MAX_RECORDS - 1)
- {
- *pres = Z_PRES_PARTIAL_2;
- break;
- }
freq.setname = setname;
freq.number = recno;
freq.comp = comp;
if (!(fres = bend_fetch(a->backend, &freq, 0)))
{
*pres = Z_PRES_FAILURE;
- return diagrec(a->proto, 2, "Backend interface problem");
+ return diagrec(a, 2, "Backend interface problem");
}
/* backend should be able to signal whether error is system-wide
or only pertaining to current record */
if (fres->errcode)
{
*pres = Z_PRES_FAILURE;
- return diagrec(a->proto, fres->errcode, fres->errstring);
+ return diagrec(a, fres->errcode, fres->errstring);
}
if (fres->len >= 0)
this_length = fres->len;
if (toget > 1)
{
logf(LOG_DEBUG, " Dropped it");
- reclist.records[reclist.num_records] =
- surrogatediagrec(a->proto, fres->basename, 16, 0);
- reclist.num_records++;
+ reclist->records[reclist->num_records] =
+ surrogatediagrec(a, fres->basename, 16, 0);
+ reclist->num_records++;
*next = fres->last_in_set ? 0 : recno + 1;
dumped_records += this_length;
continue;
else /* too big entirely */
{
logf(LOG_DEBUG, "Record > maxrcdsz");
- reclist.records[reclist.num_records] =
- surrogatediagrec(a->proto, fres->basename, 17, 0);
- reclist.num_records++;
+ reclist->records[reclist->num_records] =
+ surrogatediagrec(a, fres->basename, 17, 0);
+ reclist->num_records++;
*next = fres->last_in_set ? 0 : recno + 1;
dumped_records += this_length;
continue;
thisext->u.octet_aligned->len = thisext->u.octet_aligned->size =
fres->len;
}
- reclist.records[reclist.num_records] = thisrec;
- reclist.num_records++;
+ reclist->records[reclist->num_records] = thisrec;
+ reclist->num_records++;
*next = fres->last_in_set ? 0 : recno + 1;
}
- *num = reclist.num_records;
- return &records;
+ *num = reclist->num_records;
+ return records;
}
static Z_APDU *process_searchRequest(association *assoc, request *reqb,
bend_searchresult *bsrt, int *fd)
{
Z_SearchRequest *req = reqb->request->u.searchRequest;
- static Z_APDU apdu;
- static Z_SearchResponse resp;
- static int nulint = 0;
- static bool_t sr = 1;
- static int next = 0;
- static int none = Z_RES_NONE;
-
- apdu.which = Z_APDU_searchResponse;
- apdu.u.searchResponse = &resp;
- resp.referenceId = req->referenceId;
-#ifdef Z_95
- resp.additionalSearchInfo = 0;
- resp.otherInfo = 0;
-#endif
+ Z_APDU *apdu = odr_malloc (assoc->encode, sizeof(*apdu));
+ Z_SearchResponse *resp = odr_malloc (assoc->encode, sizeof(*resp));
+ int *nulint = odr_malloc (assoc->encode, sizeof(*nulint));
+ bool_t *sr = odr_malloc (assoc->encode, sizeof(*sr));
+ int *next = odr_malloc (assoc->encode, sizeof(*next));
+ int *none = odr_malloc (assoc->encode, sizeof(*none));
+
+ *nulint = 0;
+ *sr = 1;
+ *next = 0;
+ *none = Z_RES_NONE;
+
+ apdu->which = Z_APDU_searchResponse;
+ apdu->u.searchResponse = resp;
+ resp->referenceId = req->referenceId;
+ resp->additionalSearchInfo = 0;
+ resp->otherInfo = 0;
*fd = -1;
if (!bsrt && !(bsrt = bend_searchresponse(assoc->backend)))
{
}
else if (bsrt->errcode)
{
- resp.records = diagrec(assoc->proto, bsrt->errcode,
- bsrt->errstring);
- resp.resultCount = &nulint;
- resp.numberOfRecordsReturned = &nulint;
- resp.nextResultSetPosition = &nulint;
- resp.searchStatus = &nulint;
- resp.resultSetStatus = &none;
- resp.presentStatus = 0;
+ resp->records = diagrec(assoc, bsrt->errcode, bsrt->errstring);
+ resp->resultCount = nulint;
+ resp->numberOfRecordsReturned = nulint;
+ resp->nextResultSetPosition = nulint;
+ resp->searchStatus = nulint;
+ resp->resultSetStatus = none;
+ resp->presentStatus = 0;
}
else
{
- static int toget;
+ int *toget = odr_malloc (assoc->encode, sizeof(*toget));
+ int *presst = odr_malloc (assoc->encode, sizeof(*presst));
Z_RecordComposition comp, *compp = 0;
- static int presst = 0;
- resp.records = 0;
- resp.resultCount = &bsrt->hits;
+ *toget = 0;
+ *presst = 0;
+ resp->records = 0;
+ resp->resultCount = &bsrt->hits;
comp.which = Z_RecordComp_simple;
/* how many records does the user agent want, then? */
if (bsrt->hits <= *req->smallSetUpperBound)
{
- toget = bsrt->hits;
+ *toget = bsrt->hits;
if ((comp.u.simple = req->smallSetElementSetNames))
compp = ∁
}
else if (bsrt->hits < *req->largeSetLowerBound)
{
- toget = *req->mediumSetPresentNumber;
- if (toget > bsrt->hits)
- toget = bsrt->hits;
+ *toget = *req->mediumSetPresentNumber;
+ if (*toget > bsrt->hits)
+ *toget = bsrt->hits;
if ((comp.u.simple = req->mediumSetElementSetNames))
compp = ∁
}
else
- toget = 0;
+ *toget = 0;
- if (toget && !resp.records)
+ if (*toget && !resp->records)
{
oident *prefformat;
oid_value form;
form = VAL_NONE;
else
form = prefformat->value;
- resp.records = pack_records(assoc, req->resultSetName, 1,
- &toget, compp, &next, &presst, form);
- if (!resp.records)
+ resp->records = pack_records(assoc, req->resultSetName, 1,
+ toget, compp, next, presst, form);
+ if (!resp->records)
return 0;
- resp.numberOfRecordsReturned = &toget;
- resp.nextResultSetPosition = &next;
- resp.searchStatus = &sr;
- resp.resultSetStatus = 0;
- resp.presentStatus = &presst;
+ resp->numberOfRecordsReturned = toget;
+ resp->nextResultSetPosition = next;
+ resp->searchStatus = sr;
+ resp->resultSetStatus = 0;
+ resp->presentStatus = presst;
}
else
{
- if (*resp.resultCount)
- next = 1;
- resp.numberOfRecordsReturned = &nulint;
- resp.nextResultSetPosition = &next;
- resp.searchStatus = &sr;
- resp.resultSetStatus = 0;
- resp.presentStatus = 0;
+ if (*resp->resultCount)
+ *next = 1;
+ resp->numberOfRecordsReturned = nulint;
+ resp->nextResultSetPosition = next;
+ resp->searchStatus = sr;
+ resp->resultSetStatus = 0;
+ resp->presentStatus = 0;
}
}
- return &apdu;
+ return apdu;
}
/*
int *fd)
{
Z_PresentRequest *req = reqb->request->u.presentRequest;
- static Z_APDU apdu;
- static Z_PresentResponse resp;
- static int presst, next, num;
+ Z_APDU *apdu = odr_malloc (assoc->encode, sizeof(*apdu));
+ Z_PresentResponse *resp = odr_malloc (assoc->encode, sizeof(*resp));
+ int *presst = odr_malloc (assoc->encode, sizeof(*presst));
+ int *next = odr_malloc (assoc->encode, sizeof(*next));
+ int *num = odr_malloc (assoc->encode, sizeof(*num));
oident *prefformat;
oid_value form;
-
logf(LOG_LOG, "Got PresentRequest.");
- apdu.which = Z_APDU_presentResponse;
- apdu.u.presentResponse = &resp;
- resp.referenceId = req->referenceId;
-#ifdef Z_95
- resp.otherInfo = 0;
-#endif
+ *presst = 0;
+ *next = 0;
+ *num = 0;
+
+ apdu->which = Z_APDU_presentResponse;
+ apdu->u.presentResponse = resp;
+ resp->referenceId = req->referenceId;
+ resp->otherInfo = 0;
if (!(prefformat = oid_getentbyoid(req->preferredRecordSyntax)) ||
prefformat->oclass != CLASS_RECSYN)
form = VAL_NONE;
else
form = prefformat->value;
- num = *req->numberOfRecordsRequested;
- resp.records = pack_records(assoc, req->resultSetId,
- *req->resultSetStartPoint, &num, req->recordComposition, &next,
- &presst, form);
- if (!resp.records)
+ *num = *req->numberOfRecordsRequested;
+ resp->records = pack_records(assoc, req->resultSetId,
+ *req->resultSetStartPoint, num, req->recordComposition, next,
+ presst, form);
+ if (!resp->records)
return 0;
- resp.numberOfRecordsReturned = #
- resp.presentStatus = &presst;
- resp.nextResultSetPosition = &next;
+ resp->numberOfRecordsReturned = num;
+ resp->presentStatus = presst;
+ resp->nextResultSetPosition = next;
- return &apdu;
+ return apdu;
}
/*
static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
{
Z_ScanRequest *req = reqb->request->u.scanRequest;
- static Z_APDU apdu;
- static Z_ScanResponse res;
- static int scanStatus = Z_Scan_failure;
- static int numberOfEntriesReturned = 0;
+ Z_APDU *apdu = odr_malloc (assoc->encode, sizeof(*apdu));
+ Z_ScanResponse *res = odr_malloc (assoc->encode, sizeof(*res));
+ int *scanStatus = odr_malloc (assoc->encode, sizeof(*scanStatus));
+ int *numberOfEntriesReturned =
+ odr_malloc (assoc->encode, sizeof(*numberOfEntriesReturned));
+ Z_ListEntries *ents = odr_malloc (assoc->encode, sizeof(*ents));
oident *attent;
- static Z_ListEntries ents;
-#define SCAN_MAX_ENTRIES 200
- static Z_Entry *tab[SCAN_MAX_ENTRIES];
bend_scanrequest srq;
bend_scanresult *srs;
oident *attset;
logf(LOG_LOG, "Got scanrequest");
- apdu.which = Z_APDU_scanResponse;
- apdu.u.scanResponse = &res;
- res.referenceId = req->referenceId;
- res.stepSize = 0;
- res.scanStatus = &scanStatus;
- res.numberOfEntriesReturned = &numberOfEntriesReturned;
- res.positionOfTerm = 0;
- res.entries = &ents;
- ents.which = Z_ListEntries_nonSurrogateDiagnostics;
- res.attributeSet = 0;
-#ifdef Z_95
- res.otherInfo = 0;
-#endif
+ *scanStatus = Z_Scan_failure;
+ *numberOfEntriesReturned = 0;
+
+ apdu->which = Z_APDU_scanResponse;
+ apdu->u.scanResponse = res;
+ res->referenceId = req->referenceId;
+ res->stepSize = 0;
+ res->scanStatus = scanStatus;
+ res->numberOfEntriesReturned = numberOfEntriesReturned;
+ res->positionOfTerm = 0;
+ res->entries = ents;
+ ents->which = Z_ListEntries_nonSurrogateDiagnostics;
+ res->attributeSet = 0;
+ res->otherInfo = 0;
if (req->attributeSet && (!(attent = oid_getentbyoid(req->attributeSet)) ||
attent->oclass != CLASS_ATTSET || attent->value != VAL_BIB1))
- ents.u.nonSurrogateDiagnostics = diagrecs(assoc->proto, 121, 0);
+ ents->u.nonSurrogateDiagnostics = diagrecs(assoc, 121, 0);
else if (req->stepSize && *req->stepSize > 0)
- ents.u.nonSurrogateDiagnostics = diagrecs(assoc->proto, 205, 0);
+ ents->u.nonSurrogateDiagnostics = diagrecs(assoc, 205, 0);
else
{
if (req->termListAndStartPoint->term->which == Z_Term_general)
srq.term_position = req->preferredPositionInResponse ?
*req->preferredPositionInResponse : 1;
if (!(srs = bend_scan(assoc->backend, &srq, 0)))
- ents.u.nonSurrogateDiagnostics = diagrecs(assoc->proto, 2, 0);
+ ents->u.nonSurrogateDiagnostics = diagrecs(assoc, 2, 0);
else if (srs->errcode)
- ents.u.nonSurrogateDiagnostics = diagrecs(assoc->proto,
+ ents->u.nonSurrogateDiagnostics = diagrecs(assoc,
srs->errcode, srs->errstring);
else
{
int i;
- static Z_Entries list;
+ Z_Entries *list = odr_malloc (assoc->encode, sizeof(*list));
+ Z_Entry **tab = odr_malloc (assoc->encode,
+ sizeof(*tab) * srs->num_entries);
if (srs->status == BEND_SCAN_PARTIAL)
- scanStatus = Z_Scan_partial_5;
+ *scanStatus = Z_Scan_partial_5;
else
- scanStatus = Z_Scan_success;
- ents.which = Z_ListEntries_entries;
- ents.u.entries = &list;
- list.entries = tab;
+ *scanStatus = Z_Scan_success;
+ ents->which = Z_ListEntries_entries;
+ ents->u.entries = list;
+ list->entries = tab;
for (i = 0; i < srs->num_entries; i++)
{
Z_Entry *e;
Z_TermInfo *t;
Odr_oct *o;
- if (i >= SCAN_MAX_ENTRIES)
- {
- scanStatus = Z_Scan_partial_4;
- break;
- }
- list.entries[i] = e = odr_malloc(assoc->encode, sizeof(*e));
+ list->entries[i] = e = odr_malloc(assoc->encode, sizeof(*e));
e->which = Z_Entry_termInfo;
e->u.termInfo = t = odr_malloc(assoc->encode, sizeof(*t));
t->suggestedAttributes = 0;
logf(LOG_DEBUG, " term #%d: '%s' (%d)", i,
srs->entries[i].term, srs->entries[i].occurrences);
}
- list.num_entries = i;
- res.numberOfEntriesReturned = &list.num_entries;
- res.positionOfTerm = &srs->term_position;
+ list->num_entries = i;
+ res->numberOfEntriesReturned = &list->num_entries;
+ res->positionOfTerm = &srs->term_position;
}
}
- return &apdu;
+ return apdu;
}
static void process_close(association *assoc, request *reqb)
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: session.h,v $
- * Revision 1.11 1995-11-08 17:41:40 quinn
+ * Revision 1.12 1997-09-01 08:53:01 adam
+ * New windows NT/95 port using MSV5.0. The test server 'ztest' was
+ * moved a separate directory. MSV5.0 project server.dsp created.
+ * As an option, the server can now operate as an NT service.
+ *
+ * Revision 1.11 1995/11/08 17:41:40 quinn
* Smallish.
*
* Revision 1.10 1995/08/29 11:18:01 quinn
#include <oid.h>
#include <proto.h>
#include <sys/types.h>
-#include <eventl.h>
+#include "eventl.h"
typedef struct request
{
char *response; /* encoded data waiting for transmission */
struct request *next;
+ struct request_q *q;
} request;
typedef struct request_q
{
request *head;
request *tail;
+ request *list;
int num;
} request_q;
request *request_head(request_q *q);
request *request_deq(request_q *q);
void request_initq(request_q *q);
-request *request_get(void);
+void request_delq(request_q *q);
+request *request_get(request_q *q);
void request_release(request *r);
#endif
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: statserv.c,v $
- * Revision 1.36 1996-07-06 19:58:36 quinn
+ * Revision 1.37 1997-09-01 08:53:01 adam
+ * New windows NT/95 port using MSV5.0. The test server 'ztest' was
+ * moved a separate directory. MSV5.0 project server.dsp created.
+ * As an option, the server can now operate as an NT service.
+ *
+ * Revision 1.36 1996/07/06 19:58:36 quinn
* System headerfiles gathered in yconfig
*
* Revision 1.35 1996/05/29 10:03:28 quinn
#include <yconfig.h>
#include <stdio.h>
+#ifdef WINDOWS
+#include <process.h>
+#include <winsock.h>
+#include <direct.h>
+#else
#include <unistd.h>
+#include <pwd.h>
+#endif
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
-#include <pwd.h>
#include <options.h>
-#include <eventl.h>
-#include <session.h>
-#include <eventl.h>
+#include "eventl.h"
+#include "session.h"
#include <comstack.h>
#include <tcpip.h>
#ifdef USE_XTIMOSI
#include <log.h>
#include <statserv.h>
+static IOCHAN pListener;
+
static char *me = "statserver";
/*
* default behavior.
* doing all of the listening and accepting in the parent - it's
* safer that way.
*/
+#ifdef WINDOWS
+
+typedef struct _ThreadList ThreadList;
+
+typedef struct _ThreadList
+{
+ HANDLE hThread;
+ IOCHAN pIOChannel;
+ ThreadList *pNext;
+} ThreadList;
+
+static ThreadList *pFirstThread;
+static CRITICAL_SECTION Thread_CritSect;
+static BOOL bInitialized = FALSE;
+
+static void ThreadList_Initialize()
+{
+ /* Initialize the critical Sections */
+ InitializeCriticalSection(&Thread_CritSect);
+
+ /* Set the first thraed */
+ pFirstThread = NULL;
+
+ /* we have been initialized */
+ bInitialized = TRUE;
+}
+
+static void statserv_add(HANDLE hThread, IOCHAN pIOChannel)
+{
+ /* Only one thread can go through this section at a time */
+ EnterCriticalSection(&Thread_CritSect);
+
+ {
+ /* Lets create our new object */
+ ThreadList *pNewThread = (ThreadList *)malloc(sizeof(ThreadList));
+ pNewThread->hThread = hThread;
+ pNewThread->pIOChannel = pIOChannel;
+ pNewThread->pNext = pFirstThread;
+ pFirstThread = pNewThread;
+
+ /* Lets let somebody else create a new object now */
+ LeaveCriticalSection(&Thread_CritSect);
+ }
+}
+
+void statserv_remove(IOCHAN pIOChannel)
+{
+ /* Only one thread can go through this section at a time */
+ EnterCriticalSection(&Thread_CritSect);
+
+ {
+ ThreadList *pCurrentThread = pFirstThread;
+ ThreadList *pNextThread;
+ ThreadList *pPrevThread =NULL;
+
+ /* Step through alll the threads */
+ for (; pCurrentThread != NULL; pCurrentThread = pNextThread)
+ {
+ /* We only need to compare on the IO Channel */
+ if (pCurrentThread->pIOChannel == pIOChannel)
+ {
+ /* We have found the thread we want to delete */
+ /* First of all reset the next pointers */
+ if (pPrevThread == NULL)
+ pFirstThread = pCurrentThread->pNext;
+ else
+ pPrevThread->pNext = pCurrentThread->pNext;
+
+ /* All we need todo now is delete the memory */
+ free(pCurrentThread);
+
+ /* No need to look at any more threads */
+ pNextThread = NULL;
+ }
+ else
+ {
+ /* We need to look at another thread */
+ pNextThread = pCurrentThread->pNext;
+ }
+ }
+
+ /* Lets let somebody else remove an object now */
+ LeaveCriticalSection(&Thread_CritSect);
+ }
+}
+
+void statserv_closedown()
+{
+ /* Shouldn't do anything if we are not initialized */
+ if (bInitialized)
+ {
+ int iHandles = 0;
+ HANDLE *pThreadHandles = NULL;
+
+ /* We need to stop threads adding and removing while we start the closedown process */
+ EnterCriticalSection(&Thread_CritSect);
+
+ {
+ /* We have exclusive access to the thread stuff now */
+ /* Y didn't i use a semaphore - Oh well never mind */
+ ThreadList *pCurrentThread = pFirstThread;
+
+ /* Before we do anything else, we need to shutdown the listener */
+ if (pListener != NULL)
+ iochan_destroy(pListener);
+
+ for (; pCurrentThread != NULL; pCurrentThread = pCurrentThread->pNext)
+ {
+ /* Just destroy the IOCHAN, that should do the trick */
+ iochan_destroy(pCurrentThread->pIOChannel);
+
+ /* Keep a running count of our handles */
+ iHandles++;
+ }
+
+ if (iHandles > 0)
+ {
+ HANDLE *pCurrentHandle ;
+
+ /* Allocate the thread handle array */
+ pThreadHandles = (HANDLE *)malloc(sizeof(HANDLE) * iHandles);
+ pCurrentHandle = pThreadHandles;
+
+ for (pCurrentThread = pFirstThread;
+ pCurrentThread != NULL;
+ pCurrentThread = pCurrentThread->pNext, pCurrentHandle++)
+ {
+ /* Just the handle */
+ *pCurrentHandle = pCurrentThread->hThread;
+ }
+ }
+
+ /* We can now leave the critical section */
+ LeaveCriticalSection(&Thread_CritSect);
+ }
+
+ /* Now we can really do something */
+ if (iHandles > 0)
+ {
+ /* This will now wait, until all the threads close */
+ WaitForMultipleObjects(iHandles, pThreadHandles, TRUE, INFINITE);
+
+ /* Free the memory we allocated for the handle array */
+ free(pThreadHandles);
+ }
+
+ /* No longer require the critical section, since all threads are dead */
+ DeleteCriticalSection(&Thread_CritSect);
+ }
+}
+
+static void listener(IOCHAN h, int event)
+{
+ COMSTACK line = (COMSTACK) iochan_getdata(h);
+ association *newas;
+ int res;
+ HANDLE NewHandle;
+
+ if (event == EVENT_INPUT)
+ {
+ if ((res = cs_listen(line, 0, 0)) < 0)
+ {
+ logf(LOG_FATAL, "cs_listen failed.");
+ return;
+ }
+ else if (res == 1)
+ return;
+ logf(LOG_DEBUG, "listen ok");
+ iochan_setevent(h, EVENT_OUTPUT);
+ iochan_setflags(h, EVENT_OUTPUT | EVENT_EXCEPT); /* set up for acpt */
+ }
+ else if (event == EVENT_OUTPUT)
+ {
+ COMSTACK new_line;
+ IOCHAN new_chan;
+ char *a;
+ DWORD ThreadId;
+
+ if (!(new_line = cs_accept(line)))
+ {
+ logf(LOG_FATAL, "Accept failed.");
+ iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */
+ return;
+ }
+ logf(LOG_DEBUG, "accept ok");
+
+ if (!(new_chan = iochan_create(cs_fileno(new_line), ir_session, EVENT_INPUT)))
+ {
+ logf(LOG_FATAL, "Failed to create iochan");
+ iochan_destroy(h);
+ return;
+ }
+ if (!(newas = create_association(new_chan, new_line)))
+ {
+ logf(LOG_FATAL, "Failed to create new assoc.");
+ iochan_destroy(h);
+ return;
+ }
+ iochan_setdata(new_chan, newas);
+ iochan_settimeout(new_chan, control_block.idle_timeout * 60);
+ a = cs_addrstr(new_line);
+ logf(LOG_LOG, "Accepted connection from %s", a ? a : "[Unknown]");
+
+ /* Now what we need todo is create a new thread with this iochan as the parameter */
+/* if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)event_loop, new_chan, 0, &ThreadId) == NULL)
+*/
+ /* Somehow, somewhere we need to store this thread id, otherwise we won't be able to close cleanly */
+ NewHandle = (HANDLE)_beginthreadex(NULL, 0, event_loop, new_chan, 0, &ThreadId);
+ if (NewHandle == (HANDLE)-1)
+ {
+ logf(LOG_FATAL, "Failed to create new thread.");
+ iochan_destroy(h);
+ return;
+ }
+
+ /* We successfully created the thread, so add it to the list */
+ statserv_add(NewHandle, new_chan);
+
+ logf(LOG_DEBUG, "Created new thread, iochan %p", new_chan);
+ iochan_setflags(h, EVENT_INPUT | EVENT_EXCEPT); /* reset listener */
+ }
+ else
+ {
+ logf(LOG_FATAL, "Bad event on listener.");
+ iochan_destroy(h);
+ return;
+ }
+}
+
+#else /* WINDOWS */
+
+/* To save having an #ifdef in event_loop we need to define this empty function */
+void statserv_remove(IOCHAN pIOChannel)
+{
+}
+
+void statserv_closedown()
+{
+ /* We don't need todoanything here - or do we */
+ if (pListener != NULL)
+ iochan_destroy(pListener);
+}
+
static void listener(IOCHAN h, int event)
{
COMSTACK line = (COMSTACK) iochan_getdata(h);
if (pipe(hand) < 0)
{
logf(LOG_FATAL|LOG_ERRNO, "pipe");
- exit(1);
+ iochan_destroy(h);
+ return;
}
if ((res = fork()) < 0)
{
logf(LOG_FATAL|LOG_ERRNO, "fork");
- exit(1);
+ iochan_destroy(h);
+ return;
}
else if (res == 0) /* child */
{
if ((res = read(hand[0], dummy, 1)) < 0 && errno != EINTR)
{
logf(LOG_FATAL|LOG_ERRNO, "handshake read");
- exit(1);
+ return;
}
else if (res >= 0)
break;
EVENT_INPUT)))
{
logf(LOG_FATAL, "Failed to create iochan");
- exit(1);
+ iochan_destroy(h);
+ return;
}
if (!(newas = create_association(new_chan, new_line)))
{
logf(LOG_FATAL, "Failed to create new assoc.");
- exit(1);
+ iochan_destroy(h);
+ return;
}
iochan_setdata(new_chan, newas);
iochan_settimeout(new_chan, control_block.idle_timeout * 60);
else
{
logf(LOG_FATAL, "Bad event on listener.");
- exit(1);
+ iochan_destroy(h);
+ return;
}
}
+#endif /* WINDOWS */
+
static void inetd_connection(int what)
{
COMSTACK line;
association *assoc;
char *addr;
- if (!(line = cs_createbysocket(0, tcpip_type, 0, what)))
+ if ((line = cs_createbysocket(0, tcpip_type, 0, what)))
{
- logf(LOG_ERRNO|LOG_FATAL, "Failed to create comstack on socket 0");
- exit(1);
- }
- if (!(chan = iochan_create(cs_fileno(line), ir_session, EVENT_INPUT)))
- {
- logf(LOG_FATAL, "Failed to create iochan");
- exit(1);
+ if ((chan = iochan_create(cs_fileno(line), ir_session, EVENT_INPUT)))
+ {
+ if ((assoc = create_association(chan, line)))
+ {
+ iochan_setdata(chan, assoc);
+ iochan_settimeout(chan, control_block.idle_timeout * 60);
+ addr = cs_addrstr(line);
+ logf(LOG_LOG, "Inetd association from %s", addr ? addr : "[UNKNOWN]");
+ }
+ else
+ {
+ logf(LOG_FATAL, "Failed to create association structure");
+ }
+ }
+ else
+ {
+ logf(LOG_FATAL, "Failed to create iochan");
+ }
}
- if (!(assoc = create_association(chan, line)))
+ else
{
- logf(LOG_FATAL, "Failed to create association structure");
- exit(1);
+ logf(LOG_ERRNO|LOG_FATAL, "Failed to create comstack on socket 0");
}
- iochan_setdata(chan, assoc);
- iochan_settimeout(chan, control_block.idle_timeout * 60);
- addr = cs_addrstr(line);
- logf(LOG_LOG, "Inetd association from %s", addr ? addr : "[UNKNOWN]");
}
/*
CS_TYPE type;
char mode[100], addr[100];
void *ap;
- IOCHAN lst;
+ IOCHAN lst = NULL;
if (!where || sscanf(where, "%[^:]:%s", mode, addr) != 2)
{
fprintf(stderr, "%s: Address format: ('tcp'|'osi')':'<address>.\n",
me);
- exit(1);
}
if (!strcmp(mode, "tcp"))
{
if (!(ap = tcpip_strtoaddr(addr)))
{
fprintf(stderr, "Address resolution failed for TCP.\n");
- exit(1);
}
type = tcpip_type;
}
if (!(ap = mosi_strtoaddr(addr)))
{
fprintf(stderr, "Address resolution failed for TCP.\n");
- exit(1);
}
type = mosi_type;
#else
fprintf(stderr, "OSI Transport not allowed by configuration.\n");
- exit(1);
#endif
}
else
{
fprintf(stderr, "You must specify either 'osi:' or 'tcp:'.\n");
- exit(1);
}
logf(LOG_LOG, "Adding %s %s listener on %s",
control_block.dynamic ? "dynamic" : "static",
if (!(l = cs_create(type, 0, what)))
{
logf(LOG_FATAL|LOG_ERRNO, "Failed to create listener");
- exit(1);
}
if (cs_bind(l, ap, CS_SERVER) < 0)
{
logf(LOG_FATAL|LOG_ERRNO, "Failed to bind to %s", where);
- exit(1);
}
if (!(lst = iochan_create(cs_fileno(l), listener, EVENT_INPUT |
EVENT_EXCEPT)))
{
logf(LOG_FATAL|LOG_ERRNO, "Failed to create IOCHAN-type");
- exit(1);
}
iochan_setdata(lst, l);
+
+ /* Ensure our listener chain is setup properly */
+ lst->next = pListener;
+ pListener = lst;
}
+#ifndef WINDOWS
+/* For windows we don't need to catch the signals */
static void catchchld(int num)
{
while (waitpid(-1, 0, WNOHANG) > 0)
;
signal(SIGCHLD, catchchld);
}
+#endif /* WINDOWS */
statserv_options_block *statserv_getcontrol(void)
{
char *arg;
int protocol = control_block.default_proto;
+#ifdef WINDOWS
+ /* We need to initialize the thread list */
+ ThreadList_Initialize();
+#endif /* WINDOWS */
+
me = argv[0];
while ((ret = options("a:iszSl:v:u:c:w:t:k:", argv, argc, &arg)) != -2)
{
switch (ret)
{
case 0:
- add_listener(arg, protocol);
- listeners++;
+ add_listener(arg, protocol);
+ listeners++;
break;
case 'z': protocol = PROTO_Z3950; break;
case 's': protocol = PROTO_SR; break;
{
fprintf(stderr, "%s: Specify positive timeout for -t.\n",
me);
- exit(1);
+ return(1);
}
control_block.idle_timeout = r;
break;
{
fprintf(stderr, "%s: Specify positive timeout for -t.\n",
me);
- exit(1);
+ return(1);
}
control_block.maxrecordsize = r * 1024;
break;
if (chdir(arg))
{
perror(arg);
- exit(1);
+
+ return(1);
}
break;
default:
" -l <logfile> -u <user> -c <config> -t <minutes>"
" -k <kilobytes>"
" -zsS <listener-addr> -w <directory> ... ]\n", me);
- exit(1);
+ return(1);
}
}
+
+#ifdef WINDOWS
+ log_init(control_block.loglevel, NULL, control_block.logfile);
+#endif /* WINDOWS */
+
+ if ((pListener == NULL) && *control_block.default_listen)
+ add_listener(control_block.default_listen, protocol);
+
+#ifndef WINDOWS
if (inetd)
inetd_connection(protocol);
else
{
if (control_block.dynamic)
signal(SIGCHLD, catchchld);
- if (!listeners && *control_block.default_listen)
- add_listener(control_block.default_listen, protocol);
}
if (*control_block.setuid)
{
if (!(pw = getpwnam(control_block.setuid)))
{
logf(LOG_FATAL, "%s: Unknown user", control_block.setuid);
- exit(1);
+ return(1);
}
if (setuid(pw->pw_uid) < 0)
{
exit(1);
}
}
+#endif /* WINDOWS */
+
logf(LOG_LOG, "Entering event loop.");
-
- return event_loop();
+
+ if (pListener == NULL)
+ return(1);
+ else
+ return event_loop(pListener);
}