From 852a79d842c7294e2191ee23e072510c5bd98f0c Mon Sep 17 00:00:00 2001 From: Sebastian Hammer Date: Tue, 14 Nov 2006 20:44:36 +0000 Subject: [PATCH] Initial revision --- .cvsignore | 1 + .gdb_history | 208 ++++++++++++++++++ .pazpar2.c.swp | Bin 0 -> 28725 bytes .pazpar2.h.swp | Bin 0 -> 12288 bytes Makefile | 26 +++ bad.pz | 17 ++ command.c | 350 ++++++++++++++++++++++++++++++ command.h | 6 + danish.pz | 21 ++ def.pz | 17 ++ defport.pz | 5 + eventl.c | 142 +++++++++++++ eventl.h | 96 +++++++++ h1.pz | 9 + local.pz | 10 + multi.pz | 9 + multi.txt | 220 +++++++++++++++++++ pazpar2.c | 643 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pazpar2.h | 57 +++++ test.pz | 1 + util.c | 13 ++ util.h | 8 + 22 files changed, 1859 insertions(+) create mode 100644 .cvsignore create mode 100644 .gdb_history create mode 100644 .pazpar2.c.swp create mode 100644 .pazpar2.h.swp create mode 100644 Makefile create mode 100644 bad.pz create mode 100644 command.c create mode 100644 command.h create mode 100644 danish.pz create mode 100644 def.pz create mode 100644 defport.pz create mode 100644 eventl.c create mode 100644 eventl.h create mode 100644 h1.pz create mode 100644 local.pz create mode 100644 multi.pz create mode 100644 multi.txt create mode 100644 pazpar2.c create mode 100644 pazpar2.h create mode 100644 test.pz create mode 100644 util.c create mode 100644 util.h diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..62661d9 --- /dev/null +++ b/.cvsignore @@ -0,0 +1 @@ +paraz diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..4377013 --- /dev/null +++ b/.gdb_history @@ -0,0 +1,208 @@ +break main +run -c 2000 +quit +break main +run -c 2000 +next +ste +step +next +print hostbuf +next +un +run +nexrt +next +step +next +step +next +print p +print *p +next +cont +run +quit +break main +run -c 2000 +next +step +next +print hostbuf +next +list +bt +frame 1 +list +break event_loop +delete 1 +run +next +print *p +next +quit +break command_accept +run -c 2000 +next +print s +next +print channel_list +print *channel_list +print *channel_list->next +next +print max +next +next +quit +breack command_command +break command_command +run -c 2000 +run +next +print *s +print *s->channel +run +run +run +quit +run -c 2000 +break command_command +cont +next +break command_accept +cont +run +finish +cont +next +cont +next +print res +next +cont +con +cont +quit +run -c 2000 +break command_io +cont +cont +next +print buf +quit +run -c 2000 +break command_command +cont +next +print argv +cont +next +list +break 54 +cont +print argv +print argc +cont +quit +break load_targets +run -c 2000 +finish +print channel_list +print *channel_list +print *channel_list->data +print *channel_list->next +next +break handler +cont +next +print *target +print *t +next +print res +print errno +print erddrno +print (int)errno +quit +run -c 2000 +run -c 2001 +run +run -c 2000 +break handler +cont +next +print res +next +cont +next +h +run -c 2001 +next +cont +next +cont +print channel_list +print *channel_list +print *channel_list->next +print *channel_list->next->next +run -c 2000 +next +cont +next +cont +next +print *a +print *a->u.initResponse +next +step +next +cont +delete 1 +cont +cont +run -c 2000 +bt +frame 4 +list +print *session +print *s +list +print *i +run +run -c 2001 +run -c 2000 +run -c 2001 +run -c 2000 +cont +quit +run -c 2000 +break handler +cont +cont +cont +cont +cont +next +print *p +next +print *p +next +next +print *p +next +print *p +next +cont +next +print *t +next +print *t +print *s +next +quit +break do_presentResponse +run -c 2002 +next +print *r +print *r->presentStatus +print *r->numberOfRecordsReturned +quit diff --git a/.pazpar2.c.swp b/.pazpar2.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..64715bb00dffadea1984aab794baf22df47e5c26 GIT binary patch literal 28725 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 literal 0 HcmV?d00001 diff --git a/.pazpar2.h.swp b/.pazpar2.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..44d32aa485427b4a63cffb8789f818e641b9a237 GIT binary patch literal 12288 zcmeI2KW`*87>9jVP!MuKcS6veAQ4(`oRIJy~58fcIxprJ!FNbvK_Y-U3uuDIq-dPjP8c3*p5zkY0O zG4f#P)fcw-N~gzgJ;>OX=XW+Ax$h!7`w(M$V{J@~-{$gaAbilmw1;9eQqH#vd!XFF z+M8EbJGo6oUS@c^OxP`)eWP25!$P>;^xhfXW(;a317zUN4J=*hJ;@(^Z1MbsSMEF+ zWgr7&fDDiUGC&5%02v?yWZ<4MPy}{{{Zp2F7N1XpGc{$9KF9zWAOmE843GgbKnBPF z86X2>fDDjb{jz$f5i@DaeX^Y4H?a06h> z`8BW#o?`5QKf#aSLm)wnt$;4*fXBhZ0Pi;Deh0sRud2DueU3Zoql*lX0Wv@a$N(82 z17v^<+?57+tIK$crtQkq0YjAmSMQQ%!3&CV2kxtu5J~=Nc@gZY#P~*cWtCH zp&fg*M^>snH#(0EX&VQ4b=tOB=2htPw!l_TE*7#5lni)JaO*bvcsDq@g?^4q|)WHuXRbJkj{dHQ2v5;13$0kiE_@m zCRq$+Lgz{zk7=3D)D?RbPI+tsZFZ0Mtk&{GSR0Ll-MKzI(E{g2r6&^^n@pRmIX*@c z$IPco)U0?j%et-dh?P-T{xl!^pz1mQr-MHu|CBM~t=`%wWKkQ)k%~Vv5r^HP9K17p77bEm+9 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "command.h" +#include "util.h" +#include "eventl.h" +#include "pazpar2.h" + +extern IOCHAN channel_list; + +struct command_session { + IOCHAN channel; + char *outbuf; + + int outbuflen; + int outbufwrit; + + struct session *psession; +}; + +void command_destroy(struct command_session *s); +void command_prompt(struct command_session *s); +void command_puts(struct command_session *s, const char *buf); + +static int cmd_quit(struct command_session *s, char **argv, int argc) +{ + IOCHAN i = s->channel; + close(iochan_getfd(i)); + iochan_destroy(i); + command_destroy(s); + return 0; +} + +static int cmd_load(struct command_session *s, char **argv, int argc) +{ + if (argc != 2) { + command_puts(s, "Usage: load filename\n"); + } + if (load_targets(s->psession, argv[1]) < 0) + command_puts(s, "Failed to open file\n"); + return 1; +} + +static int cmd_search(struct command_session *s, char **argv, int argc) +{ + if (argc != 2) + { + command_puts(s, "Usage: search word\n"); + return 1; + } + search(s->psession, argv[1]); + return 1; +} + +static int cmd_hitsbytarget(struct command_session *s, char **argv, int argc) +{ + int count; + int i; + + struct hitsbytarget *ht = hitsbytarget(s->psession, &count); + for (i = 0; i < count; i++) + { + char buf[1024]; + + sprintf(buf, "%s: %d (%d records, diag=%d, state=%s)\n", ht[i].id, ht[i].hits, + ht[i].records, ht[i].diagnostic, ht[i].state); + command_puts(s, buf); + } + return 1; +} + +static int cmd_stat(struct command_session *s, char **argv, int argc) +{ + char buf[1024]; + struct statistics stat; + + statistics(s->psession, &stat); + sprintf(buf, "Number of connections: %d\n", stat.num_connections); + command_puts(s, buf); + if (stat.num_no_connection) + { + sprintf(buf, "#No_connection: %d\n", stat.num_no_connection); + command_puts(s, buf); + } + if (stat.num_connecting) + { + sprintf(buf, "#Connecting: %d\n", stat.num_connecting); + command_puts(s, buf); + } + if (stat.num_initializing) + { + sprintf(buf, "#Initializing: %d\n", stat.num_initializing); + command_puts(s, buf); + } + if (stat.num_searching) + { + sprintf(buf, "#Searching: %d\n", stat.num_searching); + command_puts(s, buf); + } + if (stat.num_presenting) + { + sprintf(buf, "#Ppresenting: %d\n", stat.num_presenting); + command_puts(s, buf); + } + if (stat.num_idle) + { + sprintf(buf, "#Idle: %d\n", stat.num_idle); + command_puts(s, buf); + } + if (stat.num_failed) + { + sprintf(buf, "#Failed: %d\n", stat.num_failed); + command_puts(s, buf); + } + if (stat.num_error) + { + sprintf(buf, "#Error: %d\n", stat.num_error); + command_puts(s, buf); + } + return 1; +} + +static struct { + char *cmd; + int (*fun)(struct command_session *s, char *argv[], int argc); +} cmd_array[] = { + {"quit", cmd_quit}, + {"load", cmd_load}, + {"search", cmd_search}, + {"ht", cmd_hitsbytarget}, + {"stat", cmd_stat}, + {0,0} +}; + +void command_command(struct command_session *s, char *command) +{ + char *p; + char *argv[20]; + int argc = 0; + int i; + int res = -1; + + p = command; + while (*p) + { + while (isspace(*p)) + p++; + if (!*p) + break; + argv[argc++] = p; + while (*p && !isspace(*p)) + p++; + if (!*p) + break; + *(p++) = '\0'; + } + if (argc) { + for (i = 0; cmd_array[i].cmd; i++) + { + if (!strcmp(cmd_array[i].cmd, argv[0])) { + res = (cmd_array[i].fun)(s, argv, argc); + + break; + } + } + if (res < 0) { + command_puts(s, "Unknown command.\n"); + command_prompt(s); + } + else if (res == 1) { + command_prompt(s); + } + } + else + command_prompt(s); + +} + + +static void command_io(IOCHAN i, int event) +{ + int res; + char buf[1024]; + struct command_session *s; + + s = iochan_getdata(i); + + + switch (event) + { + case EVENT_INPUT: + res = read(iochan_getfd(i), buf, 1024); + if (res <= 0) + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "read command"); + close(iochan_getfd(i)); + iochan_destroy(i); + command_destroy(s); + return; + } + if (!index(buf, '\n')) { + yaz_log(YLOG_WARN|YLOG_ERRNO, "Did not receive complete command"); + close(iochan_getfd(i)); + iochan_destroy(i); + command_destroy(s); + return; + } + buf[res] = '\0'; + command_command(s, buf); + break; + case EVENT_OUTPUT: + if (!s->outbuflen || s->outbufwrit < 0) + { + yaz_log(YLOG_WARN, "Called with outevent but no data"); + iochan_clearflag(i, EVENT_OUTPUT); + } + else + { + res = write(iochan_getfd(i), s->outbuf + s->outbufwrit, s->outbuflen - + s->outbufwrit); + if (res < 0) { + yaz_log(YLOG_WARN|YLOG_ERRNO, "write command"); + close(iochan_getfd(i)); + iochan_destroy(i); + command_destroy(s); + } + else + { + s->outbufwrit += res; + if (s->outbufwrit >= s->outbuflen) + { + s->outbuflen = s->outbufwrit = 0; + iochan_clearflag(i, EVENT_OUTPUT); + } + } + } + break; + default: + yaz_log(YLOG_WARN, "Bad voodoo on socket"); + } +} + +void command_puts(struct command_session *s, const char *buf) +{ + int len = strlen(buf); + memcpy(s->outbuf + s->outbuflen, buf, len); + s->outbuflen += len; + iochan_setflag(s->channel, EVENT_OUTPUT); +} + +void command_prompt(struct command_session *s) +{ + command_puts(s, "Pazpar2> "); +} + + +/* Accept a new command connection */ +static void command_accept(IOCHAN i, int event) +{ + struct sockaddr_in addr; + int fd = iochan_getfd(i); + socklen_t len; + int s; + IOCHAN c; + struct command_session *ses; + int flags; + + len = sizeof addr; + if ((s = accept(fd, (struct sockaddr *) &addr, &len)) < 0) + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "accept"); + return; + } + if ((flags = fcntl(s, F_GETFL, 0)) < 0) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "fcntl"); + if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "fcntl2"); + + yaz_log(YLOG_LOG, "New command connection"); + c = iochan_create(s, command_io, EVENT_INPUT | EVENT_EXCEPT); + + ses = xmalloc(sizeof(*ses)); + ses->outbuf = xmalloc(50000); + ses->outbuflen = 0; + ses->outbufwrit = 0; + ses->channel = c; + ses->psession = new_session(); + iochan_setdata(c, ses); + + command_puts(ses, "Welcome to pazpar2\n\n"); + command_prompt(ses); + + c->next = channel_list; + channel_list = c; +} + +void command_destroy(struct command_session *s) { + xfree(s->outbuf); + xfree(s); +} + +/* Create a command-channel listener */ +void command_init(int port) +{ + IOCHAN c; + int l; + struct protoent *p; + struct sockaddr_in myaddr; + + yaz_log(YLOG_LOG, "Command port is %d", port); + if (!(p = getprotobyname("tcp"))) { + abort(); + } + if ((l = socket(PF_INET, SOCK_STREAM, p->p_proto)) < 0) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "socket"); + bzero(&myaddr, sizeof myaddr); + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = INADDR_ANY; + myaddr.sin_port = port; + if (bind(l, (struct sockaddr *) &myaddr, sizeof myaddr) < 0) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "bind"); + if (listen(l, 5) < 0) + yaz_log(YLOG_FATAL|YLOG_ERRNO, "listen"); + + c = iochan_create(l, command_accept, EVENT_INPUT | EVENT_EXCEPT); + //iochan_setdata(c, &l); + c->next = channel_list; + channel_list = c; +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/command.h b/command.h new file mode 100644 index 0000000..25e5b99 --- /dev/null +++ b/command.h @@ -0,0 +1,6 @@ +#ifndef COMMAND_H +#define COMMAND_H + +void command_init(int port); + +#endif diff --git a/danish.pz b/danish.pz new file mode 100644 index 0000000..ba1cc52 --- /dev/null +++ b/danish.pz @@ -0,0 +1,21 @@ +target cosmos.dnlb.dk:9909/DNL01 +target odin.dtv.dk:210/DTV01 +target dvjb1.kvl.dk:9909/dvj01 +target hermes.lib.cbs.dk:2100/S +target a800.hha.dk:9909/hba01 +target z3950.kb.dk:2100/kgl01 +target hans.ruc.dk:2210/S +target a500.aub.auc.dk:9909/AUB01 +target z3950.dbc.dk:213/def1forsk +target z3950.dbc.dk:213/def1total +target z3950.dbc.dk:213/danbibv2 +target hcb.bibnet.dk:2100/S +target z3950.bibsys.no:2100/BIBSYS +target z3950.libris.kb.se:210/libr +target bagel.indexdata.dk/gils +target www.deff.dk:2100/Default +target www.deff.dk:2102/Default +connect +init +search @attr 1=4 danmarks +present diff --git a/def.pz b/def.pz new file mode 100644 index 0000000..1351fde --- /dev/null +++ b/def.pz @@ -0,0 +1,17 @@ +target cosmos.dnlb.dk:9909/DNL01 +target odin.dtv.dk:210/DTV01 +target dvjb1.kvl.dk:9909/dvj01 +target hermes.lib.cbs.dk:2100/S +target a800.hha.dk:9909/hba01 +target z3950.kb.dk:2100/kgl01 +target hans.ruc.dk:2210/S +target a500.aub.auc.dk:9909/AUB01 +target z3950.dbc.dk:213/def1forsk +target z3950.dbc.dk:213/def1total +target z3950.dbc.dk:213/danbibv2 +target bagel/gils +connect +wait reset +init +wait reset +search @attr 1=4 @attr 2=3 @attr 3=3 @attr 4=1 @attr 5=100 @attr 6=2 "pigen med" diff --git a/defport.pz b/defport.pz new file mode 100644 index 0000000..de0df23 --- /dev/null +++ b/defport.pz @@ -0,0 +1,5 @@ +target www.deff.dk:2102/Default +connect +init +search @attr 1=4 danmarks +present diff --git a/eventl.c b/eventl.c new file mode 100644 index 0000000..fc188a3 --- /dev/null +++ b/eventl.c @@ -0,0 +1,142 @@ +/* + * ParaZ - a simple tool for harvesting performance data for parallel + * operations using Z39.50. + * Copyright (c) 2000-2004 Index Data ApS + * See LICENSE file for details. + */ + +/* + * $Id: eventl.c,v 1.1 2006-11-14 20:44:37 quinn Exp $ + * Based on revision YAZ' server/eventl.c 1.29. + */ + +#include +#include +#ifdef WIN32 +#include +#else +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include "eventl.h" +#include + +IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags) +{ + IOCHAN new_iochan; + + if (!(new_iochan = (IOCHAN)xmalloc(sizeof(*new_iochan)))) + return 0; + 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; + new_iochan->next = NULL; + return new_iochan; +} + +int event_loop(IOCHAN *iochans) +{ + 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 = 30; + 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; + else + abort(); + } + 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); + } + } + for (p = *iochans; p; p = nextp) + { + nextp = p->next; + + if (p->destroyed) + { + IOCHAN tmp = p, pr; + + /* 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; +} diff --git a/eventl.h b/eventl.h new file mode 100644 index 0000000..b275852 --- /dev/null +++ b/eventl.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1995-1999, Index Data + * See the file LICENSE for details. + * Sebastian Hammer, Adam Dickmeiss + * + * $Log: eventl.h,v $ + * Revision 1.1 2006-11-14 20:44:38 quinn + * Initial revision + * + * Revision 1.1.1.1 2000/02/23 14:40:18 heikki + * Original import to cvs + * + * Revision 1.11 1999/04/20 09:56:48 adam + * Added 'name' paramter to encoder/decoder routines (typedef Odr_fun). + * Modified all encoders/decoders to reflect this change. + * + * Revision 1.10 1998/01/29 13:30:23 adam + * Better event handle system for NT/Unix. + * + * Revision 1.9 1997/09/01 09:31:48 adam + * Removed definition statserv_remove from statserv.h to eventl.h. + * + * Revision 1.8 1995/06/19 12:39:09 quinn + * Fixed bug in timeout code. Added BER dumper. + * + * Revision 1.7 1995/06/16 10:31:34 quinn + * Added session timeout. + * + * Revision 1.6 1995/05/16 08:51:02 quinn + * License, documentation, and memory fixes + * + * Revision 1.5 1995/05/15 11:56:37 quinn + * Asynchronous facilities. Restructuring of seshigh code. + * + * Revision 1.4 1995/03/27 08:34:23 quinn + * Added dynamic server functionality. + * Released bindings to session.c (is now redundant) + * + * Revision 1.3 1995/03/15 08:37:42 quinn + * Now we're pretty much set for nonblocking I/O. + * + * Revision 1.2 1995/03/14 10:28:00 quinn + * More work on demo server. + * + * Revision 1.1 1995/03/10 18:22:45 quinn + * The rudiments of an asynchronous server. + * + */ + +#ifndef EVENTL_H +#define EVENTL_H + +#include + +struct iochan; + +typedef void (*IOC_CALLBACK)(struct iochan *i, int event); + +typedef struct iochan +{ + int fd; + int flags; +#define EVENT_INPUT 0x01 +#define EVENT_OUTPUT 0x02 +#define EVENT_EXCEPT 0x04 +#define EVENT_TIMEOUT 0x08 +#define EVENT_WORK 0x10 +int force_event; + IOC_CALLBACK fun; + void *data; + int destroyed; + time_t last_event; + time_t max_idle; + + struct iochan *next; +} *IOCHAN; + +#define iochan_destroy(i) (void)((i)->destroyed = 1) +#define iochan_getfd(i) ((i)->fd) +#define iochan_setfd(i, f) ((i)->fd = (f)) +#define iochan_getdata(i) ((i)->data) +#define iochan_setdata(i, d) ((i)->data = d) +#define iochan_getflags(i) ((i)->flags) +#define iochan_setflags(i, d) ((i)->flags = d) +#define iochan_setflag(i, d) ((i)->flags |= d) +#define iochan_clearflag(i, d) ((i)->flags &= ~(d)) +#define iochan_getflag(i, d) ((i)->flags & d ? 1 : 0) +#define iochan_getfun(i) ((i)->fun) +#define iochan_setfun(i, d) ((i)->fun = d) +#define iochan_setevent(i, e) ((i)->force_event = (e)) +#define iochan_getnext(i) ((i)->next) +#define iochan_settimeout(i, t) ((i)->max_idle = (t), (i)->last_event = time(0)) + +IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags); +int event_loop(IOCHAN *iochans); +#endif diff --git a/h1.pz b/h1.pz new file mode 100644 index 0000000..2e2f0fa --- /dev/null +++ b/h1.pz @@ -0,0 +1,9 @@ +target bagel.indexdata.dk/gils +#target bagel.indexdata.dk:2100/Default +#target unknown.indexdata.dk +target localhost:9999/Default +connect +wait reset +init +search @attr 1=4 utah +present 2 diff --git a/local.pz b/local.pz new file mode 100644 index 0000000..4056d53 --- /dev/null +++ b/local.pz @@ -0,0 +1,10 @@ +target bagel.indexdata.dk/gils +connect +init +search @attr 1=4 utah +present 1 +wait +present 2 +wait +present +wait \ No newline at end of file diff --git a/multi.pz b/multi.pz new file mode 100644 index 0000000..436f34f --- /dev/null +++ b/multi.pz @@ -0,0 +1,9 @@ +target bagel.indexdata.dk/gils +target bagel.indexdata.dk/Marc +target muffin.indexdata.dk:8888/Default +target muffin.indexdata.dk:9002/E97 +target ximum.indexdata.dk:9999/resolutions +connect +init +search @attr 1=4 utah +present diff --git a/multi.txt b/multi.txt new file mode 100644 index 0000000..55eb1b0 --- /dev/null +++ b/multi.txt @@ -0,0 +1,220 @@ + 950876489,CONNECTED , 0.001341, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876489,CONNECTED , 0.001592, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876489,CONNECTED , 0.001684, bagel.indexdata.dk/Marc, , 0, 0 + 950876489,CONNECTED , 0.001911, bagel.indexdata.dk/gils, , 0, 0 + 950876489,CONNECTED , 0.002035, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876489,INIT , 0.009192, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876489,INIT , 0.024619, bagel.indexdata.dk/Marc, , 0, 0 + 950876489,INIT , 0.026139, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876489,INIT , 0.046127, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876489,FAILED , 0.046881, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876489,FINISHED , 0.047016, bagel.indexdata.dk/Marc, , 0, 0 + 950876489,FAILED , 0.060261, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876489,FINISHED , 0.060485, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876489,INIT , 0.064298, bagel.indexdata.dk/gils, , 0, 0 + 950876489,SEARCH , 0.083986, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876489,FINISHED , 0.084146, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876489,FAILED , 0.088662, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876489,FINISHED , 0.088829, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876489,SEARCH , 0.090702, bagel.indexdata.dk/gils, , 9, 0 + 950876489,PRESENT , 0.126084, bagel.indexdata.dk/gils, failed, 0, 0 + 950876489,FINISHED , 0.126188, bagel.indexdata.dk/gils, , 0, 0 + 950876489,COMPLETE , 0.126206, (all), , 0, 0 + 950876492,CONNECTED , 0.000596, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876492,CONNECTED , 0.000838, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876492,CONNECTED , 0.000930, bagel.indexdata.dk/Marc, , 0, 0 + 950876492,CONNECTED , 0.001110, bagel.indexdata.dk/gils, , 0, 0 + 950876492,CONNECTED , 0.001257, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876492,INIT , 0.008360, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876492,INIT , 0.018452, bagel.indexdata.dk/Marc, , 0, 0 + 950876492,INIT , 0.024710, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876492,FAILED , 0.040495, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876492,FINISHED , 0.040674, bagel.indexdata.dk/Marc, , 0, 0 + 950876492,INIT , 0.048323, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876492,INIT , 0.058978, bagel.indexdata.dk/gils, , 0, 0 + 950876492,FAILED , 0.060665, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876492,FINISHED , 0.060778, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876492,SEARCH , 0.085355, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876492,FINISHED , 0.085575, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876492,SEARCH , 0.085628, bagel.indexdata.dk/gils, , 9, 0 + 950876492,FAILED , 0.087761, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876492,FINISHED , 0.087854, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876492,PRESENT , 0.120268, bagel.indexdata.dk/gils, failed, 0, 0 + 950876492,FINISHED , 0.120381, bagel.indexdata.dk/gils, , 0, 0 + 950876492,COMPLETE , 0.120399, (all), , 0, 0 + 950876494,CONNECTED , 0.000545, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876494,CONNECTED , 0.000790, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876494,CONNECTED , 0.000881, bagel.indexdata.dk/Marc, , 0, 0 + 950876494,CONNECTED , 0.001021, bagel.indexdata.dk/gils, , 0, 0 + 950876494,CONNECTED , 0.001220, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876494,INIT , 0.008265, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876494,INIT , 0.019415, bagel.indexdata.dk/Marc, , 0, 0 + 950876494,INIT , 0.023800, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876494,FAILED , 0.041508, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876494,FINISHED , 0.041694, bagel.indexdata.dk/Marc, , 0, 0 + 950876494,INIT , 0.046970, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876494,FAILED , 0.050530, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876494,FINISHED , 0.050647, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876494,INIT , 0.058910, bagel.indexdata.dk/gils, , 0, 0 + 950876494,SEARCH , 0.070817, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876494,FINISHED , 0.070987, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876494,SEARCH , 0.085523, bagel.indexdata.dk/gils, , 9, 0 + 950876494,FAILED , 0.086797, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876494,FINISHED , 0.086904, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876494,PRESENT , 0.121230, bagel.indexdata.dk/gils, failed, 0, 0 + 950876494,FINISHED , 0.121337, bagel.indexdata.dk/gils, , 0, 0 + 950876494,COMPLETE , 0.121355, (all), , 0, 0 + 950876496,CONNECTED , 0.000778, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876496,CONNECTED , 0.001021, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876496,CONNECTED , 0.001168, bagel.indexdata.dk/Marc, , 0, 0 + 950876496,CONNECTED , 0.001307, bagel.indexdata.dk/gils, , 0, 0 + 950876496,CONNECTED , 0.001470, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876496,INIT , 0.008356, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876496,INIT , 0.018489, bagel.indexdata.dk/Marc, , 0, 0 + 950876496,INIT , 0.025407, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876496,FAILED , 0.040572, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876496,FINISHED , 0.040706, bagel.indexdata.dk/Marc, , 0, 0 + 950876496,INIT , 0.045839, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876496,INIT , 0.057905, bagel.indexdata.dk/gils, , 0, 0 + 950876496,FAILED , 0.058305, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876496,FINISHED , 0.058395, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876496,SEARCH , 0.082661, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876496,FINISHED , 0.082791, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876496,SEARCH , 0.085132, bagel.indexdata.dk/gils, , 9, 0 + 950876496,FAILED , 0.088815, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876496,FINISHED , 0.088918, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876496,PRESENT , 0.119781, bagel.indexdata.dk/gils, failed, 0, 0 + 950876496,FINISHED , 0.119867, bagel.indexdata.dk/gils, , 0, 0 + 950876496,COMPLETE , 0.119884, (all), , 0, 0 + 950876498,CONNECTED , 0.000566, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876498,CONNECTED , 0.000812, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876498,CONNECTED , 0.000903, bagel.indexdata.dk/Marc, , 0, 0 + 950876498,CONNECTED , 0.001005, bagel.indexdata.dk/gils, , 0, 0 + 950876498,CONNECTED , 0.001236, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876498,INIT , 0.008423, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876498,INIT , 0.018266, bagel.indexdata.dk/Marc, , 0, 0 + 950876498,INIT , 0.025240, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876498,FAILED , 0.041354, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876498,FINISHED , 0.041536, bagel.indexdata.dk/Marc, , 0, 0 + 950876498,INIT , 0.047206, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876498,FAILED , 0.052106, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876498,FINISHED , 0.052232, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876498,INIT , 0.058767, bagel.indexdata.dk/gils, , 0, 0 + 950876498,SEARCH , 0.076203, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876498,FINISHED , 0.076352, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876498,SEARCH , 0.085108, bagel.indexdata.dk/gils, , 9, 0 + 950876498,FAILED , 0.085488, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876498,FINISHED , 0.085584, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876498,PRESENT , 0.134660, bagel.indexdata.dk/gils, failed, 0, 0 + 950876498,FINISHED , 0.134770, bagel.indexdata.dk/gils, , 0, 0 + 950876498,COMPLETE , 0.134788, (all), , 0, 0 + 950876500,CONNECTED , 0.001486, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876500,CONNECTED , 0.001957, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876500,CONNECTED , 0.002047, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876500,CONNECTED , 0.002151, bagel.indexdata.dk/Marc, , 0, 0 + 950876500,CONNECTED , 0.002239, bagel.indexdata.dk/gils, , 0, 0 + 950876500,INIT , 0.008435, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876500,INIT , 0.019691, bagel.indexdata.dk/Marc, , 0, 0 + 950876500,INIT , 0.026277, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876500,FAILED , 0.041745, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876500,FINISHED , 0.041963, bagel.indexdata.dk/Marc, , 0, 0 + 950876500,INIT , 0.045740, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876500,FAILED , 0.057801, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876500,FINISHED , 0.057956, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876500,INIT , 0.059066, bagel.indexdata.dk/gils, , 0, 0 + 950876500,SEARCH , 0.082227, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876500,FINISHED , 0.082353, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876500,SEARCH , 0.086360, bagel.indexdata.dk/gils, , 9, 0 + 950876500,FAILED , 0.087483, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876500,FINISHED , 0.087572, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876500,PRESENT , 0.140876, bagel.indexdata.dk/gils, failed, 0, 0 + 950876500,FINISHED , 0.140986, bagel.indexdata.dk/gils, , 0, 0 + 950876500,COMPLETE , 0.141004, (all), , 0, 0 + 950876502,CONNECTED , 0.000538, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876502,CONNECTED , 0.000788, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876502,CONNECTED , 0.000878, bagel.indexdata.dk/Marc, , 0, 0 + 950876502,CONNECTED , 0.001104, bagel.indexdata.dk/gils, , 0, 0 + 950876502,CONNECTED , 0.001210, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876502,INIT , 0.008454, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876502,INIT , 0.018353, bagel.indexdata.dk/Marc, , 0, 0 + 950876502,INIT , 0.024693, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876502,FAILED , 0.040460, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876502,FINISHED , 0.040658, bagel.indexdata.dk/Marc, , 0, 0 + 950876502,INIT , 0.045000, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876502,FAILED , 0.060012, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876502,FINISHED , 0.060171, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876502,INIT , 0.069047, bagel.indexdata.dk/gils, , 0, 0 + 950876502,SEARCH , 0.083532, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876502,FINISHED , 0.083687, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876502,FAILED , 0.087489, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876502,FINISHED , 0.087666, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876502,SEARCH , 0.095443, bagel.indexdata.dk/gils, , 9, 0 + 950876502,PRESENT , 0.131127, bagel.indexdata.dk/gils, failed, 0, 0 + 950876502,FINISHED , 0.131228, bagel.indexdata.dk/gils, , 0, 0 + 950876502,COMPLETE , 0.131246, (all), , 0, 0 + 950876505,CONNECTED , 0.000569, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876505,CONNECTED , 0.000819, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876505,CONNECTED , 0.000908, bagel.indexdata.dk/Marc, , 0, 0 + 950876505,CONNECTED , 0.001122, bagel.indexdata.dk/gils, , 0, 0 + 950876505,CONNECTED , 0.001227, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876505,INIT , 0.008352, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876505,INIT , 0.024935, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876505,INIT , 0.033138, bagel.indexdata.dk/Marc, , 0, 0 + 950876505,INIT , 0.042941, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876505,FAILED , 0.056214, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876505,FINISHED , 0.056397, bagel.indexdata.dk/Marc, , 0, 0 + 950876505,FAILED , 0.057998, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876505,FINISHED , 0.058145, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876505,INIT , 0.073656, bagel.indexdata.dk/gils, , 0, 0 + 950876505,SEARCH , 0.082495, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876505,FINISHED , 0.082632, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876505,FAILED , 0.088327, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876505,FINISHED , 0.088488, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876505,SEARCH , 0.100023, bagel.indexdata.dk/gils, , 9, 0 + 950876505,PRESENT , 0.135071, bagel.indexdata.dk/gils, failed, 0, 0 + 950876505,FINISHED , 0.135178, bagel.indexdata.dk/gils, , 0, 0 + 950876505,COMPLETE , 0.135196, (all), , 0, 0 + 950876507,CONNECTED , 0.000567, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876507,CONNECTED , 0.000813, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876507,CONNECTED , 0.000902, bagel.indexdata.dk/Marc, , 0, 0 + 950876507,CONNECTED , 0.001112, bagel.indexdata.dk/gils, , 0, 0 + 950876507,CONNECTED , 0.001218, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876507,INIT , 0.008370, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876507,INIT , 0.016265, bagel.indexdata.dk/Marc, , 0, 0 + 950876507,INIT , 0.026364, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876507,FAILED , 0.038337, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876507,FINISHED , 0.038532, bagel.indexdata.dk/Marc, , 0, 0 + 950876507,INIT , 0.045492, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876507,INIT , 0.055726, bagel.indexdata.dk/gils, , 0, 0 + 950876507,FAILED , 0.059609, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876507,FINISHED , 0.059735, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876507,SEARCH , 0.082128, bagel.indexdata.dk/gils, , 9, 0 + 950876507,SEARCH , 0.083731, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876507,FINISHED , 0.083835, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876507,FAILED , 0.104254, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876507,FINISHED , 0.104440, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876507,PRESENT , 0.118206, bagel.indexdata.dk/gils, failed, 0, 0 + 950876507,FINISHED , 0.118315, bagel.indexdata.dk/gils, , 0, 0 + 950876507,COMPLETE , 0.118333, (all), , 0, 0 + 950876509,CONNECTED , 0.003709, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876509,CONNECTED , 0.004189, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876509,CONNECTED , 0.004281, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876509,CONNECTED , 0.004387, bagel.indexdata.dk/Marc, , 0, 0 + 950876509,CONNECTED , 0.004512, bagel.indexdata.dk/gils, , 0, 0 + 950876509,INIT , 0.008799, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876509,INIT , 0.028480, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876509,INIT , 0.032066, bagel.indexdata.dk/Marc, , 0, 0 + 950876509,INIT , 0.045047, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876509,FAILED , 0.055137, bagel.indexdata.dk/Marc, search error, 0, 0 + 950876509,FINISHED , 0.055310, bagel.indexdata.dk/Marc, , 0, 0 + 950876509,FAILED , 0.056695, muffin.indexdata.dk:9002/E97, search error, 0, 0 + 950876509,FINISHED , 0.056838, muffin.indexdata.dk:9002/E97, , 0, 0 + 950876509,INIT , 0.072675, bagel.indexdata.dk/gils, , 0, 0 + 950876509,SEARCH , 0.081390, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876509,FINISHED , 0.081532, muffin.indexdata.dk:8888/Default, , 0, 0 + 950876509,FAILED , 0.087422, ximum.indexdata.dk:9999/resolutions, search error, 0, 0 + 950876509,FINISHED , 0.087590, ximum.indexdata.dk:9999/resolutions, , 0, 0 + 950876509,SEARCH , 0.099116, bagel.indexdata.dk/gils, , 9, 0 + 950876509,PRESENT , 0.134118, bagel.indexdata.dk/gils, failed, 0, 0 + 950876509,FINISHED , 0.134221, bagel.indexdata.dk/gils, , 0, 0 + 950876509,COMPLETE , 0.134239, (all), , 0, 0 diff --git a/pazpar2.c b/pazpar2.c new file mode 100644 index 0000000..b003664 --- /dev/null +++ b/pazpar2.c @@ -0,0 +1,643 @@ +/* $Id: pazpar2.c,v 1.1 2006-11-14 20:44:38 quinn Exp $ */ + + +#define PAZPAR2_VERSION "0.1" +#define MAX_DATABASES 512 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pazpar2.h" +#include "eventl.h" +#include "command.h" + +char *myname; +static long int runId=-1; + +struct target +{ + struct session *session; + char fullname[256]; + char hostport[128]; + char *ibuf; + int ibufsize; + char databases[MAX_DATABASES][128]; + COMSTACK link; + ODR odr_in, odr_out; + struct target *next; + void *addr; + int hits; + int records; + int setno; + int requestid; // ID of current outstanding request + int diagnostic; + enum target_state + { + No_connection, + Connecting, + Connected, + Initializing, + Searching, + Presenting, + Error, + Idle, + Failed + } state; +}; + +static char *state_strings[] = { + "No_connection", + "Connecting", + "Connected", + "Initializing", + "Searching", + "Presenting", + "Error", + "Idle", + "Failed" +}; + + +IOCHAN channel_list = 0; + +static struct parameters { + int timeout; /* operations timeout, in seconds */ + char implementationId[128]; + char implementationName[128]; + char implementationVersion[128]; + struct timeval base_time; + int toget; + int chunk; +} global_parameters = +{ + 30, + "81", + "Index Data PazPar2 (MasterKey)", + PAZPAR2_VERSION, + {0,0}, + 100, + 10 +}; + + +static int send_apdu(struct target *t, Z_APDU *a) +{ + char *buf; + int len, r; + + if (!z_APDU(t->odr_out, &a, 0, 0)) + { + odr_perror(t->odr_out, "Encoding APDU"); + abort(); + } + buf = odr_getbuf(t->odr_out, &len, 0); + r = cs_put(t->link, buf, len); + if (r < 0) + { + yaz_log(YLOG_WARN, "cs_put: %s", cs_errmsg(cs_errno(t->link))); + return -1; + } + else if (r == 1) + { + fprintf(stderr, "cs_put incomplete (ParaZ does not handle that)\n"); + } + odr_reset(t->odr_out); /* release the APDU structure */ + return 0; +} + + +static void send_init(IOCHAN i) +{ + struct target *t = iochan_getdata(i); + Z_APDU *a = zget_APDU(t->odr_out, Z_APDU_initRequest); + + a->u.initRequest->implementationId = global_parameters.implementationId; + a->u.initRequest->implementationName = global_parameters.implementationName; + a->u.initRequest->implementationVersion = + global_parameters.implementationVersion; + ODR_MASK_SET(a->u.initRequest->options, Z_Options_search); + ODR_MASK_SET(a->u.initRequest->options, Z_Options_present); + ODR_MASK_SET(a->u.initRequest->options, Z_Options_namedResultSets); + + ODR_MASK_SET(a->u.initRequest->protocolVersion, Z_ProtocolVersion_1); + ODR_MASK_SET(a->u.initRequest->protocolVersion, Z_ProtocolVersion_2); + ODR_MASK_SET(a->u.initRequest->protocolVersion, Z_ProtocolVersion_3); + if (send_apdu(t, a) >= 0) + { + iochan_setflags(i, EVENT_INPUT); + t->state = Initializing; + } + else + { + iochan_destroy(i); + t->state = Failed; + cs_close(t->link); + } +} + +static void send_search(IOCHAN i) +{ + struct target *t = iochan_getdata(i); + struct session *s = t->session; + Z_APDU *a = zget_APDU(t->odr_out, Z_APDU_searchRequest); + int ndb; + char **databaselist; + Z_Query *zquery; + + yaz_log(YLOG_DEBUG, "Sending search"); + a->u.searchRequest->query = zquery = odr_malloc(t->odr_out, sizeof(Z_Query)); + zquery->which = Z_Query_type_1; + zquery->u.type_1 = p_query_rpn(t->odr_out, PROTO_Z3950, s->query); + + for (ndb = 0; *t->databases[ndb]; ndb++) + ; + databaselist = odr_malloc(t->odr_out, sizeof(char*) * ndb); + for (ndb = 0; *t->databases[ndb]; ndb++) + databaselist[ndb] = t->databases[ndb]; + + a->u.searchRequest->resultSetName = "Default"; + a->u.searchRequest->databaseNames = databaselist; + a->u.searchRequest->num_databaseNames = ndb; + + if (send_apdu(t, a) >= 0) + { + iochan_setflags(i, EVENT_INPUT); + t->state = Searching; + t->requestid = s->requestid; + } + else + { + iochan_destroy(i); + t->state = Failed; + cs_close(t->link); + } + odr_reset(t->odr_out); +} + +static void send_present(IOCHAN i) +{ + struct target *t = iochan_getdata(i); + Z_APDU *a = zget_APDU(t->odr_out, Z_APDU_presentRequest); + int toget; + + toget = global_parameters.chunk; + if (toget > t->hits - t->records) + toget = t->hits - t->records; + + yaz_log(YLOG_DEBUG, "Trying to present %d records\n", toget); + + a->u.presentRequest->numberOfRecordsRequested = &toget; + + a->u.presentRequest->resultSetId = "Default"; + + if (send_apdu(t, a) >= 0) + { + iochan_setflags(i, EVENT_INPUT); + t->state = Presenting; + } + else + { + iochan_destroy(i); + t->state = Failed; + cs_close(t->link); + } + odr_reset(t->odr_out); +} + +static void do_initResponse(IOCHAN i, Z_APDU *a) +{ + struct target *t = iochan_getdata(i); + Z_InitResponse *r = a->u.initResponse; + + yaz_log(YLOG_DEBUG, "Received init response"); + + if (*r->result) + { + t->state = Idle; + } + else + { + t->state = Failed; + iochan_destroy(i); + cs_close(t->link); + } +} + +#if 0 +static char *search_geterror(Z_SearchRequest *r) +{ +#endif + + +static void do_searchResponse(IOCHAN i, Z_APDU *a) +{ + struct target *t = iochan_getdata(i); + Z_SearchResponse *r = a->u.searchResponse; + + yaz_log(YLOG_DEBUG, "Searchresponse (status=%d)", *r->searchStatus); + + if (*r->searchStatus) + { + t->hits = *r->resultCount; + t->state = Idle; + } + else + { /*"FAILED"*/ + t->hits = 0; + t->state = Failed; + if (r->records) { + Z_Records *recs = r->records; + if (recs->which == Z_Records_NSD) + { + yaz_log(YLOG_WARN, "Non-surrogate diagnostic"); + t->diagnostic = *recs->u.nonSurrogateDiagnostic->condition; + t->state = Error; + } + } + } +} + +// FIXME Catch present errors!!!!!!! +static void do_presentResponse(IOCHAN i, Z_APDU *a) +{ + struct target *t = iochan_getdata(i); + Z_PresentResponse *r = a->u.presentResponse; + + if (r->records) { + Z_Records *recs = r->records; + if (recs->which == Z_Records_NSD) + { + yaz_log(YLOG_WARN, "Non-surrogate diagnostic"); + t->diagnostic = *recs->u.nonSurrogateDiagnostic->condition; + t->state = Error; + } + else + { + yaz_log(YLOG_DEBUG, "Got Records!"); + } + } + + if (!*r->presentStatus && t->state != Error) + { + yaz_log(YLOG_DEBUG, "Good Present response"); + t->records += *r->numberOfRecordsReturned; + t->state = Idle; + } + else if (*r->presentStatus) + { + yaz_log(YLOG_WARN, "Bad Present response"); + t->state = Error; + } +} + +static void handler(IOCHAN i, int event) +{ + struct target *t = iochan_getdata(i); + struct session *s = t->session; + //static int waiting = 0; + + if (t->state == No_connection) /* Start connection */ + { + int res = cs_connect(t->link, t->addr); + + t->state = Connecting; + if (!res) /* we are go */ + iochan_setevent(i, EVENT_OUTPUT); + else if (res == 1) + iochan_setflags(i, EVENT_OUTPUT); + else + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "ERROR %s connect\n", t->hostport); + cs_close(t->link); + t->state = Failed; + iochan_destroy(i); + } + } + + else if (t->state == Connecting && event & EVENT_OUTPUT) + { + int errcode; + socklen_t errlen = sizeof(errcode); + + if (getsockopt(cs_fileno(t->link), SOL_SOCKET, SO_ERROR, &errcode, + &errlen) < 0 || errcode != 0) + { + cs_close(t->link); + iochan_destroy(i); + t->state = Failed; + return; + } + else + { + yaz_log(YLOG_DEBUG, "Connect OK"); + t->state = Connected; + } + } + + else if (event & EVENT_INPUT) + { + int len = cs_get(t->link, &t->ibuf, &t->ibufsize); + + if (len < 0) + { + cs_close(t->link); + iochan_destroy(i); + t->state = Failed; + return; + } + if (len == 0) + { + cs_close(t->link); + iochan_destroy(i); + t->state = Failed; + return; + } + else if (len > 1) + { + if (t->requestid == s->requestid || t->state == Initializing) + { + Z_APDU *a; + + odr_reset(t->odr_in); + odr_setbuf(t->odr_in, t->ibuf, len, 0); + if (!z_APDU(t->odr_in, &a, 0, 0)) + { + cs_close(t->link); + iochan_destroy(i); + t->state = Failed; + return; + } + switch (a->which) + { + case Z_APDU_initResponse: + do_initResponse(i, a); + break; + case Z_APDU_searchResponse: + do_searchResponse(i, a); + break; + case Z_APDU_presentResponse: + do_presentResponse(i, a); + break; + default: + yaz_log(YLOG_WARN, "Unexpected result from server"); + cs_close(t->link); + iochan_destroy(i); + t->state = Failed; + return; + } + // if (cs_more(t->link)) + // iochan_setevent(i, EVENT_INPUT); + } + else // we throw away response and go to idle mode + t->state = Idle; + } + /* if len==1 we do nothing but wait for more input */ + } + + else if (t->state == Connected) { + send_init(i); + } + + if (t->state == Idle) + { + if (t->requestid != s->requestid) { + send_search(i); + } + else if (t->hits > 0 && t->records < global_parameters.toget && + t->records < t->hits) { + send_present(i); + } + } +} + +int load_targets(struct session *s, const char *fn) +{ + FILE *f = fopen(fn, "r"); + char line[256]; + struct target **target_p; + + if (!f) + { + yaz_log(YLOG_WARN|YLOG_ERRNO, "open %s", fn); + return -1; + } + + target_p = &s->targets; + while (fgets(line, 255, f)) + { + char *url, *p; + struct target *target; + IOCHAN new; + + if (strncmp(line, "target ", 7)) + continue; + url = line + 7; + url[strlen(url) - 1] = '\0'; + yaz_log(LOG_DEBUG, "Target: %s", url); + + *target_p = target = xmalloc(sizeof(**target_p)); + target->next = 0; + target_p = &target->next; + target->state = No_connection; + target->ibuf = 0; + target->ibufsize = 0; + target->odr_in = odr_createmem(ODR_DECODE); + target->odr_out = odr_createmem(ODR_ENCODE); + target->hits = -1; + target->setno = 0; + target->session = s; + target->requestid = -1; + target->records = 0; + target->diagnostic = 0; + strcpy(target->fullname, url); + if ((p = strchr(url, '/'))) + { + *p = '\0'; + strcpy(target->hostport, url); + *p = '/'; + p++; + strcpy(target->databases[0], p); + target->databases[1][0] = '\0'; + } + else + { + strcpy(target->hostport, url); + strcpy(target->databases[0], "Default"); + target->databases[1][0] = '\0'; + } + + if (!(target->link = cs_create(tcpip_type, 0, PROTO_Z3950))) + { + yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to create comstack"); + exit(1); + } + if (!(target->addr = cs_straddr(target->link, target->hostport))) + { + printf("ERROR %s bad-address", target->hostport); + target->state = Failed; + continue; + } + new = iochan_create(cs_fileno(target->link), handler, 0); + iochan_setdata(new, target); + iochan_setevent(new, EVENT_EXCEPT); + new->next = channel_list; + channel_list = new; + } + fclose(f); + + return 0; +} + +void search(struct session *s, char *query) +{ + IOCHAN c; + + yaz_log(YLOG_DEBUG, "Search"); + + // Determine what iochans belong to this session + // It might have been better to have a list of them + + strcpy(s->query, query); + s->requestid++; + nmem_reset(s->nmem); + for (c = channel_list; c; c = c->next) + { + struct target *t; + + if (iochan_getfun(c) != handler) // Not a Z target + continue; + t = iochan_getdata(c); + if (t->session == s) + { + t->hits = -1; + t->records = 0; + t->diagnostic = 0; + + if (t->state == Error) + t->state = Idle; + + if (t->state == Idle) + iochan_setflag(c, EVENT_OUTPUT); + } + } +} + +struct session *new_session() +{ + struct session *session = xmalloc(sizeof(*session)); + + yaz_log(YLOG_DEBUG, "New pazpar2 session"); + + session->requestid = -1; + session->targets = 0; + session->pqf_parser = yaz_pqf_create(); + session->query[0] = '\0'; + session->nmem = nmem_create(); + + return session; +} + +struct hitsbytarget *hitsbytarget(struct session *s, int *count) +{ + static struct hitsbytarget res[1000]; // FIXME MM + IOCHAN c; + + *count = 0; + for (c = channel_list; c; c = c->next) + if (iochan_getfun(c) == handler) + { + struct target *t = iochan_getdata(c); + if (t->session == s) + { + strcpy(res[*count].id, t->hostport); + res[*count].hits = t->hits; + res[*count].records = t->records; + res[*count].diagnostic = t->diagnostic; + res[*count].state = state_strings[(int) t->state]; + (*count)++; + } + } + + return res; +} + + +void statistics(struct session *s, struct statistics *stat) +{ + IOCHAN c; + int i; + + bzero(stat, sizeof(*stat)); + for (i = 0, c = channel_list; c; i++, c = c->next) + { + struct target *t; + if (iochan_getfun(c) != handler) + continue; + t = iochan_getdata(c); + switch (t->state) + { + case No_connection: stat->num_no_connection++; break; + case Connecting: stat->num_connecting++; break; + case Initializing: stat->num_initializing++; break; + case Searching: stat->num_searching++; break; + case Presenting: stat->num_presenting++; break; + case Idle: stat->num_idle++; break; + case Failed: stat->num_failed++; break; + case Error: stat->num_error++; break; + default: break; + } + } + + stat->num_connections = i; +} + +int main(int argc, char **argv) +{ + int ret; + char *arg; + + if (signal(SIGPIPE, SIG_IGN) < 0) + yaz_log(YLOG_WARN|YLOG_ERRNO, "signal"); + + myname = argv[0]; + yaz_log_init(YLOG_DEFAULT_LEVEL|YLOG_DEBUG, "pazpar2", 0); + + while ((ret = options("c:", argv, argc, &arg)) != -2) + { + switch (ret) { + case 0: + break; + case 'c': + command_init(atoi(arg)); + break; + default: + fprintf(stderr, "Usage: pazpar2 -d comport"); + exit(1); + } + + } + + event_loop(&channel_list); + + return 0; +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/pazpar2.h b/pazpar2.h new file mode 100644 index 0000000..1e22b78 --- /dev/null +++ b/pazpar2.h @@ -0,0 +1,57 @@ +#ifndef PAZPAR2_H +#define PAZPAR2_H + +#include + +struct session { + struct target *targets; + YAZ_PQF_Parser pqf_parser; + int requestid; + char query[1024]; + NMEM nmem; +}; + +struct record { + struct target *target; + int target_offset; + char *buf; + char *merge_key; + struct record *next_cluster; + struct record *head_cluster; +}; + +struct statistics { + int num_connections; + int num_no_connection; + int num_connecting; + int num_initializing; + int num_searching; + int num_presenting; + int num_idle; + int num_failed; + int num_error; +}; + +struct hitsbytarget { + char id[256]; + int hits; + int diagnostic; + int records; + char* state; +}; + +struct hitsbytarget *hitsbytarget(struct session *s, int *count); +struct session *new_session(); +int load_targets(struct session *s, const char *fn); +void statistics(struct session *s, struct statistics *stat); +void search(struct session *s, char *query); + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/test.pz b/test.pz new file mode 100644 index 0000000..0fb10c8 --- /dev/null +++ b/test.pz @@ -0,0 +1 @@ +target localhost:9999/Default diff --git a/util.c b/util.c new file mode 100644 index 0000000..a92d340 --- /dev/null +++ b/util.c @@ -0,0 +1,13 @@ +/* $Id: util.c,v 1.1 2006-11-14 20:44:38 quinn Exp $ */ + +#include +#include + +extern char *myname; + +void die(char *string, char *add) +{ + fprintf(stderr, "%s: %s (%s)\n", myname, string, add ? add : ""); + abort(); +} + diff --git a/util.h b/util.h new file mode 100644 index 0000000..10f7981 --- /dev/null +++ b/util.h @@ -0,0 +1,8 @@ +/* $Id: util.h,v 1.1 2006-11-14 20:44:38 quinn Exp $ */ + +#ifndef UTIL_H +#define UTIL_H + +void die(char *string, char *add); + +#endif -- 1.7.10.4