/*
* Copyright (c) 1998-2001, Index Data.
* See the file LICENSE for details.
*
* $Id: yaz-my-server.cpp,v 1.20 2006/03/29 13:14:16 adam Exp $
*/
#include <stdlib.h>
#include <yaz/log.h>
#include <yaz/diagbib1.h>
#include <yaz/options.h>
#include <yazpp/z-server.h>
#include <yazpp/pdu-assoc.h>
#include <yazpp/socket-manager.h>
using namespace yazpp_1;
class MyILL : public Yaz_Facility_ILL {
public:
void ill_service (Z_ExtendedServicesRequest *req,
Z_ItemOrder *io,
Z_ExtendedServicesResponse *res);
};
class MyUpdate : public Yaz_Facility_Update {
public:
void update_service (Z_ExtendedServicesRequest *req,
Z_IUUpdate *io,
Z_ExtendedServicesResponse *res);
void update_service0 (Z_ExtendedServicesRequest *req,
Z_IU0Update *io,
Z_ExtendedServicesResponse *res);
};
class MyRetrieval : public Yaz_Facility_Retrieval, Yaz_USMARC {
public:
int sr_init (Z_InitRequest *initRequest,
Z_InitResponse *initResponse);
void sr_search (Z_SearchRequest *searchRequest,
Z_SearchResponse *searchResponse);
void sr_present (Z_PresentRequest *presentRequest,
Z_PresentResponse *presentResponse);
void sr_record (const char *resultSetName,
int position,
int *format,
Z_RecordComposition *comp,
Z_NamePlusRecord *namePlusRecord,
Z_Records *records);
};
class MyServer : public Z_Server {
public:
~MyServer();
MyServer(IPDU_Observable *the_PDU_Observable);
IPDU_Observer* sessionNotify(IPDU_Observable *the_PDU_Observable,
int fd);
void failNotify();
void timeoutNotify();
void connectNotify();
private:
MyRetrieval m_retrieval;
MyILL m_ill;
MyUpdate m_update;
int m_no;
};
void MyILL::ill_service (Z_ExtendedServicesRequest *req,
Z_ItemOrder *io,
Z_ExtendedServicesResponse *res)
{
yaz_log (YLOG_LOG, "MyServer::ill_service");
}
void MyUpdate::update_service (Z_ExtendedServicesRequest *req,
Z_IUUpdate *io,
Z_ExtendedServicesResponse *res)
{
yaz_log (YLOG_LOG, "MyServer::update_service (v1.1)");
}
void MyUpdate::update_service0 (Z_ExtendedServicesRequest *req,
Z_IU0Update *io,
Z_ExtendedServicesResponse *res)
{
yaz_log (YLOG_LOG, "MyServer::update_service (v1.0)");
}
int MyRetrieval::sr_init (Z_InitRequest *initRequest,
Z_InitResponse *initResponse)
{
yaz_log (YLOG_LOG, "MyServer::sr_init");
return 1;
}
void MyRetrieval::sr_search (Z_SearchRequest *searchRequest,
Z_SearchResponse *searchResponse)
{
yaz_log (YLOG_LOG, "MyServer::recv_Z_search");
if (searchRequest->query->which == Z_Query_type_1)
{
Z_RPNStructure *s = searchRequest->query->u.type_1->RPNStructure;
if (s->which == Z_RPNStructure_simple &&
s->u.simple->which == Z_Operand_APT &&
s->u.simple->u.attributesPlusTerm->term->which == Z_Term_general)
{
Odr_oct *term = s->u.simple->u.attributesPlusTerm->term->u.general;
char *str = (char *) odr_malloc (odr_encode(), term->len+1);
if (term->len)
memcpy (str, term->buf, term->len);
str[term->len] = '\0';
*searchResponse->resultCount = atoi(str);
}
}
}
void MyRetrieval::sr_present (Z_PresentRequest *presentRequest,
Z_PresentResponse *presentResponse)
{
yaz_log (YLOG_LOG, "MyServer::recv_Z_present");
}
void MyRetrieval::sr_record (const char *resultSetName,
int position,
int *format,
Z_RecordComposition *comp,
Z_NamePlusRecord *namePlusRecord,
Z_Records *records)
{
yaz_log (YLOG_LOG, "MyServer::recv_Z_record");
const char *rec = get_record(position);
if (rec)
create_databaseRecord (odr_encode(), namePlusRecord, 0,
VAL_USMARC, rec, strlen(rec));
else
create_surrogateDiagnostics(odr_encode(), namePlusRecord, 0,
YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, 0);
}
MyServer::~MyServer()
{
}
IPDU_Observer *MyServer::sessionNotify(
IPDU_Observable *the_PDU_Observable, int fd)
{
MyServer *new_server;
m_no++;
new_server = new MyServer(the_PDU_Observable);
new_server->timeout(900);
new_server->facility_add(&new_server->m_retrieval, "my sr");
new_server->facility_add(&new_server->m_ill, "my ill");
new_server->facility_add(&new_server->m_update, "my update");
new_server->set_APDU_log(get_APDU_log());
return new_server;
}
MyServer::MyServer(IPDU_Observable *the_PDU_Observable) :
Z_Server (the_PDU_Observable)
{
m_no = 0;
}
void MyServer::timeoutNotify()
{
yaz_log (YLOG_LOG, "connection timed out");
delete this;
}
void MyServer::failNotify()
{
yaz_log (YLOG_LOG, "connection closed by client");
delete this;
}
void MyServer::connectNotify()
{
}
void usage(const char *prog)
{
fprintf (stderr, "%s: [-a log] [-v level] [-T] @:port\n", prog);
exit (1);
}
int main(int argc, char **argv)
{
int thread_flag = 0;
char *arg;
char *prog = *argv;
const char *addr = "tcp:@:9999";
char *apdu_log = 0;
SocketManager mySocketManager;
PDU_Assoc *my_PDU_Assoc = 0;
MyServer *z = 0;
int ret;
while ((ret = options("a:v:T", argv, argc, &arg)) != -2)
{
switch (ret)
{
case 0:
addr = xstrdup(arg);
break;
case 'a':
apdu_log = xstrdup(arg);
break;
case 'v':
yaz_log_init_level (yaz_log_mask_str(arg));
break;
case 'T':
thread_flag = 1;
break;
default:
usage(prog);
return 1;
}
}
#if YAZ_POSIX_THREADS
if (thread_flag)
my_PDU_Assoc = new PDU_AssocThread(&mySocketManager);
else
my_PDU_Assoc = new PDU_Assoc(&mySocketManager);
#else
my_PDU_Assoc = new PDU_Assoc(&mySocketManager);
#endif
z = new MyServer(my_PDU_Assoc);
z->server(addr);
if (apdu_log)
{
yaz_log (YLOG_LOG, "set_APDU_log %s", apdu_log);
z->set_APDU_log(apdu_log);
}
while (mySocketManager.processEvent() > 0)
;
delete z;
return 0;
}
/*
* Local variables:
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab
*/
syntax highlighted by Code2HTML, v. 0.9.1