* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-ir-assoc.h,v $
- * Revision 1.3 1999-02-02 14:01:12 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:12 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:39 adam
void connectNotify();
/// Failure notification
void failNotify();
+ /// Timeout notification
+ void timeoutNotify();
/// Begin Z39.50 client role
void client(const char *addr);
/// Begin Z39.50 server role
/// Send Z39.50 PDU
int send_Z_PDU(Z_APDU *apdu);
/// Receive Z39.50 PDU
- virtual void recv_Z_PDU (Z_APDU *apdu) = 0;
- /// Create Z39.50 with reasonable defaults
+ virtual void recv_Z_PDU(Z_APDU *apdu) = 0;
+ /// Create Z39.50 PDU with reasonable defaults
Z_APDU *create_Z_PDU(int type);
+ /// Request Alloc
+ ODR odr_encode ();
+ private:
static int yaz_init_flag;
static int yaz_init_func();
- private:
IYaz_PDU_Observable *m_PDU_Observable;
ODR m_odr_in;
ODR m_odr_out;
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-pdu-assoc.h,v $
- * Revision 1.3 1999-02-02 14:01:13 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:13 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:40 adam
PDU_Queue *m_queue_out;
int Yaz_PDU_Assoc::flush_PDU();
int *m_destroyed;
+ int m_idleTime;
public:
/// Create object using specified socketObservable
Yaz_PDU_Assoc(IYazSocketObservable *socketObservable, COMSTACK cs);
void close();
/// Close and destroy
void destroy();
+ /// Set Idle Time
+ void idleTime (int timeout);
};
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-pdu-observer.h,v $
- * Revision 1.3 1999-02-02 14:01:14 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:14 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:41 adam
virtual IYaz_PDU_Observable *clone() = 0;
/// Destroy completely
virtual void destroy() = 0;
+ /// Set Idle Time
+ virtual void idleTime (int timeout) = 0;
};
/** Protocol Data Unit Observer.
virtual void connectNotify() = 0;
/// Called whenever the connection was closed
virtual void failNotify() = 0;
+ /// Called whenever the connection was closed
+ virtual void timeoutNotify() = 0;
/// Make clone of observer using IYaz_PDU_Observable interface
virtual IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable) = 0;
};
--- /dev/null
+/*
+ * Copyright (c) 1998-1999, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: yaz-query.h,v $
+ * Revision 1.1 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ */
+
+
+/** Query
+ Generic Query.
+*/
+class YAZ_EXPORT Yaz_Query {
+ public:
+ /// Print query in buffer described by str and len
+ virtual void print (char *str, int len) = 0;
+};
+
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-socket-manager.h,v $
- * Revision 1.2 1999-02-02 14:01:16 adam
+ * Revision 1.3 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.2 1999/02/02 14:01:16 adam
* First WIN32 port of YAZ++.
*
* Revision 1.1.1.1 1999/01/28 09:41:07 adam
*/
#include <yaz-socket-observer.h>
+#include <time.h>
/** Simple Socket Manager.
Implements a stand-alone simple model that uses select(2) to
int fd;
unsigned mask;
unsigned timeout;
+ time_t last_activity;
YazSocketEntry *next;
};
YazSocketEntry *m_observers; // all registered observers
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-socket-observer.h,v $
- * Revision 1.2 1999-02-02 14:01:17 adam
+ * Revision 1.3 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.2 1999/02/02 14:01:17 adam
* First WIN32 port of YAZ++.
*
* Revision 1.1.1.1 1999/01/28 09:41:07 adam
#define YAZ_SOCKET_OBSERVE_READ 1
#define YAZ_SOCKET_OBSERVE_WRITE 2
#define YAZ_SOCKET_OBSERVE_EXCEPT 4
-#define YAZ_SOCKET_OBSERVE_TIME 8
+#define YAZ_SOCKET_OBSERVE_TIMEOUT 8
/**
Forward reference
--- /dev/null
+/*
+ * Copyright (c) 1998-1999, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: yaz-z-query.h,v $
+ * Revision 1.1 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ */
+
+#include <proto.h>
+#include <yaz-query.h>
+
+/** Z39.50 Query
+ RPN, etc.
+*/
+class YAZ_EXPORT Yaz_Z_Query : public Yaz_Query {
+ public:
+ /// Make Query from rpn string
+ Yaz_Z_Query();
+ /// Delete Query
+ virtual ~Yaz_Z_Query();
+ /// Set RPN
+ void set_rpn (const char *rpn);
+ /// Set Z Query
+ void set_Z_Query (Z_Query *z_query);
+ /// Get Z Query
+ Z_Query *get_Z_Query ();
+ /// print query
+ void print(char *str, int len);
+ private:
+ char *buf;
+ int len;
+ ODR odr_decode;
+ ODR odr_encode;
+};
-# Copyright (C) 1999, Index Data
+# Copyright (C) 1999, Index Data ApS
# All rights reserved.
# Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile.in,v 1.2 1999-01-28 10:04:47 adam Exp $
+# $Id: Makefile.in,v 1.3 1999-03-23 14:17:57 adam Exp $
SHELL=/bin/sh
PROG3=yaz-proxy
PROGO3=yaz-proxy-main.o
LIB=libyaz++.lib
-PO=yaz-socket-manager.o yaz-pdu-assoc.o yaz-ir-assoc.o yaz-proxy.o
+PO=yaz-socket-manager.o yaz-pdu-assoc.o yaz-ir-assoc.o yaz-proxy.o \
+ yaz-z-query.o
-.SUFFIXES: .cc
+.SUFFIXES: .cpp
all: $(PROG1) $(PROG2) $(PROG3)
alll:
-.cc.o:
+.cpp.o:
$(CXX) -c $(DEFS) $(CXXFLAGS) $<
.c.o:
clean:
rm -f *.[oa] test core mon.out gmon.out errlist
- rm -f $(PROG1) $(PROG2) $(PROG3)
+ rm -f $(PROG1) $(PROG2) $(PROG3) $(LIB)
depend:
sed '/^#Depend/q' <Makefile >Makefile.tmp
- $(CXXCPP) $(DEFS) -M *.cc >>Makefile.tmp
+ $(CXXCPP) $(DEFS) -M *.cpp >>Makefile.tmp
mv -f Makefile.tmp Makefile
#Depend --- DOT NOT DELETE THIS LINE
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-client.cpp,v $
- * Revision 1.3 1999-02-02 14:01:18 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:18 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:42 adam
#include <yaz-ir-assoc.h>
#include <yaz-pdu-assoc.h>
#include <yaz-socket-manager.h>
+#include <yaz-z-query.h>
class YAZ_EXPORT MyClient : public Yaz_IR_Assoc {
public:
void recv_Z_PDU(Z_APDU *apdu);
IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable);
void init();
+ void search(Yaz_Z_Query *query);
+ void present(int start, int number);
+ void set_databaseNames (int num, char **list);
+ void set_syntax (const char *syntax);
+ void set_elementSetName (const char *elementSetName);
+private:
+ int m_num_databaseNames;
+ char **m_databaseNames;
+ int m_recordSyntax;
+ Z_ElementSetNames *m_elementSetNames;
};
void MyClient::recv_Z_PDU(Z_APDU *apdu)
case Z_APDU_searchResponse:
logf (LOG_LOG, "got searchResponse");
break;
+ case Z_APDU_presentResponse:
+ logf (LOG_LOG, "got presentResponse");
+ break;
}
}
MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable) :
Yaz_IR_Assoc (the_PDU_Observable)
{
+ m_num_databaseNames = 0;
+ m_databaseNames = 0;
+ m_recordSyntax = VAL_NONE;
+}
+
+void MyClient::set_databaseNames (int num, char **list)
+{
+ int i;
+ for (i = 0; i<m_num_databaseNames; i++)
+ delete m_databaseNames[i];
+ delete m_databaseNames;
+ m_databaseNames = 0;
+ m_num_databaseNames = num;
+ m_databaseNames = new (char*) [num];
+ for (i = 0; i<m_num_databaseNames; i++)
+ {
+ m_databaseNames[i] = new char[strlen(list[i])+1];
+ strcpy (m_databaseNames[i], list[i]);
+ }
+}
+
+void MyClient::set_syntax (const char *syntax)
+{
+ m_recordSyntax = VAL_NONE;
+ if (syntax && *syntax)
+ m_recordSyntax = oid_getvalbyname (syntax);
+}
+
+void MyClient::set_elementSetName (const char *elementSetName)
+{
+ if (m_elementSetNames)
+ delete [] m_elementSetNames->u.generic;
+ delete m_elementSetNames;
+ m_elementSetNames = 0;
+ if (elementSetName && *elementSetName)
+ {
+ m_elementSetNames = new Z_ElementSetNames;
+ m_elementSetNames->which = Z_ElementSetNames_generic;
+ m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
+ strcpy (m_elementSetNames->u.generic, elementSetName);
+ }
+}
+
+void MyClient::search(Yaz_Z_Query *query)
+{
+ Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
+ Z_SearchRequest *req = apdu->u.searchRequest;
+
+ req->num_databaseNames = m_num_databaseNames;
+ req->databaseNames = m_databaseNames;
+ req->query = query->get_Z_Query();
+
+ int oid_syntax[OID_SIZE];
+ oident prefsyn;
+ if (m_recordSyntax != VAL_NONE)
+ {
+ prefsyn.proto = PROTO_Z3950;
+ prefsyn.oclass = CLASS_RECSYN;
+ prefsyn.value = (enum oid_value) m_recordSyntax;
+ oid_ent_to_oid(&prefsyn, oid_syntax);
+ req->preferredRecordSyntax = oid_syntax;
+ }
+ send_Z_PDU(apdu);
+}
+
+void MyClient::present(int start, int number)
+{
+ Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
+ Z_PresentRequest *req = apdu->u.presentRequest;
+
+ req->resultSetStartPoint = &start;
+ req->numberOfRecordsRequested = &number;
+
+ int oid_syntax[OID_SIZE];
+ oident prefsyn;
+ if (m_recordSyntax != VAL_NONE)
+ {
+ prefsyn.proto = PROTO_Z3950;
+ prefsyn.oclass = CLASS_RECSYN;
+ prefsyn.value = (enum oid_value) m_recordSyntax;
+ oid_ent_to_oid(&prefsyn, oid_syntax);
+ req->preferredRecordSyntax = oid_syntax;
+ }
+ Z_RecordComposition compo;
+ if (m_elementSetNames)
+ {
+ req->recordComposition = &compo;
+ compo.which = Z_RecordComp_simple;
+ compo.u.simple = m_elementSetNames;
+ }
+ send_Z_PDU(apdu);
}
void MyClient::init()
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-ir-assoc.cpp,v $
- * Revision 1.3 1999-02-02 14:01:19 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:19 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:43 adam
logf (LOG_LOG, "failNotify");
}
+void Yaz_IR_Assoc::timeoutNotify()
+{
+ logf (LOG_LOG, "timeoutNotify");
+}
+
void Yaz_IR_Assoc::client(const char *addr)
{
m_PDU_Observable->connect (this, addr);
m_PDU_Observable->listen (this, addr);
}
+ODR Yaz_IR_Assoc::odr_encode()
+{
+ return m_odr_out;
+}
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-pdu-assoc.cpp,v $
- * Revision 1.3 1999-02-02 14:01:20 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:20 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:44 adam
assoc->m_socketObservable->maskObserver(assoc,
YAZ_SOCKET_OBSERVE_READ|
YAZ_SOCKET_OBSERVE_EXCEPT);
+ if (m_idleTime)
+ assoc->m_socketObservable->timeoutObserver(assoc, m_idleTime);
}
}
else if (m_state == Ready)
return;
} while (m_cs && cs_more (m_cs));
}
+ if (event & YAZ_SOCKET_OBSERVE_TIMEOUT)
+ {
+ m_PDU_Observer->timeoutNotify();
+ }
}
}
m_state = Listen;
}
+void Yaz_PDU_Assoc::idleTime(int idleTime)
+{
+ m_idleTime = idleTime;
+}
+
void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer,
const char *addr)
{
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-server.cpp,v $
- * Revision 1.3 1999-02-02 14:01:22 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:22 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:47 adam
void recv_Z_PDU(Z_APDU *apdu);
IYaz_PDU_Observer* clone(IYaz_PDU_Observable *the_PDU_Observable);
void failNotify();
+ void timeoutNotify();
private:
int m_no;
};
IYaz_PDU_Observer *MyServer::clone(IYaz_PDU_Observable *the_PDU_Observable)
{
- logf (LOG_LOG, "clone %d", m_no);
+ logf (LOG_LOG, "child no %d", m_no);
m_no++;
return new MyServer(the_PDU_Observable);
}
m_no = 0;
}
+void MyServer::timeoutNotify()
+{
+ logf (LOG_LOG, "connection timed out");
+ delete this;
+}
+
void MyServer::failNotify()
{
+ logf (LOG_LOG, "connection closed by client");
delete this;
}
int main(int argc, char **argv)
{
Yaz_SocketManager mySocketManager;
+ Yaz_PDU_Assoc *my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager, 0);
- MyServer z(new Yaz_PDU_Assoc(&mySocketManager, 0));
+ my_PDU_Assoc->idleTime(20);
+ MyServer z(my_PDU_Assoc);
if (argc <= 1)
z.server("@:9999");
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: yaz-socket-manager.cpp,v $
- * Revision 1.3 1999-02-02 14:01:23 adam
+ * Revision 1.4 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ * Revision 1.3 1999/02/02 14:01:23 adam
* First WIN32 port of YAZ++.
*
* Revision 1.2 1999/01/28 13:08:48 adam
}
se->fd = fd;
se->mask = 0;
+ se->last_activity = 0;
+ se->timeout = 0;
}
void Yaz_SocketManager::deleteObserver(IYazSocketObserver *observer)
{
YazSocketEntry *p;
YazSocketEvent *event = getEvent();
+ unsigned timeout = 0;
if (event)
{
event->observer->socketNotify(event->event);
int res;
int max = 0;
int no = 0;
- struct timeval to;
- struct timeval *timeout = &to;
FD_ZERO(&in);
FD_ZERO(&out);
FD_ZERO(&except);
- timeout = &to; /* hang on select */
- to.tv_sec = 60;
- to.tv_usec = 0;
-
+ time_t now = time(0);
for (p = m_observers; p; p = p->next)
{
int fd = p->fd;
- logf (LOG_LOG, "fd = %d mask=%d", fd, p->mask);
if (p->mask)
no++;
if (p->mask & YAZ_SOCKET_OBSERVE_READ)
FD_SET(fd, &except);
if (fd > max)
max = fd;
+ if (p->timeout)
+ {
+ unsigned timeout_this;
+ timeout_this = p->timeout;
+ if (p->last_activity)
+ timeout_this -= now - p->last_activity;
+ if (timeout_this < 1)
+ timeout_this = 1;
+ if (!timeout || timeout_this < timeout)
+ timeout = timeout_this;
+ }
}
if (!no)
return 0;
- while ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
+
+ struct timeval to;
+ to.tv_sec = timeout;
+ to.tv_usec = 0;
+
+ while ((res = select(max + 1, &in, &out, &except, timeout ? &to : 0)) < 0)
if (errno != EINTR)
return -1;
-
+ now = time(0);
for (p = m_observers; p; p = p->next)
{
int fd = p->fd;
if (mask)
{
YazSocketEvent *event = new YazSocketEvent;
+ p->last_activity = now;
event->observer = p->observer;
event->event = mask;
putEvent (event);
}
+ else if (p->timeout && now >= p->last_activity + (int) (p->timeout))
+ {
+ YazSocketEvent *event = new YazSocketEvent;
+ p->last_activity = now;
+ event->observer = p->observer;
+ event->event = YAZ_SOCKET_OBSERVE_TIMEOUT;
+ putEvent (event);
+ }
}
if ((event = getEvent()))
{
--- /dev/null
+/*
+ * Copyright (c) 1998-1999, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: yaz-z-query.cpp,v $
+ * Revision 1.1 1999-03-23 14:17:57 adam
+ * More work on timeout handling. Work on yaz-client.
+ *
+ */
+
+#include <yaz-z-query.h>
+#include <pquery.h>
+
+Yaz_Z_Query::Yaz_Z_Query()
+{
+ odr_encode = odr_createmem (ODR_ENCODE);
+ odr_decode = odr_createmem (ODR_DECODE);
+}
+
+void Yaz_Z_Query::set_rpn (const char *rpn)
+{
+ buf = 0;
+ odr_reset (odr_encode);
+ Z_Query *query = (Z_Query*) odr_malloc (odr_encode, sizeof(*query));
+ query->which = Z_Query_type_1;
+ query->u.type_1 = p_query_rpn (odr_encode, PROTO_Z3950, rpn);
+ if (!query->u.type_1)
+ return;
+ if (!z_Query (odr_encode, &query, 0))
+ return;
+ buf = odr_getbuf (odr_encode, &len, 0);
+}
+
+void Yaz_Z_Query::set_Z_Query(Z_Query *z_query)
+{
+ buf = 0;
+ odr_reset (odr_encode);
+ if (!z_Query (odr_encode, &z_query, 0))
+ return;
+ buf = odr_getbuf (odr_encode, &len, 0);
+}
+
+Yaz_Z_Query::~Yaz_Z_Query()
+{
+ odr_destroy (odr_encode);
+ odr_destroy (odr_decode);
+}
+
+Z_Query *Yaz_Z_Query::get_Z_Query ()
+{
+ Z_Query *query;
+ if (!buf)
+ return 0;
+ odr_setbuf (odr_decode, buf, len, 0);
+ if (!z_Query(odr_decode, &query, 0))
+ return 0;
+ return query;
+}
+
+void Yaz_Z_Query::print(char *str, int len)
+{
+
+}
# Copyright (C) 1999, Index Data
# All rights reserved.
# Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile.in,v 1.1 1999-01-28 09:41:07 adam Exp $
+# $Id: Makefile.in,v 1.2 1999-03-23 14:17:57 adam Exp $
SHELL=/bin/sh
MAKE=make
-.PHONY: all doc clean distclean
+.PHONY: all doc clean distclean depend
all:
cd ../src; $(MAKE)
+depend:
+ cd ../src; $(MAKE) depend
doc:
cd ../include; doc++ -H -d ../doc *.h
-dnl YAZ Toolkit
-dnl (c) Index Data 1994-1999
+dnl YAZ++ Toolkit configure script.
+dnl (c) Index Data ApS 1999
dnl See the file LICENSE for details.
-dnl $Id: configure.in,v 1.1 1999-01-28 09:41:07 adam Exp $
+dnl $Id: configure.in,v 1.2 1999-03-23 14:17:57 adam Exp $
AC_INIT(../include/yaz-socket-manager.h)
dnl
dnl ------ Checking programs