From: Adam Dickmeiss Date: Mon, 6 Jan 2003 08:20:26 +0000 (+0000) Subject: SRW, CQL, 2003 X-Git-Tag: YAZ.1.9.2.Roel~7 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=4d531a1a9131d69c3b6c27fbac42837e22cff61c SRW, CQL, 2003 --- diff --git a/CHANGELOG b/CHANGELOG index 917ac97..0bbd392 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,20 @@ Possible compatibility problems with earlier versions marked with '*'. ---- 1.9.3 2002/MM/DD +--- 1.9.3 2003/MM/DD + +Support for SRW 1.0. This is an optional feature and requires +gSOAP to operate. Enable it by specifying --with-gsoap for +configure. SRW stuff is located in sub directory srw. +Example applications are located in srwapps. + +Z39.50 Query Type-104 added - to facilitate CQL within Z39.50. + +CQL support. Source is directory 'cql'. CQL is supported in ZOOM +(both SRW and Z39.50) and the YAZ client (Z39.50 only). + +ZOOM connections are SRW based if host/port is specified +as http. e.g. z = ZOOM_connection_new("http://myserver"); +ZOOM_query may be of type CQL, e.g. ZOOM_query_cql(q, "dc.title=x"); CCL proximity operators !n, %n converts to PQF @prox 0 n 1 2 k 2 and @prox 0 n 0 1 k 2 respectively, meaning: exlusion=false, diff --git a/LICENSE b/LICENSE index 6235cb1..db81ecc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, diff --git a/Makefile.am b/Makefile.am index 260c395..4c1ea35 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,10 @@ -## $Id: Makefile.am,v 1.17 2002-10-22 12:51:18 adam Exp $ +## Copyright (C) 1994-2003, Index Data +## All rights reserved. +## $Id: Makefile.am,v 1.18 2003-01-06 08:20:26 adam Exp $ AUTOMAKE_OPTIONS = foreign -SUBDIRS = util odr comstack z39.50 ill zutil ccl server include lib client ztest zoom doc +SUBDIRS = util odr comstack z39.50 ill srw zutil ccl cql server include lib client ztest zoom srwapps doc etc aclocaldir=$(datadir)/aclocal diff --git a/README b/README index bc2f56b..889f14a 100644 --- a/README +++ b/README @@ -1,11 +1,11 @@ -YAZ toolkit - $Id: README,v 1.41 2002-08-27 13:30:18 adam Exp $ +YAZ toolkit - $Id: README,v 1.42 2003-01-06 08:20:26 adam Exp $ -Copyright (C) 1995-2002, Index Data ApS. +Copyright (C) 1995-2003, Index Data ApS. See the file LICENSE for details. The primary output of the source here is the YAZ library, which contains support functions for implementing the server or client -role of Z39.50. +role of Z39.50 and SRW. Windows programmers: refer to the file windows.txt which describes how to build the software using Microsoft Visual C++. @@ -52,11 +52,19 @@ zoom An implementation of Mike Taylors Z39.50 Object Oriented in C this may be good start. You'll find example programs in this directory too. -server This is the implementation of the server frontend. It +server This is the implementation of the Z39.50 server frontend. It provides event-handling and server managament functions, and calls the backend primitives (best documentation of these is in the file include/yaz/backend.h). +ccl CCL parser. + +cql CQL parser. + +srw SRW support (based on gSOAP). + +srwapps SRW applicaions, most notably a SRW-to-Z39.50 gateway. + client A demonstration client for testing the protocol. It's bug'n ugly. But, it supports many features. diff --git a/client/admin.c b/client/admin.c index b94e968..4f96bce 100644 --- a/client/admin.c +++ b/client/admin.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: admin.c,v 1.14 2002-09-24 08:05:41 adam Exp $ + * $Id: admin.c,v 1.15 2003-01-06 08:20:26 adam Exp $ */ #include diff --git a/client/admin.h b/client/admin.h index efa8483..f2d49fb 100644 --- a/client/admin.h +++ b/client/admin.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: admin.h,v 1.4 2002-09-17 11:07:30 adam Exp $ + * $Id: admin.h,v 1.5 2003-01-06 08:20:26 adam Exp $ */ int cmd_adm_reindex(char* arg); diff --git a/client/client.c b/client/client.c index 3db21cf..639feca 100644 --- a/client/client.c +++ b/client/client.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: client.c,v 1.177 2002-12-16 13:30:41 adam Exp $ + * $Id: client.c,v 1.178 2003-01-06 08:20:26 adam Exp $ */ #include @@ -97,7 +97,8 @@ static int auto_reconnect = 0; typedef enum { QueryType_Prefix, QueryType_CCL, - QueryType_CCL2RPN + QueryType_CCL2RPN, + QueryType_CQL } QueryType; static QueryType queryType = QueryType_Prefix; @@ -144,6 +145,7 @@ const char* query_type_as_string(QueryType q) case QueryType_Prefix: return "prefix (RPN sent to server)"; case QueryType_CCL: return "CCL (CCL sent to server) "; case QueryType_CCL2RPN: return "CCL -> RPN (RPN sent to server)"; + case QueryType_CQL: return "CQL (CQL sent to server)"; default: return "unknown Query type internal yaz-client error"; } @@ -875,6 +877,7 @@ static int send_searchRequest(char *arg) Z_RPNQuery *RPNquery; Odr_oct ccl_query; YAZ_PQF_Parser pqf_parser; + Z_External *ext; if (queryType == QueryType_CCL2RPN) { @@ -961,6 +964,16 @@ static int send_searchRequest(char *arg) query.u.type_1 = RPNquery; ccl_rpn_delete (rpn); break; + case QueryType_CQL: + query.which = Z_Query_type_104; + ext = odr_malloc(out, sizeof(*ext)); + ext->direct_reference = odr_getoidbystr(out, "1.2.840.10003.16.2"); + ext->indirect_reference = 0; + ext->descriptor = 0; + ext->which = Z_External_CQL; + ext->u.cql = odr_strdup(out, arg); + query.u.type_104 = ext; + break; default: printf ("Unsupported query type\n"); return 0; @@ -2225,12 +2238,15 @@ int cmd_querytype (char *arg) queryType = QueryType_Prefix; else if (!strcmp (arg, "ccl2rpn") || !strcmp (arg, "cclrpn")) queryType = QueryType_CCL2RPN; + else if (!strcmp(arg, "cql")) + queryType = QueryType_CQL; else { printf ("Querytype must be one of:\n"); printf (" prefix - Prefix query\n"); printf (" ccl - CCL query\n"); printf (" ccl2rpn - CCL query converted to RPN\n"); + printf (" cql - CQL\n"); return 0; } return 1; diff --git a/client/tabcomplete.c b/client/tabcomplete.c index ad48f3b..c1eeba4 100644 --- a/client/tabcomplete.c +++ b/client/tabcomplete.c @@ -2,7 +2,7 @@ * Copyright (c) 2002, Index Data * See the file LICENSE for details. * - * $Id: tabcomplete.c,v 1.8 2002-09-24 08:05:41 adam Exp $ + * $Id: tabcomplete.c,v 1.9 2003-01-06 08:20:26 adam Exp $ */ #include @@ -14,11 +14,11 @@ extern char** curret_global_list; -/* ***************************************************************************** +/* *************************************************************************** * - * generic compleater + * generic completer * - * *****************************************************************************/ + * ***************************************************************************/ char* complete_from_list(char* completions[], const char *text, int state) { @@ -44,11 +44,11 @@ char* complete_from_list(char* completions[], const char *text, int state) } -/* ***************************************************************************** +/* *************************************************************************** * * code for getting a list of valid strings from the oid subsystem * - * *****************************************************************************/ + * ***************************************************************************/ typedef struct { @@ -59,8 +59,8 @@ typedef struct { } oid_callback_t; /*! - This is the call back function given to oid_trav... it updates the list of pointers into the oid - owned data + This is the call back function given to oid_trav... it updates the list + of pointers into the oid owned data */ void oid_loader(struct oident* oid, void* data_) @@ -91,15 +91,15 @@ char** build_list_for_oclass(oid_class oclass) { return data.values; } -/* ***************************************************************************** +/* *************************************************************************** * - * the compleater functions + * the completer functions * - * *****************************************************************************/ + * ***************************************************************************/ char* complete_querytype(const char *text, int state) { - char* querytypes[] = {"ccl2rpn","prefix","cclrpn","ccl",0}; + char* querytypes[] = {"ccl2rpn","prefix","cclrpn","ccl","cql", 0}; return complete_from_list(querytypes,text,state); } diff --git a/comstack/tcpip.c b/comstack/tcpip.c index 9e0e0cf..8649a3f 100644 --- a/comstack/tcpip.c +++ b/comstack/tcpip.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: tcpip.c,v 1.52 2002-12-19 14:04:22 adam Exp $ + * $Id: tcpip.c,v 1.53 2003-01-06 08:20:27 adam Exp $ */ #include diff --git a/comstack/unix.c b/comstack/unix.c index 235c9b1..908ab7e 100644 --- a/comstack/unix.c +++ b/comstack/unix.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: unix.c,v 1.8 2002-12-15 21:22:58 adam Exp $ + * $Id: unix.c,v 1.9 2003-01-06 08:20:27 adam Exp $ * UNIX socket COMSTACK. By Morten Bøgeskov. */ #ifndef WIN32 diff --git a/configure.in b/configure.in index 41cf8d1..50fcf89 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ -dnl YAZ Toolkit, Index Data 1994-2002 +dnl YAZ Toolkit, Index Data 1994-2003 dnl See the file LICENSE for details. -dnl $Id: configure.in,v 1.99 2002-12-16 13:13:53 adam Exp $ +dnl $Id: configure.in,v 1.100 2003-01-06 08:20:26 adam Exp $ AC_INIT(include/yaz/yaz-version.h) AM_INIT_AUTOMAKE(yaz, 1.9.2) dnl @@ -9,6 +9,8 @@ AC_SUBST(YAZ_CONF_CFLAGS) dnl ------ Checking programs AC_PROG_CC AC_PROG_CPP +AC_CHECK_PROGS(YACC, 'bison -y') +test -z "$YACC" && AC_MSG_WARN([GNU bison not found]) AC_PROG_INSTALL AM_DISABLE_SHARED AM_PROG_LIBTOOL @@ -173,7 +175,7 @@ if test "$with_iconv" != "no"; then ]) fi dnl ------ various functions -AC_CHECK_FUNCS(vsnprintf gettimeofday poll) +AC_CHECK_FUNCS(vsnprintf gettimeofday poll strerror_r) if test "$ac_cv_func_poll" = "yes"; then AC_CHECK_HEADERS(sys/poll.h) fi @@ -306,6 +308,58 @@ if test "$enable_threads" = "yes" -a "$HAVETHREADS" = "0"; then fi AM_CONDITIONAL(ISTHR, test $HAVETHREADS = "1") dnl +dnl ----- gSOAP +AC_SUBST(GSOAP_LIB) +AC_SUBST(GSOAP_INCLUDE) +AC_SUBST(GSOAP_PREFIX) +gsoapdir=NONE +AC_ARG_WITH(gsoap, [ --with-gsoap[=PREFIX] Use gSOAP in PREFIX/{lib,include}],[gsoapdir=$withval]) +if test "x$gsoapdir" = "xNONE"; then + for d in /usr /usr/local; do + if test -f $d/include/stdsoap2.h; then + gsoapdir=$d + fi + done +fi +AC_MSG_CHECKING(for gSOAP prefix) +GSOAP_PREFIX=$gsoapdir +if test -x $gsoapdir/bin/soapcpp2; then + AC_MSG_RESULT($gsoapdir) + if test "$gsoapdir" != "/usr"; then + GSOAP_LIB="-L$gsoapdir/lib -lgsoap" + GSOAP_INCLUDE=-I$gsoapdir/include + fi + AC_DEFINE(HAVE_GSOAP) + usesrw=1 +else + AC_MSG_RESULT(Not found) + usesrw=0 +fi +AM_CONDITIONAL(SRW, test $usesrw = "1") +dnl +dnl ----- XML/XSLT +AC_SUBST(XSLT_LIB) +AC_SUBST(XSLT_CFLAGS) +xsltdir=NONE +AC_ARG_WITH(xslt, [ --with-xslt[=PREFIX] Use libxslt in PREFIX/{lib,include}],[xsltdir=$withval]) +if test "x$xsltdir" = "xNONE"; then + for d in /usr /usr/local; do + if test -x $d/bin/xslt-config; then + xsltdir=$d + fi + done +fi +AC_MSG_CHECKING(for XSLT) +if test -x $xsltdir/bin/xslt-config; then + XSLT_LIB=`$xsltdir/bin/xslt-config --libs` + XSLT_CFLAGS=`$xsltdir/bin/xslt-config --cflags` + XSLT_VER=`$xsltdir/bin/xslt-config --version` + AC_MSG_RESULT($XSLT_VER) + AC_DEFINE(HAVE_XSLT) +else + AC_MSG_RESULT(Not found) +fi +dnl dnl ------ Memory debugging AC_ARG_ENABLE(memdebug, [ --enable-memdebug enable memory debugging],[enable_memdebug=$enableval],[enable_memdebug=none]) if test "$enable_memdebug" = "yes"; then @@ -328,13 +382,16 @@ yaz.spec util/Makefile odr/Makefile z39.50/Makefile +srw/Makefile ill/Makefile zutil/Makefile comstack/Makefile ccl/Makefile +cql/Makefile server/Makefile include/Makefile include/yaz/Makefile +srwapps/Makefile lib/Makefile client/Makefile ztest/Makefile @@ -345,5 +402,6 @@ doc/yazhtml.dsl doc/yazphp.dsl doc/yazprint.dsl doc/tkl.xsl +etc/Makefile yaz-config ],[sed s%yaz_echo_source=yes%yaz_echo_source=no%g < yaz-config > lib/yaz-config && chmod +x yaz-config lib/yaz-config]) diff --git a/cql/.cvsignore b/cql/.cvsignore new file mode 100644 index 0000000..f995e38 --- /dev/null +++ b/cql/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la +cql.c diff --git a/cql/Makefile.am b/cql/Makefile.am new file mode 100644 index 0000000..c0c875e --- /dev/null +++ b/cql/Makefile.am @@ -0,0 +1,17 @@ +# $Id: Makefile.am,v 1.1 2003-01-06 08:20:27 adam Exp $ +AM_YFLAGS=-p cql_ + +AM_CPPFLAGS=-I$(top_srcdir)/include + +noinst_LTLIBRARIES = libcql.la +noinst_PROGRAMS = cql2pqf cql2xcql + +EXTRA_DIST=lexer.c + +libcql_la_SOURCES=cql.y cqlstdio.c cqltransform.c \ + cqlutil.c xcqlutil.c cqlstring.c cql.h + +cql2pqf_SOURCES = cql2pqf.c +cql2xcql_SOURCES = cql2xcql.c + +LDADD=libcql.la diff --git a/cql/cql.y b/cql/cql.y new file mode 100644 index 0000000..4a816aa --- /dev/null +++ b/cql/cql.y @@ -0,0 +1,267 @@ +/* $Id: cql.y,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. + + bison parser for CQL grammar. +*/ +%{ +#include +#include +#include +#include +#include + + typedef struct { + struct cql_node *rel; + struct cql_node *cql; + char buf[80]; + size_t len; + size_t max; + } token; + + struct cql_parser { + int (*getbyte)(void *client_data); + void (*ungetbyte)(int b, void *client_data); + void *client_data; + int last_error; + int last_pos; + struct cql_node *top; + }; + +#define YYSTYPE token + +#define YYPARSE_PARAM parm +#define YYLEX_PARAM parm + + int yylex(YYSTYPE *lval, void *vp); + int yyerror(char *s); +%} + +%pure_parser +%token TERM AND OR NOT PROX EXACT ALL ANY GE LE NE SCR +%expect 8 + +%% + +top: { + $$.rel = cql_node_mk_sc("srw.serverChoice", "scr", 0); + ((CQL_parser) parm)->top = 0; +} cqlQuery1 { + cql_node_destroy($$.rel); + ((CQL_parser) parm)->top = $2.cql; +} +; + +cqlQuery1: cqlQuery +| cqlQuery error { + cql_node_destroy($1.cql); + $$.cql = 0; +} +; + +cqlQuery: + searchClause +| + cqlQuery boolean { + $$.rel = $0.rel; + } searchClause { + struct cql_node *cn = cql_node_mk_boolean($2.buf); + + cn->u.bool.modifiers = $2.rel; + cn->u.bool.left = $1.cql; + cn->u.bool.right = $4.cql; + + $$.cql = cn; + } +; + +searchClause: + '(' { + $$.rel = $0.rel; + + } cqlQuery ')' { + $$.cql = $3.cql; + } +| + searchTerm { + struct cql_node *st = cql_node_dup ($0.rel); + st->u.st.term = strdup($1.buf); + $$.cql = st; + } +| + index relation { + $$.rel = $2.rel; + $$.rel->u.st.index = strdup($1.buf); + } searchClause { + $$.cql = $4.cql; + cql_node_destroy($$.rel); + } +| '>' searchTerm '=' searchTerm { + $$.rel = $0.rel; + } cqlQuery { + $$.cql = cql_node_prefix($6.cql, $2.buf, $4.buf); + } +| '>' searchTerm { + $$.rel = $0.rel; + } cqlQuery { + $$.cql = cql_node_prefix($4.cql, 0, $2.buf); + } +; + +boolean: + AND | OR | NOT | PROX proxqualifiers { + $$ = $1; + $$.rel = $2.rel; + } + ; + +proxqualifiers: + Prelation { + $$.rel = cql_node_mk_proxargs ($1.buf, 0, 0, 0); + } +| + PrelationO Pdistance { + $$.rel = cql_node_mk_proxargs ($1.buf, $2.buf, 0, 0); + } +| + PrelationO PdistanceO Punit { + $$.rel = cql_node_mk_proxargs ($1.buf, $2.buf, $3.buf, 0); + } +| + PrelationO PdistanceO PunitO Pordering { + $$.rel = cql_node_mk_proxargs ($1.buf, $2.buf, $3.buf, $4.buf); + } +| +{ $$.rel = 0; } +; + +Punit: '/' searchTerm { + $$ = $2; + } +; + +PunitO: '/' searchTerm { + $$ = $2; + } +| +'/' { $$.buf[0] = 0; } +; +Prelation: '/' baseRelation { + $$ = $2; +} +; +PrelationO: '/' baseRelation { + $$ = $2; +} +| '/' { $$.buf[0] = 0; } +; +Pdistance: '/' searchTerm { + $$ = $2; +} +; + +PdistanceO: '/' searchTerm { + $$ = $2; +} +| '/' { $$.buf[0] = 0; } +; +Pordering: '/' searchTerm { + $$ = $2; +} +; + +relation: baseRelation modifiers { + struct cql_node *st = cql_node_mk_sc(/* index */ 0, + /* relation */ $1.buf, + /* term */ 0); + + st->u.st.modifiers = $2.cql; + $$.rel = st; +} +; + +modifiers: '/' searchTerm modifiers +{ + struct cql_node *mod = cql_node_mk_mod(0, $2.buf); + + mod->u.mod.next = $3.cql; + $$.cql = mod; +} +| +{ + $$.cql = 0; +} +; + +baseRelation: + '=' +| '>' +| '<' +| GE +| LE +| NE +| EXACT +| ALL +| ANY +| SCR +; + +index: + searchTerm; + +searchTerm: + TERM +| AND +| OR +| NOT +| EXACT +| ALL +| ANY +| PROX +; + +%% + +int yyerror(char *s) +{ + return 0; +} + +#include "lexer.c" + + +int cql_parser_stream(CQL_parser cp, + int (*getbyte)(void *client_data), + void (*ungetbyte)(int b, void *client_data), + void *client_data) +{ + cp->getbyte = getbyte; + cp->ungetbyte = ungetbyte; + cp->client_data = client_data; + cql_parse(cp); + if (cp->top) + return 0; + return -1; +} + +CQL_parser cql_parser_create(void) +{ + CQL_parser cp = malloc (sizeof(*cp)); + + return cp; +} + +void cql_parser_destroy(CQL_parser cp) +{ + cql_node_destroy(cp->top); + free (cp); +} + +struct cql_node *cql_parser_result(CQL_parser cp) +{ + return cp->top; +} diff --git a/cql/cql2pqf.c b/cql/cql2pqf.c new file mode 100644 index 0000000..e5a3731 --- /dev/null +++ b/cql/cql2pqf.c @@ -0,0 +1,52 @@ +/* $Id: cql2pqf.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include +#include + +#include + +int main(int argc, char **argv) +{ + cql_transform_t ct; + int r; + CQL_parser cp = cql_parser_create(); + + if (argc < 2) + { + fprintf (stderr, "usage\n cqltransform []\n"); + exit (1); + } + ct = cql_transform_open_fname(argv[1]); + if (!ct) + { + fprintf (stderr, "failed to read properties %s\n", argv[1]); + exit (1); + } + if (argc == 3) + r = cql_parser_string(cp, argv[2]); + else + r = cql_parser_stdio(cp, stdin); + if (r) + fprintf (stderr, "Syntax error\n"); + else + { + r = cql_transform_FILE(ct, cql_parser_result(cp), stdout); + printf("\n"); + if (r) + { + const char *addinfo; + cql_transform_error(ct, &addinfo); + printf ("Transform error %d %s\n", r, addinfo ? addinfo : ""); + } + } + cql_transform_close(ct); + cql_parser_destroy(cp); + return 0; +} diff --git a/cql/cql2xcql.c b/cql/cql2xcql.c new file mode 100644 index 0000000..b2db2e5 --- /dev/null +++ b/cql/cql2xcql.c @@ -0,0 +1,28 @@ +/* $Id: cql2xcql.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include + +#include + +int main(int argc, char **argv) +{ + int r; + CQL_parser cp = cql_parser_create(); + if (argc == 2) + r = cql_parser_string(cp, argv[1]); + else + r = cql_parser_stdio(cp, stdin); + if (r) + fprintf (stderr, "Syntax error\n"); + else + cql_to_xml_stdio(cql_parser_result(cp), stdout); + cql_parser_destroy(cp); + return 0; +} diff --git a/cql/cqlstdio.c b/cql/cqlstdio.c new file mode 100644 index 0000000..7846f0d --- /dev/null +++ b/cql/cqlstdio.c @@ -0,0 +1,36 @@ +/* $Id: cqlstdio.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include + +int getbyte_stream(void *client_data) +{ + FILE *f = (FILE*) client_data; + + int c = fgetc(f); + if (c == EOF) + return 0; + return c; +} + +void ungetbyte_stream (int c, void *client_data) +{ + FILE *f = (FILE*) client_data; + + if (c == 0) + c = EOF; + ungetc(c, f); +} + +int cql_parser_stdio(CQL_parser cp, FILE *f) +{ + return cql_parser_stream(cp, getbyte_stream, ungetbyte_stream, f); +} + + diff --git a/cql/cqlstring.c b/cql/cqlstring.c new file mode 100644 index 0000000..b04dd5b --- /dev/null +++ b/cql/cqlstring.c @@ -0,0 +1,40 @@ +/* $Id: cqlstring.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE for details. +*/ +#include + +struct cql_buf_info { + const char *str; + int off; +}; + +int getbuf(void *vp) +{ + struct cql_buf_info *bi = vp; + if (bi->str[bi->off] == 0) + return 0; + return bi->str[bi->off++]; +} + +void ungetbuf(int b, void *vp) +{ + struct cql_buf_info *bi = vp; + if (b) + (bi->off--); +} + +int cql_parser_string(CQL_parser cp, const char *str) +{ + struct cql_buf_info b; + + b.str = str; + b.off = 0; + + return cql_parser_stream(cp, getbuf, ungetbuf, &b); +} + diff --git a/cql/cqltransform.c b/cql/cqltransform.c new file mode 100644 index 0000000..d5e3ddb --- /dev/null +++ b/cql/cqltransform.c @@ -0,0 +1,462 @@ +/* $Id: cqltransform.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include +#include +#include + +struct cql_prop_entry { + char *pattern; + char *value; + struct cql_prop_entry *next; +}; + +struct cql_transform_t_ { + struct cql_prop_entry *entry; + int error; + char *addinfo; +}; + +cql_transform_t cql_transform_open_FILE(FILE *f) +{ + char line[1024]; + cql_transform_t ct = malloc (sizeof(*ct)); + struct cql_prop_entry **pp = &ct->entry; + + ct->error = 0; + ct->addinfo = 0; + while (fgets(line, sizeof(line)-1, f)) + { + const char *cp_value_start; + const char *cp_value_end; + const char *cp_pattern_end; + const char *cp = line; + while (*cp && !strchr(" \t=\r\n#", *cp)) + cp++; + cp_pattern_end = cp; + if (cp == line) + continue; + while (*cp && strchr(" \t\r\n", *cp)) + cp++; + if (*cp != '=') + continue; + cp++; + while (*cp && strchr(" \t\r\n", *cp)) + cp++; + cp_value_start = cp; + if (!(cp_value_end = strchr(cp, '#'))) + cp_value_end = strlen(line) + line; + + if (cp_value_end != cp_value_start && + strchr(" \t\r\n", cp_value_end[-1])) + cp_value_end--; + *pp = malloc (sizeof(**pp)); + (*pp)->pattern = malloc (cp_pattern_end - line + 1); + memcpy ((*pp)->pattern, line, cp_pattern_end - line); + (*pp)->pattern[cp_pattern_end-line] = 0; + + (*pp)->value = malloc (cp_value_end - cp_value_start + 1); + if (cp_value_start != cp_value_end) + memcpy ((*pp)->value, cp_value_start, cp_value_end-cp_value_start); + (*pp)->value[cp_value_end - cp_value_start] = 0; + pp = &(*pp)->next; + } + *pp = 0; + return ct; +} + +void cql_transform_close(cql_transform_t ct) +{ + struct cql_prop_entry *pe; + if (!ct) + return; + pe = ct->entry; + while (pe) + { + struct cql_prop_entry *pe_next = pe->next; + free (pe->pattern); + free (pe->value); + free (pe); + pe = pe_next; + } + if (ct->addinfo) + free (ct->addinfo); + free (ct); +} + +cql_transform_t cql_transform_open_fname(const char *fname) +{ + cql_transform_t ct; + FILE *f = fopen(fname, "r"); + if (!f) + return 0; + ct = cql_transform_open_FILE(f); + fclose(f); + return ct; +} + +static const char *cql_lookup_property(cql_transform_t ct, + const char *pat1, const char *pat2) +{ + char pattern[80]; + struct cql_prop_entry *e; + + if (pat2) + sprintf (pattern, "%.39s%.39s", pat1, pat2); + else + sprintf (pattern, "%.39s", pat1); + for (e = ct->entry; e; e = e->next) + { + if (!strcmp(e->pattern, pattern)) + return e->value; + } + return 0; +} + +static const char *cql_lookup_value(cql_transform_t ct, + const char *prefix, + const char *value) +{ + struct cql_prop_entry *e; + int len = strlen(prefix); + + for (e = ct->entry; e; e = e->next) + { + if (!memcmp(e->pattern, prefix, len) && !strcmp(e->value, value)) + return e->pattern + len; + } + return 0; +} + + +int cql_pr_attr(cql_transform_t ct, const char *category, + const char *val, + const char *default_val, + void (*pr)(const char *buf, void *client_data), + void *client_data, + int errcode) +{ + const char *res; + res = cql_lookup_property(ct, category, val ? val : default_val); + if (!res) + res = cql_lookup_property(ct, category, "*"); + if (res) + { + char buf[64]; + + const char *cp0 = res, *cp1; + while ((cp1 = strchr(cp0, '='))) + { + while (*cp1 && *cp1 != ' ') + cp1++; + if (cp1 - cp0 >= sizeof(buf)) + break; + memcpy (buf, cp0, cp1 - cp0); + buf[cp1-cp0] = 0; + (*pr)("@attr ", client_data); + (*pr)(buf, client_data); + (*pr)(" ", client_data); + cp0 = cp1; + while (*cp0 == ' ') + cp0++; + } + return 1; + } + /* error ... */ + if (errcode && !ct->error) + { + ct->error = errcode; + ct->addinfo = strdup(val); + } + return 0; +} + +void emit_term(cql_transform_t ct, + const char *term, int length, + void (*pr)(const char *buf, void *client_data), + void *client_data) +{ + int i; + if (length > 0) + { + if (length > 1 && term[0] == '^' && term[length-1] == '^') + { + cql_pr_attr(ct, "position.", "firstAndLast", 0, + pr, client_data, 32); + term++; + length -= 2; + } + else if (term[0] == '^') + { + cql_pr_attr(ct, "position.", "first", 0, + pr, client_data, 32); + term++; + } + else if (term[length-1] == '^') + { + cql_pr_attr(ct, "position.", "last", 0, + pr, client_data, 32); + length--; + } + else + { + cql_pr_attr(ct, "position.", "any", 0, + pr, client_data, 32); + } + } + (*pr)("\"", client_data); + for (i = 0; iu.st.term; + const char *cp1; + const char *last_term = 0; + int last_length = 0; + while(cp0) + { + while (*cp0 == ' ') + cp0++; + cp1 = strchr(cp0, ' '); + if (last_term) + { + (*pr)("@", client_data); + (*pr)(op, client_data); + (*pr)(" ", client_data); + emit_term(ct, last_term, last_length, pr, client_data); + } + last_term = cp0; + if (cp1) + last_length = cp1 - cp0; + else + last_length = strlen(cp0); + cp0 = cp1; + } + if (last_term) + emit_term(ct, last_term, last_length, pr, client_data); +} + + +static const char *cql_get_ns(cql_transform_t ct, + struct cql_node *cn, + struct cql_node **prefix_ar, int prefix_level, + const char **n_prefix, + const char **n_suffix) +{ + int i; + const char *ns = 0; + char prefix[32]; + const char *cp = cn->u.st.index; + const char *cp_dot = strchr(cp, '.'); + + /* strz current prefix (empty if not given) */ + if (cp_dot && cp_dot-cp < sizeof(prefix)) + { + memcpy (prefix, cp, cp_dot - cp); + prefix[cp_dot - cp] = 0; + } + else + *prefix = 0; + + /* 2. lookup in prefix_ar. and return NS */ + for (i = prefix_level; !ns && --i >= 0; ) + { + struct cql_node *cn_prefix = prefix_ar[i]; + for (; cn_prefix; cn_prefix = cn_prefix->u.mod.next) + { + if (*prefix && cn_prefix->u.mod.name && + !strcmp(prefix, cn_prefix->u.mod.name)) + { + ns = cn_prefix->u.mod.value; + break; + } + else if (!*prefix && !cn_prefix->u.mod.name) + { + ns = cn_prefix->u.mod.value; + break; + } + } + } + if (!ns) + { + if (!ct->error) + { + ct->error = 15; + ct->addinfo = strdup(prefix); + } + return 0; + } + /* 3. lookup in set.NS for new prefix */ + *n_prefix = cql_lookup_value(ct, "set.", ns); + if (!*n_prefix) + { + if (!ct->error) + { + ct->error = 15; + ct->addinfo = strdup(ns); + } + return 0; + } + /* 4. lookup qualifier.prefix. */ + + cp = cn->u.st.index; + cp_dot = strchr(cp, '.'); + + *n_suffix = cp_dot ? cp_dot+1 : cp; + return ns; +} + +void cql_transform_r(cql_transform_t ct, + struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data, + struct cql_node **prefix_ar, int prefix_level) +{ + const char *ns, *n_prefix, *n_suffix; + + if (!cn) + return; + switch (cn->which) + { + case CQL_NODE_ST: + if (cn->u.st.prefixes && prefix_level < 20) + prefix_ar[prefix_level++] = cn->u.st.prefixes; + ns = cql_get_ns(ct, cn, prefix_ar, prefix_level, &n_prefix, &n_suffix); + if (ns) + { + char n_full[64]; + sprintf (n_full, "%.20s.%.40s", n_prefix, n_suffix); + + if (!strcmp(ns, "http://www.loc.gov/zing/cql/srw-indexes/v1.0/") + && !strcmp(n_suffix, "resultSet")) + { + (*pr)("@set \"", client_data); + (*pr)(cn->u.st.term, client_data); + (*pr)("\" ", client_data); + return ; + } + cql_pr_attr(ct, "qualifier.", n_full, "srw.serverChoice", + pr, client_data, 16); + } + + if (cn->u.st.relation && !strcmp(cn->u.st.relation, "=")) + cql_pr_attr(ct, "relation.", "eq", "scr", + pr, client_data, 19); + else + cql_pr_attr(ct, "relation.", cn->u.st.relation, "eq", + pr, client_data, 19); + if (cn->u.st.modifiers) + { + struct cql_node *mod = cn->u.st.modifiers; + for (; mod; mod = mod->u.mod.next) + { + cql_pr_attr(ct, "relationModifier.", mod->u.mod.value, 0, + pr, client_data, 20); + } + } + cql_pr_attr(ct, "structure.", cn->u.st.relation, 0, + pr, client_data, 24); + if (cn->u.st.relation && !strcmp(cn->u.st.relation, "all")) + { + emit_wordlist(ct, cn, pr, client_data, "and"); + } + else if (cn->u.st.relation && !strcmp(cn->u.st.relation, "any")) + { + emit_wordlist(ct, cn, pr, client_data, "or"); + } + else + { + emit_term(ct, cn->u.st.term, strlen(cn->u.st.term), + pr, client_data); + } + break; + case CQL_NODE_BOOL: + if (cn->u.bool.prefixes && prefix_level < 20) + prefix_ar[prefix_level++] = cn->u.bool.prefixes; + (*pr)("@", client_data); + (*pr)(cn->u.bool.value, client_data); + (*pr)(" ", client_data); + + cql_transform_r(ct, cn->u.bool.left, pr, client_data, + prefix_ar, prefix_level); + cql_transform_r(ct, cn->u.bool.right, pr, client_data, + prefix_ar, prefix_level); + } +} + +int cql_transform(cql_transform_t ct, + struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data) +{ + struct cql_node *prefix_ar[20], **pp; + struct cql_prop_entry *e; + + ct->error = 0; + if (ct->addinfo) + free (ct->addinfo); + ct->addinfo = 0; + + prefix_ar[0] = 0; + pp = &prefix_ar[0]; + for (e = ct->entry; e ; e = e->next) + { + if (!memcmp(e->pattern, "set.", 4)) + { + *pp = cql_node_mk_mod(e->pattern+4, e->value); + pp = &(*pp)->u.mod.next; + } + else if (!strcmp(e->pattern, "set")) + { + *pp = cql_node_mk_mod(0, e->value); + pp = &(*pp)->u.mod.next; + } + } + cql_transform_r (ct, cn, pr, client_data, prefix_ar, 1); + return ct->error; +} + + +int cql_transform_FILE(cql_transform_t ct, struct cql_node *cn, FILE *f) +{ + return cql_transform(ct, cn, cql_fputs, f); +} + +int cql_transform_buf(cql_transform_t ct, struct cql_node *cn, + char *out, int max) +{ + struct cql_buf_write_info info; + int r; + + info.off = 0; + info.max = max; + info.buf = out; + r = cql_transform(ct, cn, cql_buf_write_handler, &info); + if (info.off >= 0) + info.buf[info.off] = '\0'; + return r; +} + +int cql_transform_error(cql_transform_t ct, const char **addinfo) +{ + *addinfo = ct->addinfo; + return ct->error; +} diff --git a/cql/cqlutil.c b/cql/cqlutil.c new file mode 100644 index 0000000..6207d19 --- /dev/null +++ b/cql/cqlutil.c @@ -0,0 +1,177 @@ +/* $Id: cqlutil.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include +#include + +#include + +void cql_fputs(const char *buf, void *client_data) +{ + FILE *f = client_data; + fputs(buf, f); +} + +struct cql_node *cql_node_dup (struct cql_node *cp) +{ + struct cql_node *cn; + + if (!cp) + return 0; + switch (cp->which) + { + case CQL_NODE_ST: + cn = cql_node_mk_sc(cp->u.st.index, + cp->u.st.relation, + cp->u.st.term); + cn->u.st.modifiers = cql_node_dup(cp->u.st.modifiers); + cn->u.st.prefixes = cql_node_dup(cp->u.st.prefixes); + break; + case CQL_NODE_MOD: + cn = cql_node_mk_mod(cp->u.mod.name, + cp->u.mod.value); + cn->u.mod.next = cql_node_dup(cp->u.mod.next); + break; + case CQL_NODE_BOOL: + cn = cql_node_mk_boolean(cp->u.bool.value); + cn->u.bool.left = cql_node_dup(cp->u.bool.left); + cn->u.bool.right = cql_node_dup(cp->u.bool.right); + cn->u.bool.prefixes = cql_node_dup(cp->u.bool.prefixes); + } + return cn; +} + +struct cql_node *cql_node_mk_sc(const char *index, + const char *relation, + const char *term) +{ + struct cql_node *p = malloc(sizeof(*p)); + p->which = CQL_NODE_ST; + p->u.st.index = 0; + if (index) + p->u.st.index = strdup(index); + p->u.st.term = 0; + if (term) + p->u.st.term = strdup(term); + p->u.st.relation = 0; + if (relation) + p->u.st.relation = strdup(relation); + p->u.st.modifiers = 0; + p->u.st.prefixes = 0; + return p; +} + +struct cql_node *cql_node_mk_mod(const char *name, + const char *value) +{ + struct cql_node *p = malloc(sizeof(*p)); + p->which = CQL_NODE_MOD; + + p->u.mod.name = 0; + if (name) + p->u.mod.name = strdup(name); + p->u.mod.value = 0; + if (value) + p->u.mod.value = strdup(value); + p->u.mod.next = 0; + return p; +} + +struct cql_node *cql_node_mk_boolean(const char *op) +{ + struct cql_node *p = malloc(sizeof(*p)); + p->which = CQL_NODE_BOOL; + p->u.bool.value = 0; + if (op) + p->u.bool.value = strdup(op); + p->u.bool.left = 0; + p->u.bool.right = 0; + p->u.bool.modifiers = 0; + p->u.bool.prefixes = 0; + return p; +} + +struct cql_node *cql_node_prefix(struct cql_node *n, const char *prefix, + const char *uri) +{ + struct cql_node **cpp = 0; + if (n->which == CQL_NODE_ST) + { + cpp = &n->u.st.prefixes; + } + else if (n->which == CQL_NODE_BOOL) + { + cpp = &n->u.bool.prefixes; + } + if (cpp) + { + struct cql_node *cp = cql_node_mk_mod(prefix, uri); + cp->u.mod.next = *cpp; + *cpp = cp; + } + return n; +} + +struct cql_node *cql_node_mk_proxargs(const char *relation, + const char *distance, + const char *unit, + const char *ordering) +{ + struct cql_node *m = 0, *m1; + + if (ordering && *ordering) + m = cql_node_mk_mod("ordering", ordering); + if (unit && *unit) + { + m1 = cql_node_mk_mod("unit", unit); + m1->u.mod.next = m; + m = m1; + } + if (distance && *distance) + { + m1 = cql_node_mk_mod("distance", distance); + m1->u.mod.next = m; + m = m1; + } + if (relation && *relation) + { + m1 = cql_node_mk_mod("relation", relation); + m1->u.mod.next = m; + m = m1; + } + return m; +} + +void cql_node_destroy(struct cql_node *cn) +{ + if (!cn) + return; + switch (cn->which) + { + case CQL_NODE_ST: + free (cn->u.st.index); + free (cn->u.st.relation); + free (cn->u.st.term); + cql_node_destroy(cn->u.st.modifiers); + cql_node_destroy(cn->u.st.prefixes); + break; + case CQL_NODE_MOD: + free (cn->u.mod.name); + free (cn->u.mod.value); + cql_node_destroy(cn->u.mod.next); + break; + case CQL_NODE_BOOL: + free (cn->u.bool.value); + cql_node_destroy(cn->u.bool.left); + cql_node_destroy(cn->u.bool.right); + cql_node_destroy(cn->u.bool.prefixes); + } + free (cn); +} + diff --git a/cql/lexer.c b/cql/lexer.c new file mode 100644 index 0000000..8a26522 --- /dev/null +++ b/cql/lexer.c @@ -0,0 +1,108 @@ +/* $Id: lexer.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ +/* + * bison lexer for CQL. + */ + +int yylex(YYSTYPE *lval, void *vp) +{ + CQL_parser cp = (CQL_parser) vp; + int c; + do + { + c = cp->getbyte(cp->client_data); + if (c == 0) + return 0; + if (c == '\n') + return 0; + } while (isspace(c)); + lval->rel = 0; + lval->len = 0; + if (strchr("()=>buf[lval->len++] = c; + if (c == '>') + { + c1 = cp->getbyte(cp->client_data); + if (c1 == '=') + { + lval->buf[lval->len++] = c1; + lval->buf[lval->len] = 0; + return GE; + } + else + cp->ungetbyte(c1, cp->client_data); + } + else if (c == '<') + { + c1 = cp->getbyte(cp->client_data); + if (c1 == '=') + { + lval->buf[lval->len++] = c1; + lval->buf[lval->len] = 0; + return LE; + } + else if (c1 == '>') + { + lval->buf[lval->len++] = c1; + lval->buf[lval->len] = 0; + return NE; + } + else + cp->ungetbyte(c1, cp->client_data); + } + lval->buf[lval->len] = 0; + return c; + } + if (c == '"') + { + while ((c = cp->getbyte(cp->client_data)) != EOF && c != '"') + { + if (c == '\\') + c = cp->getbyte(cp->client_data); + lval->buf[lval->len++] = c; + } + lval->buf[lval->len] = 0; + } + else + { + lval->buf[lval->len++] = c; + while ((c = cp->getbyte(cp->client_data)) != 0 && + !strchr(" \n()=<>/", c)) + { + if (c == '\\') + c = cp->getbyte(cp->client_data); + lval->buf[lval->len++] = c; + } + lval->buf[lval->len] = 0; +#if YYDEBUG + printf ("got %s\n", lval->buf); +#endif + if (c != 0) + cp->ungetbyte(c, cp->client_data); + if (!strcmp(lval->buf, "and")) + return AND; + if (!strcmp(lval->buf, "or")) + return OR; + if (!strcmp(lval->buf, "not")) + return NOT; + if (!strcmp(lval->buf, "exact")) + return EXACT; + if (!strcmp(lval->buf, "all")) + return ALL; + if (!strncmp(lval->buf, "prox", 4)) + return PROX; + if (!strcmp(lval->buf, "any")) + return ANY; + if (!strcmp(lval->buf, "scr")) + return SCR; + } + return TERM; +} diff --git a/cql/xcqlutil.c b/cql/xcqlutil.c new file mode 100644 index 0000000..9294a02 --- /dev/null +++ b/cql/xcqlutil.c @@ -0,0 +1,210 @@ +/* $Id: xcqlutil.c,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ +#include +#include +#include + +#include + +static void pr_n(const char *buf, + void (*pr)(const char *buf, void *client_data), + void *client_data, int n) +{ + int i; + for (i = 0; i': + (*pr)(">", client_data); + break; + default: + bf[0] = *src; + bf[1] = 0; + (*pr)(bf, client_data); + } + src++; + } +} + +static void prefixes(struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data, int level) +{ + if (cn) + { + pr_n("\n", pr, client_data, level); + for (; cn; cn = cn->u.mod.next) + { + pr_n("\n", pr, client_data, level+2); + if (cn->u.mod.name) + { + pr_n("", pr, client_data, level+4); + pr_cdata(cn->u.mod.name, pr, client_data); + pr_n("\n", pr, client_data, 0); + } + if (cn->u.mod.value) + { + pr_n("", pr, client_data, level+4); + pr_cdata(cn->u.mod.value, pr, client_data); + pr_n("\n", pr, client_data, 0); + } + pr_n("\n", pr, client_data, level+2); + } + pr_n("\n", pr, client_data, level); + } +} + +static void cql_to_xml_r(struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data, int level) +{ + if (!cn) + return; + switch (cn->which) + { + case CQL_NODE_ST: + pr_n("\n", pr, client_data, level); + prefixes(cn->u.st.prefixes, pr, client_data, level+2); + if (cn->u.st.index) + { + pr_n("", pr, client_data, level+2); + pr_cdata(cn->u.st.index, pr, client_data); + pr_n("\n", pr, client_data, 0); + } + if (cn->u.st.relation) + { + struct cql_node *m = cn->u.st.modifiers; + pr_n("\n", pr, client_data, level+2); + pr_n("", pr, client_data, level+4); + pr_cdata(cn->u.st.relation, pr, client_data); + pr_n("\n", pr, client_data, 0); + if (m) + { + pr_n("\n", pr, client_data, level+4); + for (; m; m = m->u.mod.next) + { + pr_n("", pr, client_data, level+6); + pr_cdata(m->u.mod.value, pr, client_data); + pr_n("\n", pr, client_data, 0); + } + pr_n("\n", pr, client_data, level+4); + } + pr_n("\n", pr, client_data, level+2); + } + if (cn->u.st.term) + { + pr_n("", pr, client_data, level+2); + pr_cdata(cn->u.st.term, pr, client_data); + pr_n("\n", pr, client_data, 0); + } + pr_n("\n", pr, client_data, level); + break; + case CQL_NODE_BOOL: + pr_n("\n", pr, client_data, level); + prefixes(cn->u.st.prefixes, pr, client_data, level+2); + if (cn->u.bool.value) + { + struct cql_node *m = cn->u.bool.modifiers; + pr_n("\n", pr, client_data, level+2); + + pr_n("", pr, client_data, level+4); + pr_cdata(cn->u.bool.value, pr, client_data); + pr_n("\n", pr, client_data, 0); + + if (m) + { + pr_n("\n", pr, client_data, level+4); + for (; m; m = m->u.mod.next) + { + pr_n("", pr, client_data, level+6); + pr_cdata(m->u.mod.name, pr, client_data); + pr_n("", pr, client_data, 0); + if (m->u.mod.value) + { + pr_n("", pr, client_data, 0); + pr_cdata(m->u.mod.value, pr, client_data); + pr_n("", pr, client_data, 0); + } + pr_n("\n", pr, client_data, 0); + } + pr_n("\n", pr, client_data, level+4); + } + pr_n("\n", pr, client_data, level+2); + } + if (cn->u.bool.left) + { + printf ("%*s\n", level+2, ""); + cql_to_xml_r(cn->u.bool.left, pr, client_data, level+4); + printf ("%*s\n", level+2, ""); + } + if (cn->u.bool.right) + { + printf ("%*s\n", level+2, ""); + cql_to_xml_r(cn->u.bool.right, pr, client_data, level+4); + printf ("%*s\n", level+2, ""); + } + pr_n("\n", pr, client_data, level); + } +} + +void cql_to_xml(struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data) +{ + cql_to_xml_r(cn, pr, client_data, 0); +} + +void cql_to_xml_stdio(struct cql_node *cn, FILE *f) +{ + cql_to_xml(cn, cql_fputs, f); +} + +void cql_buf_write_handler (const char *b, void *client_data) +{ + struct cql_buf_write_info *info = client_data; + int l = strlen(b); + if (info->off < 0 || (info->off + l >= info->max)) + { + info->off = -1; + return; + } + memcpy (info->buf + info->off, b, l); + info->off += l; +} + +int cql_to_xml_buf(struct cql_node *cn, char *out, int max) +{ + struct cql_buf_write_info info; + info.off = 0; + info.max = max; + info.buf = out; + cql_to_xml(cn, cql_buf_write_handler, &info); + if (info.off >= 0) + info.buf[info.off] = '\0'; + return info.off; +} + diff --git a/debian/rules b/debian/rules index 4370644..f33c5cc 100755 --- a/debian/rules +++ b/debian/rules @@ -12,7 +12,7 @@ export DH_COMPAT=2 YAZ_WITH_SSL?=1 -CONFIG_FLAGS=--enable-static --enable-shared --enable-tcpd --prefix=/usr +CONFIG_FLAGS=--without-gsoap --enable-static --enable-shared --enable-tcpd --prefix=/usr # Enable parallel builds if CONCURRENCY_LEVEL is set ifdef CONCURRENCY_LEVEL diff --git a/etc/MARC21slim2DC.xsl b/etc/MARC21slim2DC.xsl new file mode 100644 index 0000000..75f92ab --- /dev/null +++ b/etc/MARC21slim2DC.xsl @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + abfghk + + + + + + + + + + + + + + yes + + + + yes + + + + text + cartographic + notated music + sound recording + still image + moving image + three dimensional object + software, multimedia + mixed material + + + + + + + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcd + + + + + + + + abcdu + + + + + + + + ot + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/MARC21slim2MODS.xsl b/etc/MARC21slim2MODS.xsl new file mode 100644 index 0000000..ff35524 --- /dev/null +++ b/etc/MARC21slim2MODS.xsl @@ -0,0 +1,1873 @@ + + + + + + + + + + + + + + + + + + + + + + + BK + SE + + + BK + MM + CF + MP + VM + MU + + + + + + + + + + abfghk + + + + + + + + + + + <xsl:value-of select="substring($title,@ind2+1)"/> + + + + + <xsl:value-of select="$title"/> + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">ab</xsl:with-param> + </xsl:call-template> + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">abh</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">abfh</xsl:with-param> + </xsl:call-template> + + + + + + + + + <xsl:variable name="str"> + <xsl:for-each select="marc:subfield"> + <xsl:if test="(contains('adfhklmor',@code) and (not(../marc:subfield[@code='n' or @code='p']) or (following-sibling::marc:subfield[@code='n' or @code='p'])))"> + <xsl:value-of select="text()"/><xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each> + </xsl:variable> + <xsl:value-of select="substring($str,1,string-length($str)-1)"/> + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">ah</xsl:with-param> + </xsl:call-template> + + + + + + + + + + creator + + + + + + + + + creator + + + + + + + + creator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + personal + + + + + + + + + + + yes + + + yes + + + + text + cartographic + notated music + sound recording + still image + moving image + three dimensional object + software, multimedia + mixed material + + + + + globe + + + + remote sensing image + + + + + + + map + + + atlas + + + + + + + + + database + + + loose-leaf + + + series + + + newspaper + + + periodical + + + web site + + + + + + + + + abstract or summary + + + bibliography + + + catalog + + + dictionary + + + encyclopedia + + + handbook + + + legal article + + + index + + + discography + + + legislation + + + theses + + + survey of literature + + + review + + + programmed text + + + filmography + + + directory + + + statistics + + + technical report + + + legal case and case notes + + + law report or digest + + + treaty + + + + + + conference publication + + + + + + + + + numeric data + + + database + + + font + + + game + + + + + + + patent + + + festschrift + + + + + biography + + + + + + essay + + + drama + + + comic strip + + + fiction + + + humor, satire + + + letter + + + novel + + + short story + + + speech + + + + + + + + biography + + + conference publication + + + drama + + + essay + + + fiction + + + folktale + + + history + + + humor, satire + + + memoir + + + poetry + + + rehersal + + + reporting + + + sound + + + speech + + + + + + + + art original + + + kit + + + art reproduction + + + diorama + + + filmstrip + + + legal article + + + picture + + + graphic + + + technical drawing + + + motion picture + + + chart + + + flash card + + + microscope slide + + + model + + + realia + + + slide + + + transparency + + + videorecording + + + toy + + + + + + + + + + + abvxyz + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + monographic + continuing + + + + + + + + ab + + + + + + + + + + + + rfc3066 + + + iso639-2b + + + + + + + + + + + + + + + + + reformatted digital + + + + + + + + + + + + + + + + + + + +
braille
+
+ +
electronic
+
+ +
microfiche
+
+ +
microfilm
+
+
+ + + + + + + + +
+ + + +
+
+ + + + + abce + + + +
+ + + + + + + + + + + + ab + + + + + + + + + agrt + + + + + + + + ab + + + + + + + + + adolescent + + + adult + + + general + + + juvenile + + + preschool + + + specialized + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + defg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + abx + + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + <xsl:call-template name="part"/> + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">av</xsl:with-param> + </xsl:call-template> + <xsl:call-template name="part"/> + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + abcq + t + g + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + <xsl:value-of select="marc:subfield[@code='a']"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + + + abcq + t + g + + + + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklmorsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">dg</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + c + t + dgn + + + + + + + + + + + + + + + + + <xsl:call-template name="specialSubfieldSelect"> + <xsl:with-param name="anyCodes">tfklsv</xsl:with-param> + <xsl:with-param name="axis">t</xsl:with-param> + <xsl:with-param name="afterCodes">g</xsl:with-param> + </xsl:call-template> + + + + + + + aqdc + t + gn + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfgklmorsv</xsl:with-param> + </xsl:call-template> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + issue number + matrix number + music plate + music publisher + videorecording identifier + + + + ab + + + + + + + + ab + + + + + + + + + doi + uri + + + + + + + + + + + + + + + + abj + + + + + + + + abcd35 + + + + + + + + abcde35 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + n + n + fghkdlmor + + + + + p + p + fghkdlmor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdn + + + + + + + + + + + abcq + + + + + + + + + + + acdeq + + + + + + + + constituent + related + + + + + + + + + <xsl:value-of select="."/> + + + + + + + + + + <xsl:value-of select="."/> + + + + + + + + + + + + + + + + + + + + + + + + lcsh + lcshac + mesh + csh + nal + rvm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + abcq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cdnp + + + + + + + + + + + + + + + + abcdeqnp + + + + + + + + + + + + + + + + + + <xsl:call-template name="subfieldSelect"> + <xsl:with-param name="codes">adfhklor</xsl:with-param> + </xsl:call-template> + <xsl:call-template name="part"/> + + + + + + + + + + + + + + abcd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/etc/MARC21slim2RDFDC.xsl b/etc/MARC21slim2RDFDC.xsl new file mode 100644 index 0000000..2e81677 --- /dev/null +++ b/etc/MARC21slim2RDFDC.xsl @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + abfghk + + + + + + + + + + + + + + yes + + + + yes + + + + text + cartographic + notated music + sound recording + still image + moving image + three dimensional object + software, multimedia + mixed material + + + + + + + + + + + + + ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcdq + + + + + + + + abcd + + + + + + + + abcdu + + + + + + + + ot + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/etc/MARC21slimUtils.xsl b/etc/MARC21slimUtils.xsl new file mode 100644 index 0000000..acfe598 --- /dev/null +++ b/etc/MARC21slimUtils.xsl @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/etc/Makefile.am b/etc/Makefile.am new file mode 100644 index 0000000..fa4b417 --- /dev/null +++ b/etc/Makefile.am @@ -0,0 +1,9 @@ +# $Id: Makefile.am,v 1.1 2003-01-06 08:20:27 adam Exp $ + +EXTRA_DIST=maps.xml \ + MARC21slim2DC.xsl \ + MARC21slim2MODS.xsl \ + MARC21slim2RDFDC.xsl \ + MARC21slimUtils.xsl \ + pqf.properties + diff --git a/etc/maps.xml b/etc/maps.xml new file mode 100644 index 0000000..72c7227 --- /dev/null +++ b/etc/maps.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/pqf.properties b/etc/pqf.properties new file mode 100644 index 0000000..76f046b --- /dev/null +++ b/etc/pqf.properties @@ -0,0 +1,111 @@ +# $Id: pqf.properties,v 1.1 2003-01-06 08:20:27 adam Exp $ +# +# Propeties file to drive org.z3950.zing.cql.CQLNode's toPQF() +# back-end. This specifies the interpretation of various CQL +# qualifiers, relations, etc. in terms of Type-1 query attributes. +# +# See http://www.loc.gov/z3950/agency/zing/cql/dc-indexes.html +# for the Maintenance Agency's work-in-progress mapping of Dublic Core +# qualifiers to Attribute Architecture (util, XD and BIB-2) +# attributes. + +# Identifiers for prefixes used in this file. (qualifier.*) +set.srw = http://www.loc.gov/zing/cql/srw-indexes/v1.0/ +set.dc = http://www.loc.gov/zing/cql/dc-indexes/v1.0/ +# default set (in query) +set = http://www.loc.gov/zing/cql/dc-indexes/v1.0/ + +# The default access point and result-set references +qualifier.srw.serverChoice = 1=1016 + # "any" + +qualifier.dc.title = 1=4 +qualifier.dc.subject = 1=21 +qualifier.dc.creator = 1=1003 +qualifier.dc.author = 1=1003 + ### Unofficial synonym for "creator" +qualifier.dc.editor = 1=1020 +qualifier.dc.publisher = 1=1018 +qualifier.dc.description = 1=62 + # "abstract" +qualifier.dc.date = 1=30 +qualifier.dc.resourceType = 1=1031 + # guesswork: "Material-type" +qualifier.dc.format = 1=1034 + # guesswork: "Content-type" +qualifier.dc.resourceIdentifier = 1=12 + # "Local number" +qualifier.dc.source = 1=1019 + # "Record-source" +qualifier.dc.language = 1=54 + # "Code--language" +qualifier.dc.relation = 1=? + ### No idea how to represent this +qualifier.dc.coverage = 1=? + ### No idea how to represent this +qualifier.dc.rights = 1=? + ### No idea how to represent this + +### These aren't right: I've just put them here for the Generator +qualifier.bath.subject = 1=21 +qualifier.bath.author = 1=1003 +qualifier.foo>bar = 1=2000 + +# Relation attributes are selected according to the CQL relation by +# looking up the "relation." property: +# +relation.< = 2=1 +relation.le = 2=2 +relation.eq = 2=3 +relation.exact = 2=3 +relation.ge = 2=4 +relation.> = 2=5 +relation.<> = 2=6 + +### These two are not really right: +relation.all = 2=3 +relation.any = 2=3 + +# BIB-1 doesn't have a server choice relation, so we just make the +# choice here, and use equality (which is clearly correct). +relation.scr = 2=3 + +# Relation modifiers. +# +relationModifier.relevant = 2=102 +relationModifier.fuzzy = 2=100 + ### 100 is "phonetic", which is not quite the same thing +relationModifier.stem = 2=101 +relationModifier.phonetic = 2=100 + +# Position attributes may be specified for anchored terms (those +# beginning with "^", which is stripped) and unanchored (those not +# beginning with "^"). This may change when we get a BIB-1 truncation +# attribute that says "do what CQL does". +# +position.first = 3=1 6=1 + # "first in field" +position.any = 3=3 6=1 + # "any position in field" +position.last = 3=4 6=1 + # not a standard BIB-1 attribute +position.firstAndLast = 3=3 6=3 + # search term is anchored to be complete field + +# Structure attributes may be specified for individual relations; a +# default structure attribute my be specified by the pseudo-relation +# "*", to be used whenever a relation not listed here occurs. +# +structure.exact = 4=108 + # string +structure.all = 4=2 +structure.any = 4=2 +structure.* = 4=1 + # phrase + +# Finally, any additional attributes that should always be included +# with each term can be specified in the "always" property. +# +always = 5=105 6=1 +# 5=105: the not-yet-standarised CQL-like trunction attribute +# 6=1: completeness = incomplete subfield diff --git a/include/yaz/Makefile.am b/include/yaz/Makefile.am index 275489a..5bf7713 100644 --- a/include/yaz/Makefile.am +++ b/include/yaz/Makefile.am @@ -1,8 +1,8 @@ -## $Id: Makefile.am,v 1.18 2002-12-16 13:13:53 adam Exp $ +## $Id: Makefile.am,v 1.19 2003-01-06 08:20:27 adam Exp $ -pkginclude_HEADERS= backend.h ccl.h comstack.h \ +pkginclude_HEADERS= backend.h ccl.h cql.h comstack.h \ diagbib1.h sortspec.h log.h logrpn.h marcdisp.h nmem.h odr.h oid.h \ - options.h otherinfo.h pquery.h prt-ext.h readconf.h statserv.h \ + options.h otherinfo.h pquery.h prt-ext.h readconf.h srw-util.h statserv.h \ tcpip.h unix.h tpath.h wrbuf.h xmalloc.h \ yaz-ccl.h yaz-iconv.h yaz-util.h yaz-version.h yconfig.h proto.h \ \ diff --git a/include/yaz/backend.h b/include/yaz/backend.h index 866b468..27343c2 100644 --- a/include/yaz/backend.h +++ b/include/yaz/backend.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: backend.h,v 1.16 2002-09-16 10:48:06 adam Exp $ + * $Id: backend.h,v 1.17 2003-01-06 08:20:27 adam Exp $ */ #ifndef BACKEND_H diff --git a/include/yaz/cql.h b/include/yaz/cql.h new file mode 100644 index 0000000..9ae7b6b --- /dev/null +++ b/include/yaz/cql.h @@ -0,0 +1,199 @@ +/* $Id: cql.h,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#ifndef CQL_H_INCLUDED +#define CQL_H_INCLUDED +#include + +typedef struct cql_parser *CQL_parser; + +/** + * cql_parser_create: + * + * creates a CQL parser. + * + * Returns CQL parser or NULL if parser could not be created. + */ +CQL_parser cql_parser_create(void); + +/** + * cql_parser_destroy: + * @cp: A CQL parser + * + * Destroy CQL parser. This function does nothing if + * NULL pointer is received. + */ +void cql_parser_destroy(CQL_parser cp); + +/** + * cql_parser_string: + * @cp: A CQL parser. + * @str: A query string to be parsed. + * + * Parses a CQL query string. + * + * Returns 0 if parsing was succesful; non-zero (error code) if + * unsuccesful. + */ +int cql_parser_string(CQL_parser cp, const char *str); + +/** + * cql_parser_stream: + * @cp: A CQL parser. + * @getbyte: Handler to read one character (for parsing). + * @ungetbyte: Handler to unread one byte (for parsing). + * @client_data: User data associated with getbyte/ungetbyte handlers. + * + * Parses a CQL query from a user defined stream. + * + * Returns 0 if parsing was succesful; non-zero (error code) if + * unsuccesful. + */ +int cql_parser_stream(CQL_parser cp, + int (*getbyte)(void *client_data), + void (*ungetbyte)(int b, void *client_data), + void *client_data); + +/** + * cql_parser_stdio: + * @cp: A CQL parser. + * @f: FILE handler in read mode. + * + * Parses a CQL query from a file. + * + * Returns 0 if parsing was succesful; non-zero (error code) if + * unsuccesful. + */ +int cql_parser_stdio(CQL_parser cp, FILE *f); + +#define CQL_NODE_ST 1 +#define CQL_NODE_BOOL 2 +#define CQL_NODE_MOD 3 +struct cql_node { + int which; + union { + struct { + char *index; + char *term; + char *relation; + struct cql_node *modifiers; + struct cql_node *prefixes; + } st; + struct { + char *value; + struct cql_node *left; + struct cql_node *right; + struct cql_node *modifiers; + struct cql_node *prefixes; + } bool; + struct { + char *name; + char *value; + struct cql_node *next; + } mod; + } u; +}; + +struct cql_properties; + +struct cql_buf_write_info { + int max; + int off; + char *buf; +}; + +void cql_buf_write_handler (const char *b, void *client_data); + +void cql_node_print(struct cql_node *cn); +struct cql_node *cql_node_mk_sc(const char *index, + const char *relation, + const char *term); +struct cql_node *cql_node_mk_boolean(const char *op); +void cql_node_destroy(struct cql_node *cn); +struct cql_node *cql_node_prefix(struct cql_node *n, const char *prefix, + const char *uri); +struct cql_node *cql_node_mk_mod(const char *name, + const char *value); + +struct cql_node *cql_node_dup (struct cql_node *cp); +struct cql_node *cql_parser_result(CQL_parser cp); + +void cql_to_xml(struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data); +void cql_to_xml_stdio(struct cql_node *cn, FILE *f); +int cql_to_xml_buf(struct cql_node *cn, char *out, int max); + +struct cql_node *cql_node_mk_proxargs(const char *relation, + const char *distance, + const char *unit, + const char *ordering); + + +void cql_fputs(const char *buf, void *client_data); + +typedef struct cql_transform_t_ *cql_transform_t; + +cql_transform_t cql_transform_open_FILE (FILE *f); +cql_transform_t cql_transform_open_fname(const char *fname); +void cql_transform_close(cql_transform_t ct); + +void cql_transform_pr(cql_transform_t ct, + struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data); + +int cql_transform_FILE(cql_transform_t ct, + struct cql_node *cn, FILE *f); + +int cql_transform_buf(cql_transform_t ct, + struct cql_node *cn, char *out, int max); +int cql_transform_error(cql_transform_t ct, const char **addinfo); + +/* +10 Illegal query +11 Unsupported query type (XCQL vs CQL) +12 Too many characters in query +13 Unbalanced or illegal use of parentheses +14 Unbalanced or illegal use of quotes +15 Illegal or unsupported index set +16 Illegal or unsupported index +17 Illegal or unsupported combination of index and index set +18 Illegal or unsupported combination of indexes +19 Illegal or unsupported relation +20 Illegal or unsupported relation modifier +21 Illegal or unsupported combination of relation modifers +22 Illegal or unsupported combination of relation and index +23 Too many characters in term +24 Illegal combination of relation and term +25 Special characters not quoted in term +26 Non special character escaped in term +27 Empty term unsupported +28 Masking character not supported +29 Masked words too short +30 Too many masking characters in term +31 Anchoring character not supported +32 Anchoring character in illegal or unsupported position +33 Combination of proximity/adjacency and masking characters not supported +34 Combination of proximity/adjacency and anchoring characters not supported +35 Terms only exclusion (stop) words +36 Term in invalid format for index or relation +37 Illegal or unsupported boolean operator +38 Too many boolean operators in query +39 Proximity not supported +40 Illegal or unsupported proximity relation +41 Illegal or unsupported proximity distance +42 Illegal or unsupported proximity unit +43 Illegal or unsupported proximity ordering +44 Illegal or unsupported combination of proximity modifiers +45 Index set name (prefix) assigned to multiple identifiers +*/ + +#endif +/* CQL_H_INCLUDED */ diff --git a/include/yaz/log.h b/include/yaz/log.h index 6b41af3..6925d78 100644 --- a/include/yaz/log.h +++ b/include/yaz/log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: log.h,v 1.7 2002-08-29 09:58:42 adam Exp $ + * $Id: log.h,v 1.8 2003-01-06 08:20:27 adam Exp $ */ #ifndef LOG_H diff --git a/include/yaz/logrpn.h b/include/yaz/logrpn.h index e5e7552..d1f4c07 100644 --- a/include/yaz/logrpn.h +++ b/include/yaz/logrpn.h @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: logrpn.h,v $ - * Revision 1.2 2000-02-28 11:20:06 adam + * Revision 1.3 2003-01-06 08:20:27 adam + * SRW, CQL, 2003 + * + * Revision 1.2 2000/02/28 11:20:06 adam * Using autoconf. New definitions: YAZ_BEGIN_CDECL/YAZ_END_CDECL. * * Revision 1.1 1999/11/30 13:47:11 adam @@ -26,6 +29,7 @@ YAZ_BEGIN_CDECL YAZ_EXPORT void log_rpn_query (Z_RPNQuery *rpn); YAZ_EXPORT void log_scan_term (Z_AttributesPlusTerm *zapt, oid_value ast); +YAZ_EXPORT void yaz_log_zquery (Z_Query *q); YAZ_END_CDECL diff --git a/include/yaz/marcdisp.h b/include/yaz/marcdisp.h index 3760a2f..afbe121 100644 --- a/include/yaz/marcdisp.h +++ b/include/yaz/marcdisp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: marcdisp.h,v 1.7 2002-12-16 13:13:53 adam Exp $ + * $Id: marcdisp.h,v 1.8 2003-01-06 08:20:27 adam Exp $ */ #ifndef MARCDISP_H diff --git a/include/yaz/nmem.h b/include/yaz/nmem.h index 1a0a260..2a11b2b 100644 --- a/include/yaz/nmem.h +++ b/include/yaz/nmem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: nmem.h,v 1.9 2002-12-05 12:19:23 adam Exp $ + * $Id: nmem.h,v 1.10 2003-01-06 08:20:27 adam Exp $ */ #ifndef NMEM_H diff --git a/include/yaz/odr.h b/include/yaz/odr.h index 895d635..629b7f6 100644 --- a/include/yaz/odr.h +++ b/include/yaz/odr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: odr.h,v 1.6 2002-07-25 12:51:08 adam Exp $ + * $Id: odr.h,v 1.7 2003-01-06 08:20:27 adam Exp $ */ #ifndef ODR_H diff --git a/include/yaz/oid.h b/include/yaz/oid.h index e418f6c..d9f18df 100644 --- a/include/yaz/oid.h +++ b/include/yaz/oid.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: oid.h,v 1.12 2002-08-30 15:39:40 mike Exp $ + * $Id: oid.h,v 1.13 2003-01-06 08:20:27 adam Exp $ */ #ifndef OID_H @@ -209,6 +209,7 @@ typedef enum oid_value VAL_IDXPATH, VAL_BIB2, VAL_ZEEREX, + VAL_CQL, /* VAL_DYNAMIC must have highest value */ VAL_DYNAMIC, diff --git a/include/yaz/pquery.h b/include/yaz/pquery.h index 5237b7e..bbb6975 100644 --- a/include/yaz/pquery.h +++ b/include/yaz/pquery.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: pquery.h,v 1.3 2002-09-02 13:59:07 adam Exp $ + * $Id: pquery.h,v 1.4 2003-01-06 08:20:27 adam Exp $ */ #ifndef PQUERY_H diff --git a/include/yaz/proto.h b/include/yaz/proto.h index 2350c57..cf3858b 100644 --- a/include/yaz/proto.h +++ b/include/yaz/proto.h @@ -1,9 +1,9 @@ /* - * Copyright (c) 1998-2002, Index Data + * Copyright (c) 1998-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: proto.h,v 1.5 2002-12-05 12:07:00 adam Exp $ + * $Id: proto.h,v 1.6 2003-01-06 08:20:27 adam Exp $ */ #ifndef Z_PROTO_H #define Z_PROTO_H diff --git a/include/yaz/prt-ext.h b/include/yaz/prt-ext.h index 9bfd485..48bacb1 100644 --- a/include/yaz/prt-ext.h +++ b/include/yaz/prt-ext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -85,6 +85,7 @@ struct Z_External #define Z_External_acfDes1 24 #define Z_External_acfKrb1 25 #define Z_External_multisrch2 26 +#define Z_External_CQL 27 union { /* Generic types */ @@ -122,6 +123,7 @@ struct Z_External Z_KRBObject *acfKrb1; Z_MultipleSearchTerms_2 *multipleSearchTerms_2; + Z_InternationalString *cql; } u; }; diff --git a/include/yaz/srw-util.h b/include/yaz/srw-util.h new file mode 100644 index 0000000..6e03390 --- /dev/null +++ b/include/yaz/srw-util.h @@ -0,0 +1,48 @@ +/* $Id: srw-util.h,v 1.1 2003-01-06 08:20:27 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include "srw_H.h" +#include +struct cql_node *xcql_to_cqlnode(struct xcql__operandType *p); + +typedef struct xslt_maps_info *xslt_maps; +typedef struct xslt_map_result_info *xslt_map_result; + +xslt_maps xslt_maps_create(void); +int xslt_maps_file(xslt_maps m, const char *f); +void xslt_maps_free(xslt_maps m); + +xslt_map_result xslt_map (xslt_maps m, const char *schema_source, + const char *scheme_target, + const char *in_buf, int in_len); +void xslt_map_free (xslt_map_result res); + +char *xslt_map_result_buf(xslt_map_result res); +int xslt_map_result_len(xslt_map_result res); +char *xslt_map_result_schema(xslt_map_result res); +const char *yaz_srw_diag_str (int code); + +void yaz_srw_serve (struct soap *soap, + void *userinfo, + int (*sr_h)(void *userinfo, + struct soap * soap, + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *res), + int (*e_h)(void *userinfo, + struct soap *soap, + struct zs__explainResponse *explainResponse)); + +extern struct Namespace srw_namespaces[]; diff --git a/include/yaz/tpath.h b/include/yaz/tpath.h index 5f9e907..e6b240e 100644 --- a/include/yaz/tpath.h +++ b/include/yaz/tpath.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: tpath.h,v 1.4 2002-04-05 12:46:07 adam Exp $ + * $Id: tpath.h,v 1.5 2003-01-06 08:20:27 adam Exp $ * */ diff --git a/include/yaz/unix.h b/include/yaz/unix.h index 93998af..7b7054b 100644 --- a/include/yaz/unix.h +++ b/include/yaz/unix.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: unix.h,v 1.1 2002-06-04 11:36:11 adam Exp $ + * $Id: unix.h,v 1.2 2003-01-06 08:20:27 adam Exp $ * UNIX socket COMSTACK. By Morten Bøgeskov. * */ diff --git a/include/yaz/wrbuf.h b/include/yaz/wrbuf.h index 79c568d..3b6258d 100644 --- a/include/yaz/wrbuf.h +++ b/include/yaz/wrbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: wrbuf.h,v 1.7 2002-12-03 10:03:27 adam Exp $ + * $Id: wrbuf.h,v 1.8 2003-01-06 08:20:27 adam Exp $ * */ diff --git a/include/yaz/yaz-iconv.h b/include/yaz/yaz-iconv.h index 5b4dd5f..a039280 100644 --- a/include/yaz/yaz-iconv.h +++ b/include/yaz/yaz-iconv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: yaz-iconv.h,v 1.1 2002-12-16 13:13:53 adam Exp $ + * $Id: yaz-iconv.h,v 1.2 2003-01-06 08:20:27 adam Exp $ */ #ifndef YAZ_ICONV_H diff --git a/include/yaz/yaz-util.h b/include/yaz/yaz-util.h index bbba458..8db1ed7 100644 --- a/include/yaz/yaz-util.h +++ b/include/yaz/yaz-util.h @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: yaz-util.h,v 1.7 2002-12-16 13:13:53 adam Exp $ + * $Id: yaz-util.h,v 1.8 2003-01-06 08:20:27 adam Exp $ */ #ifndef YAZ_UTIL_H diff --git a/include/yaz/zoom.h b/include/yaz/zoom.h index f0a9b74..956bd51 100644 --- a/include/yaz/zoom.h +++ b/include/yaz/zoom.h @@ -1,6 +1,6 @@ /* * Public header for ZOOM C. - * $Id: zoom.h,v 1.15 2002-12-09 23:32:29 adam Exp $ + * $Id: zoom.h,v 1.16 2003-01-06 08:20:27 adam Exp $ */ #include @@ -92,6 +92,7 @@ ZOOM_diag_str (int error); #define ZOOM_ERROR_INIT 10005 #define ZOOM_ERROR_INTERNAL 10006 #define ZOOM_ERROR_TIMEOUT 10007 +#define ZOOM_ERROR_UNSUPPORTED_PROTOCOL 10008 ZOOM_API(int) ZOOM_connection_last_event(ZOOM_connection cs); @@ -166,7 +167,10 @@ ZOOM_query_create(void); /* destroy it */ ZOOM_API(void) ZOOM_query_destroy(ZOOM_query s); -/* specify prefix query for search */ +/* CQL */ +ZOOM_API(int) +ZOOM_query_cql(ZOOM_query s, const char *str); +/* PQF */ ZOOM_API(int) ZOOM_query_prefix(ZOOM_query s, const char *str); /* specify sort criteria for search */ diff --git a/lib/Makefile.am b/lib/Makefile.am index ca46b69..8fd9e3b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,10 @@ -## $Id: Makefile.am,v 1.24 2002-10-22 12:51:18 adam Exp $ +## $Id: Makefile.am,v 1.25 2003-01-06 08:20:27 adam Exp $ + +if SRW +libsrw=../srw/libsrw.la +else +libsrw= +endif if ISTHR extra=libyazthread.la @@ -74,6 +80,6 @@ tcpip.o: $(top_srcdir)/comstack/tcpip.c libyaz_la_LIBADD=../odr/libodr.la \ ../comstack/libcomstack.la ../server/libserver.la \ - ../util/libutil.la ../ccl/libccl.la ../zutil/libzutil.la \ - ../ill/libill.la ../z39.50/libz39.50.la + ../util/libutil.la ../ccl/libccl.la ../cql/libcql.la ../zutil/libzutil.la \ + ../ill/libill.la ../z39.50/libz39.50.la $(libsrw) diff --git a/odr/ber_any.c b/odr/ber_any.c index 6ae67d0..1280040 100644 --- a/odr/ber_any.c +++ b/odr/ber_any.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: ber_any.c,v 1.19 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_any.c,v 1.20 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/ber_bit.c b/odr/ber_bit.c index 1733226..e82c2d5 100644 --- a/odr/ber_bit.c +++ b/odr/ber_bit.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_bit.c,v 1.13 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_bit.c,v 1.14 2003-01-06 08:20:27 adam Exp $ * */ #if HAVE_CONFIG_H diff --git a/odr/ber_bool.c b/odr/ber_bool.c index 289d681..20a8a35 100644 --- a/odr/ber_bool.c +++ b/odr/ber_bool.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_bool.c,v 1.12 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_bool.c,v 1.13 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/odr/ber_int.c b/odr/ber_int.c index 6fa7a41..e5a59ab 100644 --- a/odr/ber_int.c +++ b/odr/ber_int.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_int.c,v 1.20 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_int.c,v 1.21 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/ber_len.c b/odr/ber_len.c index 6fd3f9b..88602bd 100644 --- a/odr/ber_len.c +++ b/odr/ber_len.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 1995-2002, Index Data. + * Copyright (C) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_len.c,v 1.10 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_len.c,v 1.11 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/ber_null.c b/odr/ber_null.c index bd334c9..a883a81 100644 --- a/odr/ber_null.c +++ b/odr/ber_null.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_null.c,v 1.12 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_null.c,v 1.13 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/ber_oct.c b/odr/ber_oct.c index 4f04960..e2ba432 100644 --- a/odr/ber_oct.c +++ b/odr/ber_oct.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_oct.c,v 1.19 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_oct.c,v 1.20 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/ber_oid.c b/odr/ber_oid.c index 0f48b31..0f744fa 100644 --- a/odr/ber_oid.c +++ b/odr/ber_oid.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_oid.c,v 1.13 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_oid.c,v 1.14 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/ber_tag.c b/odr/ber_tag.c index 61a6872..9172075 100644 --- a/odr/ber_tag.c +++ b/odr/ber_tag.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: ber_tag.c,v 1.23 2002-07-25 12:51:08 adam Exp $ + * $Id: ber_tag.c,v 1.24 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/dumpber.c b/odr/dumpber.c index 1fbdecf..de57132 100644 --- a/odr/dumpber.c +++ b/odr/dumpber.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: dumpber.c,v 1.13 2002-07-25 12:51:08 adam Exp $ + * $Id: dumpber.c,v 1.14 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr-priv.h b/odr/odr-priv.h index d8ad03c..0c60940 100644 --- a/odr/odr-priv.h +++ b/odr/odr-priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: odr-priv.h,v 1.2 2002-08-28 07:53:51 adam Exp $ + * $Id: odr-priv.h,v 1.3 2003-01-06 08:20:27 adam Exp $ */ #ifndef ODR_PRIV_H diff --git a/odr/odr.c b/odr/odr.c index a0f34e1..22f9b21 100644 --- a/odr/odr.c +++ b/odr/odr.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: odr.c,v 1.38 2002-09-24 08:05:41 adam Exp $ + * $Id: odr.c,v 1.39 2003-01-06 08:20:27 adam Exp $ * */ #if HAVE_CONFIG_H diff --git a/odr/odr_any.c b/odr/odr_any.c index 3c5c067..aa5b08f 100644 --- a/odr/odr_any.c +++ b/odr/odr_any.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_any.c,v 1.11 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_any.c,v 1.12 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_bit.c b/odr/odr_bit.c index aa10414..0a1426f 100644 --- a/odr/odr_bit.c +++ b/odr/odr_bit.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_bit.c,v 1.15 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_bit.c,v 1.16 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_bool.c b/odr/odr_bool.c index 597293c..f1cb60a 100644 --- a/odr/odr_bool.c +++ b/odr/odr_bool.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_bool.c,v 1.13 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_bool.c,v 1.14 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_choice.c b/odr/odr_choice.c index d752714..15ef87c 100644 --- a/odr/odr_choice.c +++ b/odr/odr_choice.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_choice.c,v 1.20 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_choice.c,v 1.21 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_cons.c b/odr/odr_cons.c index 0bda85a..b02842b 100644 --- a/odr/odr_cons.c +++ b/odr/odr_cons.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: odr_cons.c,v 1.23 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_cons.c,v 1.24 2003-01-06 08:20:27 adam Exp $ * */ #if HAVE_CONFIG_H diff --git a/odr/odr_enum.c b/odr/odr_enum.c index b60014b..8dc6e84 100644 --- a/odr/odr_enum.c +++ b/odr/odr_enum.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_enum.c,v 1.6 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_enum.c,v 1.7 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_int.c b/odr/odr_int.c index 3637174..04ffbee 100644 --- a/odr/odr_int.c +++ b/odr/odr_int.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_int.c,v 1.16 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_int.c,v 1.17 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_mem.c b/odr/odr_mem.c index 9b2c7cc..a032d4b 100644 --- a/odr/odr_mem.c +++ b/odr/odr_mem.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: odr_mem.c,v 1.20 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_mem.c,v 1.21 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_null.c b/odr/odr_null.c index 8158421..76e3b05 100644 --- a/odr/odr_null.c +++ b/odr/odr_null.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_null.c,v 1.14 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_null.c,v 1.15 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_oct.c b/odr/odr_oct.c index b1c400d..73b7088 100644 --- a/odr/odr_oct.c +++ b/odr/odr_oct.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_oct.c,v 1.19 2002-09-24 08:05:41 adam Exp $ + * $Id: odr_oct.c,v 1.20 2003-01-06 08:20:27 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_oid.c b/odr/odr_oid.c index cbb968e..5081f73 100644 --- a/odr/odr_oid.c +++ b/odr/odr_oid.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_oid.c,v 1.17 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_oid.c,v 1.18 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_seq.c b/odr/odr_seq.c index 191b97e..c23614b 100644 --- a/odr/odr_seq.c +++ b/odr/odr_seq.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_seq.c,v 1.28 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_seq.c,v 1.29 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/odr/odr_tag.c b/odr/odr_tag.c index 288403b..6fa0eb4 100644 --- a/odr/odr_tag.c +++ b/odr/odr_tag.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_tag.c,v 1.12 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_tag.c,v 1.13 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_use.c b/odr/odr_use.c index 972d5f7..5ae1e9c 100644 --- a/odr/odr_use.c +++ b/odr/odr_use.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: odr_use.c,v 1.12 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_use.c,v 1.13 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/odr/odr_util.c b/odr/odr_util.c index 5f7d7e5..3f450ca 100644 --- a/odr/odr_util.c +++ b/odr/odr_util.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: odr_util.c,v 1.21 2002-07-25 12:51:08 adam Exp $ + * $Id: odr_util.c,v 1.22 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/server/seshigh.c b/server/seshigh.c index 90b1a70..59361f5 100644 --- a/server/seshigh.c +++ b/server/seshigh.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.132 2002-09-25 12:37:07 adam Exp $ + * $Id: seshigh.c,v 1.133 2003-01-06 08:20:28 adam Exp $ */ /* @@ -1047,11 +1047,8 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb, for (i = 0; i < req->num_databaseNames; i++) yaz_log (LOG_LOG, "Database '%s'", req->databaseNames[i]); } - switch (req->query->which) - { - case Z_Query_type_1: case Z_Query_type_101: - log_rpn_query (req->query->u.type_1); - } + yaz_log_zquery(req->query); + if (assoc->init->bend_search) { bsrr->setname = req->resultSetName; @@ -1593,7 +1590,7 @@ int bend_backend_respond (bend_association a, bend_request req) int r; r = process_request (a, req, &msg); if (r < 0) - logf (LOG_WARN, "%s", msg); + yaz_log (LOG_WARN, "%s", msg); return r; } diff --git a/server/session.h b/server/session.h index 45d5cb0..6e8f8b0 100644 --- a/server/session.h +++ b/server/session.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 1995-2002, Index Data + * Copyright (C) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: session.h,v 1.26 2002-11-26 13:15:42 adam Exp $ + * $Id: session.h,v 1.27 2003-01-06 08:20:28 adam Exp $ */ #ifndef SESSION_H diff --git a/server/statserv.c b/server/statserv.c index c694443..5922a2b 100644 --- a/server/statserv.c +++ b/server/statserv.c @@ -1,12 +1,12 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * * NT threaded server code by * Chas Woodfield, Fretwell Downing Informatics. * - * $Id: statserv.c,v 1.87 2002-11-26 16:04:15 adam Exp $ + * $Id: statserv.c,v 1.88 2003-01-06 08:20:28 adam Exp $ */ #include @@ -719,7 +719,7 @@ int statserv_start(int argc, char **argv) inetd_connection(control_block.default_proto); else { - logf (LOG_LOG, "Starting server %s pid=%d", me, getpid()); + yaz_log (LOG_LOG, "Starting server %s pid=%d", me, getpid()); #if 0 sigset_t sigs_to_block; diff --git a/srw/.cvsignore b/srw/.cvsignore new file mode 100644 index 0000000..9db4dc3 --- /dev/null +++ b/srw/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Makefile +Makefile.in +srw_* +*.lo +*.la diff --git a/srw/Makefile.am b/srw/Makefile.am new file mode 100644 index 0000000..bb4c9fc --- /dev/null +++ b/srw/Makefile.am @@ -0,0 +1,28 @@ +# $Id: Makefile.am,v 1.1 2003-01-06 08:20:28 adam Exp $ +AM_CPPFLAGS = -I$(top_srcdir)/include $(GSOAP_INCLUDE) $(XSLT_CFLAGS) + +if SRW +noinst_LTLIBRARIES = libsrw.la +endif + +libsrw_la_SOURCES = srw_C.c srw-namespace.c srw-xcql.c srw-xslt.c srw_Client.c srw-diag.c srw-server.c srw_Server.c + +include_HEADERS = srw_H.h srw_Stub.h + +LDADD = $(GSOAP_LIB) + +EXTRA_DIST = zing.h + +# Dependency for stdsoap2.h needed! +stdsoap2.h srw_C.c srw_Client.c srw_Server.c srw_H.h srw_Stub.h: zing.h + $(GSOAP_PREFIX)/bin/soapcpp2 -p srw_ -c zing.h + +srw-namespace.o: srw_H.h + +srw_C.o: srw_C.c + $(COMPILE) -c soapC.c +srw_Client.o: soapClient.c + $(COMPILE) -c srw_Client.c +srw_Server.o: srw_Server.c + $(COMPILE) -c srw_Server.c + diff --git a/srw/srw-diag.c b/srw/srw-diag.c new file mode 100644 index 0000000..e514c95 --- /dev/null +++ b/srw/srw-diag.c @@ -0,0 +1,108 @@ +/* $Id: srw-diag.c,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include + +static struct { + int code; + char *msg; +} msg_tab[] = { +/* General Diagnostics*/ +{1, "Permanent system error"}, +{2, "System temporarily unavailable"}, +{3, "Authentication error"}, +/* Diagnostics Relating to CQL*/ +{10, "Illegal query"}, +{11, "Unsupported query type (XCQL vs CQL)"}, +{12, "Too many characters in query"}, +{13, "Unbalanced or illegal use of parentheses"}, +{14, "Unbalanced or illegal use of quotes"}, +{15, "Illegal or unsupported index set"}, +{16, "Illegal or unsupported index"}, +{17, "Illegal or unsupported combination of index and index set"}, +{18, "Illegal or unsupported combination of indexes"}, +{19, "Illegal or unsupported relation"}, +{20, "Illegal or unsupported relation modifier"}, +{21, "Illegal or unsupported combination of relation modifers"}, +{22, "Illegal or unsupported combination of relation and index"}, +{23, "Too many characters in term"}, +{24, "Illegal combination of relation and term"}, +{25, "Special characters not quoted in term"}, +{26, "Non special character escaped in term"}, +{27, "Empty term unsupported"}, +{28, "Masking character not supported"}, +{29, "Masked words too short"}, +{30, "Too many masking characters in term"}, +{31, "Anchoring character not supported"}, +{32, "Anchoring character in illegal or unsupported position"}, +{33, "Combination of proximity/adjacency and masking characters not supported"}, +{34, "Combination of proximity/adjacency and anchoring characters not supported"}, +{35, "Terms only exclusion (stop) words"}, +{36, "Term in invalid format for index or relation"}, +{37, "Illegal or unsupported boolean operator"}, +{38, "Too many boolean operators in query"}, +{39, "Proximity not supported"}, +{40, "Illegal or unsupported proximity relation"}, +{41, "Illegal or unsupported proximity distance"}, +{42, "Illegal or unsupported proximity unit"}, +{43, "Illegal or unsupported proximity ordering"}, +{44, "Illegal or unsupported combination of proximity modifiers"}, +{45, "Index set name (prefix) assigned to multiple identifiers"}, +/* Diagnostics Relating to Result Sets*/ +{50, "Result sets not supported"}, +{51, "Result set does not exist"}, +{52, "Result set temporarily unavailable"}, +{53, "Result sets only supported for retrieval"}, +{54, "Retrieval may only occur from an existing result set"}, +{55, "Combination of result sets with search terms not supported"}, +{56, "Only combination of single result set with search terms supported"}, +{57, "Result set created but no records available"}, +{58, "Result set created with unpredictable partial results available"}, +{59, "Result set created with valid partial results available"}, +/* Diagnostics Relating to Records*/ +{60, "Too many records retrieved"}, +{61, "First record position out of range"}, +{62, "Negative number of records requested"}, +{63, "System error in retrieving records"}, +{64, "Record temporarily unavailable"}, +{65, "Record does not exist"}, +{66, "Unknown schema for retrieval"}, +{67, "Record not available in this schema"}, +{68, "Not authorised to send record"}, +{69, "Not authorised to send record in this schema"}, +{70, "Record too large to send"}, +/* Diagnostics Relating to Sorting*/ +{80, "Sort not supported"}, +{81, "Unsupported sort type (sortKeys vs xSortKeys)"}, +{82, "Illegal or unsupported sort sequence"}, +{83, "Too many records"}, +{84, "Too many sort keys"}, +{85, "Duplicate sort keys"}, +{86, "Incompatible record formats"}, +{87, "Unsupported schema for sort"}, +{88, "Unsupported tag path for sort"}, +{89, "Tag path illegal or unsupported for schema"}, +{90, "Illegal or unsupported direction value"}, +{91, "Illegal or unsupported case value"}, +{92, "Illegal or unsupported missing value action"}, +/* Diagnostics Relating to Explain*/ +{100, "Explain not supported"}, +{101, "Explain request type not supported (SOAP vs GET)"}, +{102, "Explain record temporarily unavailable"}, +{0, 0} +}; + +const char *yaz_srw_diag_str (int code) +{ + int i; + for (i=0; msg_tab[i].msg; i++) + if (msg_tab[i].code == code) + return msg_tab[i].msg; + return "Unknown error"; +} diff --git a/srw/srw-namespace.c b/srw/srw-namespace.c new file mode 100644 index 0000000..1659536 --- /dev/null +++ b/srw/srw-namespace.c @@ -0,0 +1,29 @@ +/* $Id: srw-namespace.c,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include "srw_H.h" + +struct Namespace srw_namespaces[] = +{ + {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"}, + {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"}, +#if 1 + {"xsi", "http://schemas.xmlsoap.org/wsdl/"}, + {"xsd", "http://www.w3.org/2001/XMLSchema"}, +#else + {"xsi", "http://www.w3.org/1999/XMLSchema-instance"}, + {"xsd", "http://www.w3.org/1999/XMLSchema"}, +#endif + {"zs", "http://www.loc.gov/zing/srw/v1.0/"}, + {"zt", "http://www.loc.gov/zing/srw/v1.0/types/"}, + {"xcql", "http://www.loc.gov/zing/cql/v1.0/xcql/"}, + {"xsortkeys","http://www.loc.gov/zing/srw/v1.0/xsortkeys/"}, + {"diag", "http://www.loc.gov/zing/srw/v1.0/diagnostic/"}, + {NULL, NULL} +}; diff --git a/srw/srw-server.c b/srw/srw-server.c new file mode 100644 index 0000000..2d09052 --- /dev/null +++ b/srw/srw-server.c @@ -0,0 +1,74 @@ + +#include +#include + +struct srw_info { + int (*sr_h)(void *userinfo, + struct soap * soap, + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *res); + int (*e_h)(void *userinfo, + struct soap *soap, + struct zs__explainResponse *explainResponse); + void *userinfo; +}; + +int zs__explainRequest (struct soap *soap, + struct zs__explainResponse *explainResponse) +{ + struct srw_info *info = (struct srw_info *) soap->user; + return (*info->e_h)(info->userinfo, soap, explainResponse); +} + +int zs__searchRetrieveRequest(struct soap * soap, + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *res) +{ + struct srw_info *info = (struct srw_info *) soap->user; + return (*info->sr_h)(info->userinfo, soap, + query, xQuery, sortKeys, xSortKeys, + startRecord, maximumRecords, + recordSchema, recordPacking, + res); +} + +void yaz_srw_serve (struct soap *soap, + void *userinfo, + int (*sr_h)(void *userinfo, + struct soap * soap, + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *res), + int (*e_h)(void *userinfo, + struct soap *soap, + struct zs__explainResponse *explainResponse)) +{ + struct srw_info info; + + info.sr_h = sr_h; + info.e_h = e_h; + info.userinfo = userinfo; + soap->user = &info; + soap->namespaces = srw_namespaces; + soap_serve(soap); +} diff --git a/srw/srw-xcql.c b/srw/srw-xcql.c new file mode 100644 index 0000000..bdd16fd --- /dev/null +++ b/srw/srw-xcql.c @@ -0,0 +1,84 @@ +/* $Id: srw-xcql.c,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#include + +struct cql_node *xcql_to_cqlnode(struct xcql__operandType *p) +{ + struct cql_node *cn = 0; + if (p && p->searchClause) + { + cn = cql_node_mk_sc(p->searchClause->index, + p->searchClause->relation->value, + p->searchClause->term); + if (p->searchClause->relation->modifiers) + { + struct xcql__modifiersType *mods = + p->searchClause->relation->modifiers; + struct cql_node **cnp = &cn->u.st.modifiers; + + int i; + for (i = 0; i < mods->__sizeModifier; i++) + { + *cnp = cql_node_mk_mod(mods->modifier[i]->type, + mods->modifier[i]->value); + cnp = &(*cnp)->u.mod.next; + } + } + if (p->searchClause->prefixes) + { + struct xcql__prefixesType *prefixes = p->searchClause->prefixes; + struct cql_node **cnp = &cn->u.st.prefixes; + + int i; + for (i = 0; i < prefixes->__sizePrefix; i++) + { + *cnp = cql_node_mk_mod(prefixes->prefix[i]->name, + prefixes->prefix[i]->identifier); + cnp = &(*cnp)->u.mod.next; + } + } + } + else if (p && p->triple) + { + cn = cql_node_mk_boolean(p->triple->boolean->value); + + if (p->triple->boolean->modifiers) + { + struct xcql__modifiersType *mods = + p->triple->boolean->modifiers; + struct cql_node **cnp = &cn->u.bool.modifiers; + + int i; + for (i = 0; i < mods->__sizeModifier; i++) + { + *cnp = cql_node_mk_mod(mods->modifier[i]->type, + mods->modifier[i]->value); + cnp = &(*cnp)->u.mod.next; + } + } + if (p->triple->prefixes) + { + struct xcql__prefixesType *prefixes = p->triple->prefixes; + struct cql_node **cnp = &cn->u.bool.prefixes; + + int i; + for (i = 0; i < prefixes->__sizePrefix; i++) + { + *cnp = cql_node_mk_mod(prefixes->prefix[i]->name, + prefixes->prefix[i]->identifier); + cnp = &(*cnp)->u.mod.next; + } + } + cn->u.bool.left = xcql_to_cqlnode(p->triple->leftOperand); + cn->u.bool.right = xcql_to_cqlnode(p->triple->rightOperand); + } + return cn; +} + diff --git a/srw/srw-xslt.c b/srw/srw-xslt.c new file mode 100644 index 0000000..c3dbac0 --- /dev/null +++ b/srw/srw-xslt.c @@ -0,0 +1,209 @@ +/* $Id: srw-xslt.c,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +#if HAVE_XSLT +#include +#include +#include +#include +#endif + +#include + +struct xslt_maps_info { +#if HAVE_XSLT + xmlDocPtr doc; +#else + int dummy; +#endif +}; + +struct xslt_map_result_info { +#if HAVE_XSLT + xmlChar *buf; +#else + char *buf; +#endif + int len; + char *schema; +}; + +xslt_maps xslt_maps_create() +{ + xslt_maps m = malloc(sizeof(*m)); +#if HAVE_XSLT + m->doc = 0; +#endif + return m; +} + +void xslt_maps_free(xslt_maps m) +{ +#if HAVE_XSLT + xmlFreeDoc(m->doc); +#endif + free (m); +} + +int xslt_maps_file(xslt_maps m, const char *f) +{ +#if HAVE_XSLT + if (m->doc) + xmlFreeDoc(m->doc); + m->doc = xmlParseFile(f); + if (!m->doc) + return -1; + return 0; +#else + return -2; +#endif +} + +void xslt_map_free (xslt_map_result res) +{ + if (res) + { + free (res->schema); +#if HAVE_XSLT + xmlFree(res->buf); +#endif + free (res); + } +} + +xslt_map_result xslt_map (xslt_maps m, const char *schema_source, + const char *schema_target, + const char *in_buf, int in_len) +{ +#if HAVE_XSLT + const char *map_ns = "http://indexdata.dk/srw/schema-mappings/v1.0/"; + xmlNodePtr ptr; + + if (!m) + return 0; + ptr = xmlDocGetRootElement(m->doc); + while (ptr && ptr->type == XML_ELEMENT_NODE) + { + if (!strcmp(ptr->name, "schema-mappings")) + { + ptr = ptr->children; + break; + } + } + for (; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, "map") + && !strcmp(ptr->ns->href, map_ns) && ptr->children) + { + xmlNodePtr src = ptr->children; + int source_ok = 0; + int target_ok = 0; + const char *full_target = 0; + const char *filename = 0; + + for (; src; src = src->next) + { + if (src->type == XML_ELEMENT_NODE && + !strcmp(src->name, "schema") && + !strcmp(src->ns->href, map_ns)) + { + struct _xmlAttr *attr = src->properties; + for (; attr; attr = attr->next) + if (!strcmp(attr->name, "target") && + attr->children && + attr->children->type == XML_TEXT_NODE) + { + full_target = attr->children->content; + if (!strcmp(attr->children->content, + schema_target)) + target_ok = 1; + } + else if (!strcmp(attr->name, "source") + && attr->children + && attr->children->type == XML_TEXT_NODE) + + { + if (!strcmp(schema_source, + attr->children->content)) + source_ok = 1; + } + else if (!strcmp(attr->name, "alias") + && attr->children + && attr->children->type == XML_TEXT_NODE) + { + if (!strcmp(attr->children->content, schema_target)) + target_ok = 1; + } + } + if (src->type == XML_ELEMENT_NODE && + !strcmp(src->name, "stylesheet") && + !strcmp(src->ns->href, map_ns)) + { + struct _xmlAttr *attr = src->properties; + for (; attr; attr = attr->next) + if (!strcmp(attr->name, "filename") && + attr->children && + attr->children->type == XML_TEXT_NODE) + { + filename = attr->children->content; + } + } + } + if (source_ok && target_ok) + { + if (filename) + { + xslt_map_result out = malloc(sizeof(*out)); + xmlDocPtr res, doc = xmlParseMemory(in_buf, in_len); + xmlDocPtr xslt_doc = xmlParseFile(filename); + xsltStylesheetPtr xsp; + + xsp = xsltParseStylesheetDoc(xslt_doc); + + res = xsltApplyStylesheet(xsp, doc, 0); + + xmlDocDumpMemory (res, &out->buf, &out->len); + + xsltFreeStylesheet(xsp); + + xmlFreeDoc(doc); + xmlFreeDoc(res); + + out->schema = strdup(full_target); + return out; + } + else + { + xslt_map_result out = malloc(sizeof(*out)); + out->buf = xmlMalloc(in_len); + memcpy (out->buf, in_buf, in_len); + out->len = in_len; + out->schema = strdup(full_target); + return out; + } + } + } + } +#endif + return 0; +} + +char *xslt_map_result_buf(xslt_map_result res) +{ + return res->buf; +} +int xslt_map_result_len(xslt_map_result res) +{ + return res->len; +} + +char *xslt_map_result_schema(xslt_map_result res) +{ + return res->schema; +} diff --git a/srw/zing.h b/srw/zing.h new file mode 100644 index 0000000..8224be3 --- /dev/null +++ b/srw/zing.h @@ -0,0 +1,136 @@ +/* $Id: zing.h,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002 + Index Data Aps + +This file is part of the YAZ toolkit. + +See file LICENSE for details. +*/ +//gsoap zs service name: SRW +//gsoap zs service encoding: literal +//gsoap zs service namespace: http://www.loc.gov/zing/srw/v1.0/ +//gsoap zs schema namespace: http://www.loc.gov/zing/srw/v1.0/ +//gsoap xcql schema namespace: http://www.loc.gov/zing/cql/v1.0/xcql/ +//gsoap xsort schema namespace: http://www.loc.gov/zing/srw/v1.0/xsortkeys/ +//gsoap diag schema namespace: http://www.loc.gov/zing/srw/v1.0/diagnostic/ + +typedef char *xsd__string; +typedef int xsd__integer; +typedef int xsd__boolean; + +typedef xsd__string zs__idType; +typedef char *XML; + +struct zs__recordType { + xsd__string recordSchema; + xsd__string recordData; + xsd__integer recordPosition 0; +}; + +struct zs__records { + int __sizeRecords; + struct zs__recordType **record; +}; + +struct diag__diagnosticType { + xsd__integer code; + xsd__string details 0; +}; + +struct zs__diagnostics { + int __sizeDiagnostics; + struct diag__diagnosticType **diagnostic; +}; + +struct zs__searchRetrieveResponse { + xsd__integer numberOfRecords; + xsd__string resultSetId 1; + xsd__integer resultSetIdleTime 0; + + struct zs__records records 0; + struct zs__diagnostics diagnostics 0; + xsd__integer *nextRecordPosition 0; + xsd__string debugInfo; +}; + +struct xcql__prefixType { + xsd__string name; + xsd__string identifier; +}; + +struct xcql__prefixesType { + int __sizePrefix; + struct xcql__prefixType **prefix; +}; + +struct xcql__relationType { + xsd__string value; + struct xcql__modifiersType *modifiers 0; +}; + +struct xcql__searchClauseType { + struct xcql__prefixesType *prefixes 0; + xsd__string index 0; + struct xcql__relationType *relation 0; + xsd__string term; +}; + +struct xcql__modifierType { + xsd__string type 0; + xsd__string value; +}; + +struct xcql__modifiersType { + int __sizeModifier; + struct xcql__modifierType **modifier; +}; + +struct xcql__booleanType { + xsd__string value; + struct xcql__modifiersType *modifiers 0; +}; + +struct xcql__operandType { + struct xcql__searchClauseType *searchClause 0; + struct xcql__tripleType *triple 0; +}; + +struct xcql__tripleType { + struct xcql__prefixesType *prefixes 0; + struct xcql__booleanType *boolean; + struct xcql__operandType *leftOperand; + struct xcql__operandType *rightOperand; +}; + +struct xsort__sortKeyType { + xsd__string path; + xsd__string schema 0; + xsd__boolean ascending 0; + xsd__boolean caseSensitive 0; + xsd__string missingValue 0; +}; + +struct xsort__xSortKeysType { + int __sizeSortKey; + struct xsort__sortKeyType **sortKey; +}; + +int zs__searchRetrieveRequest ( + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *searchRetrieveResponse +); + +struct zs__explainResponse { + xsd__string Explain; +}; + +int zs__explainRequest ( + struct zs__explainResponse *explainResponse +); diff --git a/srwapps/.cvsignore b/srwapps/.cvsignore new file mode 100644 index 0000000..da7b481 --- /dev/null +++ b/srwapps/.cvsignore @@ -0,0 +1,5 @@ +.deps +.libs +Makefile +Makefile.in +*.lo diff --git a/srwapps/Makefile.am b/srwapps/Makefile.am new file mode 100644 index 0000000..a024153 --- /dev/null +++ b/srwapps/Makefile.am @@ -0,0 +1,18 @@ +## $Id: Makefile.am,v 1.1 2003-01-06 08:20:28 adam Exp $ +## Copyright (C) 2002-2003, Index Data + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/srw $(CFLAGSTHREADS) + +if SRW +bin_PROGRAMS = srw-gateway srw-client +endif + +if ISTHR +extra=../lib/libyazthread.la +endif + +LDADD = $(extra) ../lib/libyaz.la $(GSOAP_LIB) $(XSLT_LIB) $(LIBTHREAD) + +srw_gateway_SOURCES = srw-gateway.c +srw_client_SOURCES = srw-client.c + diff --git a/srwapps/srw-client.c b/srwapps/srw-client.c new file mode 100644 index 0000000..b1c4c6d --- /dev/null +++ b/srwapps/srw-client.c @@ -0,0 +1,179 @@ +/* $Id: srw-client.c,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See file LICENSE for details. +*/ + +#include + +#include + +int main (int argc, char **argv) +{ + struct soap soap; + char *action; + int ret; + struct zs__searchRetrieveResponse res; + char * query = 0; + struct xcql__operandType *xQuery = 0; + xsd__integer startRecord = 1; + xsd__integer maximumRecord = 0; + char *recordSchema = "http://www.loc.gov/marcxml/"; + xsd__string recordPacking = 0; + char *service = 0; + int xcql = 0; + int explain = 0; + char *arg; + + while ((ret = options("er:xs:", argv, argc, &arg)) != -2) + { + switch(ret) + { + case 0: + if (!service) + service = arg; + else if (!query) + query = arg; + break; + case 'e': + explain = 1; + break; + case 'r': + sscanf (arg, "%d,%d", &startRecord, &maximumRecord); + break; + case 'x': + xcql = 1; + break; + case 's': + recordSchema = arg; + } + } + if (!query) + { + printf ("usage:\n srw-client"); + printf (" [-e] [-r start,number] [-x] [-s schema] \n"); + printf (" http://localhost:8001/indexdata.dk/gils computer\n"); + exit (1); + } + soap_init(&soap); + soap.namespaces = srw_namespaces; + + if (explain) + { + struct zs__explainResponse eres; + ret = soap_call_zs__explainRequest(&soap, service, action, + &eres); + if (ret == SOAP_OK) + { + if (eres.Explain) + printf ("%s\n", eres.Explain); + else + printf ("no record\n"); + } + else + soap_print_fault(&soap, stderr); + } + + if (xcql) /* xquery */ + { /* just a hacked query for testing .. */ + struct xcql__searchClauseType *sc1, *sc2; + struct xcql__relationType *relation; + struct xcql__tripleType *triple; + xQuery = soap_malloc (&soap, sizeof(*xQuery)); + sc1 = soap_malloc (&soap, sizeof(*sc1)); + sc1->prefixes = 0; + sc1->index = "dc.title"; + relation = sc1->relation = soap_malloc(&soap, sizeof(*relation)); + sc1->term = "computer"; + relation->value = "="; + relation->modifiers = 0; + + sc2 = soap_malloc (&soap, sizeof(*sc2)); + sc2->prefixes = 0; + sc2->index = "dc.author"; + relation = sc2->relation = soap_malloc(&soap, sizeof(*relation)); + sc2->term = "knuth"; + relation->value = "="; + relation->modifiers = + soap_malloc (&soap, sizeof(*relation->modifiers)); + relation->modifiers->__sizeModifier = 1; + relation->modifiers->modifier = + soap_malloc (&soap, sizeof(*relation->modifiers->modifier)); + relation->modifiers->modifier[0] = + soap_malloc (&soap, sizeof(**relation->modifiers->modifier)); + relation->modifiers->modifier[0]->type = 0; + relation->modifiers->modifier[0]->value = soap_malloc (&soap, 6); + strcpy(relation->modifiers->modifier[0]->value, "fuzzy"); + ; + triple = soap_malloc (&soap, sizeof(*triple)); + triple->prefixes = 0; + triple->boolean = soap_malloc (&soap, sizeof(*triple->boolean)); + triple->boolean->value = "and"; + triple->boolean->modifiers = 0; + triple->leftOperand = + soap_malloc (&soap, sizeof(*triple->leftOperand)); + triple->leftOperand->searchClause = sc1; + triple->rightOperand = + soap_malloc (&soap, sizeof(*triple->rightOperand)); + triple->rightOperand->searchClause = sc2; + xQuery->triple = triple; + query = 0; + } + + ret = soap_call_zs__searchRetrieveRequest(&soap, service, action, + &query, xQuery, + 0, 0, + &startRecord, + &maximumRecord, + &recordSchema, + &recordPacking, + &res); + + if (ret == SOAP_OK) + { + if (res.diagnostics.__sizeDiagnostics > 0) + { + int i; + for (i = 0; i < + res.diagnostics.__sizeDiagnostics; + i++) + { + int code = res.diagnostics.diagnostic[i]->code; + char *details = + res.diagnostics.diagnostic[i]->details; + printf ("error = %d", code); + if (details) + printf (" details = %s", details); + printf ("\n"); + } + } + else + { + int i; + if (res.resultSetId) + printf ("set: %s\n", res.resultSetId); + printf ("numberOfRecords: %d\n", res.numberOfRecords); + for (i = 0; irecordData) + { + printf ("rec %d schema=%s string:\n%s\n", i+1, + res.records.record[i]->recordSchema, + res.records.record[i]->recordData); + } + } + } + } + else + { + soap_print_fault(&soap, stderr); + } + soap_end(&soap); + exit (0); + return 0; +} + diff --git a/srwapps/srw-gateway.c b/srwapps/srw-gateway.c new file mode 100644 index 0000000..77591db --- /dev/null +++ b/srwapps/srw-gateway.c @@ -0,0 +1,903 @@ +/* $Id: srw-gateway.c,v 1.1 2003-01-06 08:20:28 adam Exp $ + Copyright (C) 2002-2003 + Index Data Aps + +This file is part of the YAZ toolkit. + +See the file LICENSE. +*/ + +/* + * TODO: + * + * TTL for targets. Separate thread for cleanup. + * External target config and aliases. + */ + +/* note that soapH.h defines _REENTRANT so we check for it here */ +#ifdef _REENTRANT +#include +#define USE_THREADS 1 +#else +#define USE_THREADS 0 +#endif + +#include +#include +#include +#include +#include +#include + +#define RESULT_SETS 0 +#define SRW_DEBUG 1 + +struct tset { + ZOOM_resultset m_r; + long m_expiry_sec; /* date of creation */ + int m_idle_time; + char *m_query; + char *m_schema; + struct tset *m_next; +}; + +struct target { + ZOOM_connection m_c; + char *m_name; + int m_in_use; + struct tset *m_sets; + struct target *next; +}; + +struct srw_prop { + int optimize_level; + int idle_time; + int max_sets; + xslt_maps maps; +}; + +static cql_transform_t cql_transform_handle = 0; +static struct target *target_list = 0; +#if USE_THREADS +static pthread_mutex_t target_mutex = PTHREAD_MUTEX_INITIALIZER; +#define mylock(x) pthread_mutex_lock(x) +#define myunlock(x) pthread_mutex_unlock(x) +#else +#define mylock(x) +#define myunlock(x) +#endif + +#define ERROR_NO_TARGET -1 +#define ERROR_BAD_CQL 10 + +static int diag_bib1_to_srw (int code) +{ + static int map[] = { + 1, 1, + 2, 2, + 3, 11, + 4, 35, + 5, 12, + 6, 30, + 7, 30, + 8, 32, + 9, 29, + 10, 10, + 11, 12, + 13, 61, + 14, 63, + 15, 68, + 16, 70, + 17, 70, + 18, 50, + 19, 55, + 20, 56, + 21, 52, + 22, 50, + /* 23-26 no map */ + 27, 51, + 28, 52, + 29, 52, + 30, 51, + 31, 52, + 32, 52, + 33, 52, + /* 100 -105 */ + 106, 66, + 107, 11, + 108, 10, + 109, 2, + 110, 37, + /* 111- 112 */ + 113, 10, + 114, 16, + 115, 16, + 116, 16, + 117, 19, + 118, 22, + 119, 32, + 120, 28, + 121, 15, + 122, 32, + 123, 22, + 124, 24, + 125, 36, + 126, 36, + 127, 36, + 128, 51, + 129, 39, + 130, 43, + 131, 40, + 132, 42, + 201, 44, + 202, 41, + 203, 43, + /* 205 */ + 0 + }; + const int *p = map; + while (*p) + { + if (code == *p) + return p[1]; + p += 2; + } + return 0; +} + +static int searchRetrieve(void *userinfo, + struct soap * soap, + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *res); +static int explain (void *userinfo, + struct soap *soap, + struct zs__explainResponse *explainResponse); + +struct target *target_use (const char *action, const char *query, + const char *schema, struct tset **set, + struct srw_prop *prop) +{ + char name[80]; + struct target *l = 0; + struct timeval tv; + struct tset **ssp = 0; + long now; + int no_sets = 0; + + gettimeofday(&tv, 0); + now = tv.tv_sec; + + if (strlen(action) >= 80) + action = "localhost:210"; + if (strchr(action, '/') || strchr(action, ':')) + strcpy (name, action); + else + { + strcpy (name, "localhost/"); + if (*action == '\0') + strcat (name, "Default"); + else + strcat (name, action); + } + + /* See if we have the target and the same query */ + if (query) + for (l = target_list; l; l = l->next) + if (!l->m_in_use && !strcmp (l->m_name, name)) + { + struct tset *s = l->m_sets; + for (; s; s = s->m_next) + if (!strcmp(s->m_query, query) && + !strcmp (s->m_schema, schema)) + { + *set = s; + return l; + } + } + + /* OK, see if we have the target, then.. */ + for (l = target_list; l; l = l->next) + if (!strcmp (l->m_name, name) && !l->m_in_use) + { + struct tset *s = l->m_sets; + for (; s; s = s->m_next) + /* if m_expiry_sec is 0, the condition is true below */ + if (s->m_expiry_sec < now) + { + xfree (s->m_query); + s->m_query = xstrdup(""); + xfree (s->m_schema); + s->m_schema = xstrdup(""); + ZOOM_resultset_destroy(s->m_r); + s->m_r = 0; + *set = s; + return l; + } + break; + } + if (!l) + { + /* allright. Have to make a new one */ + l = xmalloc (sizeof(*l)); + l->m_name = xstrdup (name); + l->m_in_use = 1; + l->m_c = 0; + l->m_sets = 0; + l->next = target_list; + target_list = l; + } + for (ssp = &l->m_sets; *ssp; ssp = &(*ssp)->m_next) + no_sets++; + *ssp = xmalloc(sizeof(**ssp)); + (*ssp)->m_next = 0; + (*ssp)->m_query = xstrdup(""); + (*ssp)->m_schema = xstrdup(""); + (*ssp)->m_r = 0; + (*ssp)->m_expiry_sec = 0; + (*ssp)->m_idle_time = (no_sets >= prop->max_sets ? 0 : prop->idle_time); + *set = *ssp; + return l; +} + +static void target_destroy (struct target *t) +{ + struct target **tp; + + mylock(&target_mutex); + + for (tp = &target_list; *tp; tp = &(*tp)->next) + if (*tp == t) + { + struct tset *s = t->m_sets; + while (s) + { + struct tset *s_next = s->m_next; + xfree (s->m_query); + xfree (s->m_schema); + ZOOM_resultset_destroy (s->m_r); + xfree (s); + s = s_next; + } + + *tp = t->next; + + ZOOM_connection_destroy (t->m_c); + + xfree (t->m_name); + xfree (t); + break; + } + myunlock(&target_mutex); +} + +static void target_leave (struct target *l) +{ + mylock(&target_mutex); + l->m_in_use = 0; + + if (1) + { + struct tset *s = l->m_sets; + for (; s; s = s->m_next) + yaz_log(LOG_LOG, " set %s q=%s", + (s->m_r ? ZOOM_resultset_option_get(s->m_r,"setname"):""), + s->m_query); + } + myunlock(&target_mutex); +} + +static void standalone(struct soap *soap, const char *host, int port, + int max_thr, struct srw_prop *properties) +{ + struct soap **soap_thr = malloc (sizeof(*soap_thr) * max_thr); +#if USE_THREADS + pthread_t *tid = malloc (sizeof(pthread_t) * max_thr); +#endif + int m, s, i; + int cno = 0; + int stop = 0; + char fname[40]; + + m = soap_bind(soap, 0, port, 100); + if (m < 0) + { + yaz_log (LOG_WARN|LOG_ERRNO, "Cannot bind to %d", port); + stop = 1; + } + + for (i = 0; i 1) /* static mode for max_thr <= 1 */ + pthread_join(tid[i], 0); +#endif + soap_end(soap_thr[i]); + } + +#if SRW_DEBUG + sprintf (fname, "srw.recv.%05d.log", cno); + remove (fname); + soap_set_recv_logfile(soap_thr[i], fname); + + sprintf (fname, "srw.sent.%05d.log", cno); + remove (fname); + soap_set_sent_logfile(soap_thr[i], fname); + + sprintf (fname, "srw.test.%05d.log", cno); + remove (fname); + soap_set_test_logfile(soap_thr[i], fname); + + yaz_log (LOG_LOG, "starting session %d %ld.%ld.%ld.%ld", cno, + (long) (soap->ip>>24) & 0xff, + (long) (soap->ip>>16) & 0xff, + (long) (soap->ip>>8) & 0xff, + (long) soap->ip & 0xff); +#endif + soap_thr[i]->encodingStyle = 0; + soap_thr[i]->socket = s; + soap_thr[i]->user = properties; +#if USE_THREADS + if (max_thr <= 1) + yaz_srw_serve(soap_thr[i], properties, + searchRetrieve, explain); /* static mode .. */ + else + pthread_create(&tid[i], 0, (void*(*)(void*))soap_serve, + soap_thr[i]); +#else + yaz_srw_serve(soap_thr[i], properties, + searchRetrieve, explain); /* static mode .. */ +#endif + } + } +#if USE_THREADS + free (tid); +#endif + free (soap_thr); +} + +static void reconnect (struct target *t) +{ + struct tset *s; + + for (s = t->m_sets; s; s = s->m_next) + { + ZOOM_resultset_destroy(s->m_r); + s->m_r = 0; + } + ZOOM_connection_destroy (t->m_c); + + t->m_c = ZOOM_connection_create (0); + ZOOM_connection_connect (t->m_c, t->m_name, 0); +} + +int explain (void *userinfo, + struct soap *soap, + struct zs__explainResponse *explainResponse) +{ + explainResponse->Explain = + "\n" + " \n" + "\n"; + return SOAP_OK; +} + +int fetchone(struct soap *soap, struct srw_prop *properties, + ZOOM_record zrec, const char *schema, + char **rec_data, char **rec_schema) +{ + xslt_map_result res; + int xml_len; + const char *xml_rec = ZOOM_record_get(zrec, "xml", &xml_len); + if (!xml_rec) + { + return 65; + } + if (!strcmp(schema, "MARC21")) + { + *rec_data = soap_malloc (soap, xml_len+1); + memcpy (*rec_data, xml_rec, xml_len); + (*rec_data)[xml_len] = 0; + *rec_schema = "http://www.loc.gov/marcxml/"; + } + else if ((res = xslt_map (properties->maps, "MARC21", + schema, xml_rec, xml_len))) + { + int len = xslt_map_result_len(res); + char *buf = xslt_map_result_buf(res); + + *rec_data = soap_malloc (soap, len+1); + memcpy (*rec_data, buf, len); + (*rec_data)[len] = 0; + + *rec_schema = soap_malloc(soap, + strlen(xslt_map_result_schema(res)) + 1); + strcpy(*rec_schema, xslt_map_result_schema(res)); + + xslt_map_free (res); + } + else + { + *rec_data = soap_malloc(soap, strlen(schema)+1); + strcpy(*rec_data, schema); + return 66; + } + return 0; +} + +int searchRetrieve(void *userinfo, + struct soap * soap, + xsd__string *query, + struct xcql__operandType *xQuery, + xsd__string *sortKeys, + struct xsort__xSortKeysType *xSortKeys, + xsd__integer *startRecord, + xsd__integer *maximumRecords, + xsd__string *recordSchema, + xsd__string *recordPacking, + struct zs__searchRetrieveResponse *res) +{ + const char *msg = 0, *addinfo = 0; + const char *schema = recordSchema ? *recordSchema : ""; + struct target *t = 0; + struct tset *s = 0; + int error = 0; + struct srw_prop *properties = (struct srw_prop*) userinfo; + WRBUF wr_log = wrbuf_alloc(); + + char pqf_buf[1024]; + char zurl[81]; + + *pqf_buf = '\0'; + *zurl = '\0'; + yaz_log (LOG_LOG, "HTTP: %s", soap->endpoint); + if (*soap->endpoint) + { + const char *cp = strstr(soap->endpoint, "//"); + if (cp) + cp = cp+2; /* skip method// */ + else + cp = soap->endpoint; + cp = strstr(cp, "/"); + if (cp) + { + size_t len; + cp++; + len = strlen(cp); + if (len > 80) + len = 80; + if (len) + memcpy (zurl, cp, len); + zurl[len] = '\0'; + } + } + else + { + const char *cp = getenv("PATH_INFO"); + if (cp && cp[0] && cp[1]) + { + size_t len; + cp++; /* skip / */ + len = strlen(cp); + if (len > 80) + len = 80; + if (len) + memcpy (zurl, cp, len); + zurl[len] = '\0'; + } + } + if (query) + { + CQL_parser cql_parser = cql_parser_create(); + int r = cql_parser_string(cql_parser, *query); + + if (r) + { + yaz_log (LOG_LOG, "cql failed: %s", *query); + error = ERROR_BAD_CQL; + } + else + { + struct cql_node *tree = cql_parser_result(cql_parser); + error = cql_transform_buf (cql_transform_handle, tree, + pqf_buf, sizeof(pqf_buf)); + if (error) + cql_transform_error(cql_transform_handle, &addinfo); + cql_parser_destroy(cql_parser); + yaz_log (LOG_LOG, "cql OK: %s", *query); + } + } + else if (xQuery) + { + struct cql_node *tree = xcql_to_cqlnode(xQuery); + yaz_log (LOG_LOG, "xcql"); + cql_transform_buf (cql_transform_handle, tree, + pqf_buf, sizeof(pqf_buf)); + cql_node_destroy(tree); + } + if (!error) + { + mylock(&target_mutex); + t = target_use (zurl, *pqf_buf ? pqf_buf : 0, schema, &s, properties); + myunlock(&target_mutex); + } + + if (!error && !t->m_c) + { + reconnect(t); + if (ZOOM_connection_error (t->m_c, &msg, &addinfo)) + { + yaz_log (LOG_LOG, "%s: connect failed", t->m_name); + error = ERROR_NO_TARGET; + } + else + yaz_log (LOG_LOG, "%s: connect ok", t->m_name); + } + if (!error && t->m_c && *pqf_buf) + { + if (properties->optimize_level <=1 || + strcmp (pqf_buf, s->m_query) || + strcmp (schema, s->m_schema)) + { + /* not the same query: remove result set .. */ + ZOOM_resultset_destroy (s->m_r); + s->m_r = 0; + } + else + { + /* same query: retrieve (instead of doing search) */ + if (maximumRecords && *maximumRecords > 0) + { + int start = startRecord ? *startRecord : 1; + yaz_log (LOG_LOG, "%s: present start=%d count=%d pqf=%s", + t->m_name, start, *maximumRecords, pqf_buf); + wrbuf_printf (wr_log, "%s: present start=%d count=%d pqf=%s", + t->m_name, start, *maximumRecords, pqf_buf); + ZOOM_resultset_records (s->m_r, 0, start-1, *maximumRecords); + error = ZOOM_connection_error (t->m_c, &msg, &addinfo); + if (error == ZOOM_ERROR_CONNECTION_LOST || + error == ZOOM_ERROR_CONNECT) + { + reconnect (t); + if ((error = ZOOM_connection_error (t->m_c, &msg, + &addinfo))) + { + yaz_log (LOG_LOG, "%s: connect failed", t->m_name); + error = ERROR_NO_TARGET; + } + } + else if (error) + { + yaz_log (LOG_LOG, "%s: present failed bib1-code=%d", + t->m_name, error); + error = diag_bib1_to_srw(error); + } + } + else + { + yaz_log (LOG_LOG, "%s: matched search pqf=%s", + t->m_name, pqf_buf); + wrbuf_printf (wr_log, "%s: matched search pqf=%s", + t->m_name, pqf_buf); + } + } + if (!error && !s->m_r) + { /* no result set usable. We must search ... */ + int pass; + for (pass = 0; pass < 2; pass++) + { + char val[30]; + int start = startRecord ? *startRecord : 1; + int count = maximumRecords ? *maximumRecords : 0; + + sprintf (val, "%d", start-1); + ZOOM_connection_option_set (t->m_c, "start", val); + + sprintf (val, "%d", count); + ZOOM_connection_option_set (t->m_c, "count", val); + + ZOOM_connection_option_set (t->m_c, "preferredRecordSyntax", + "usmarc"); + + xfree (s->m_query); + s->m_query = xstrdup (pqf_buf); + + xfree (s->m_schema); + s->m_schema = xstrdup (schema); + + yaz_log (LOG_LOG, "%s: search start=%d count=%d pqf=%s", + t->m_name, start, count, pqf_buf); + + wrbuf_printf (wr_log, "%s: search start=%d count=%d pqf=%s", + t->m_name, start, count, pqf_buf); + + s->m_r = ZOOM_connection_search_pqf (t->m_c, s->m_query); + + error = ZOOM_connection_error (t->m_c, &msg, &addinfo); + if (!error) + break; + if (error != ZOOM_ERROR_CONNECTION_LOST && + error != ZOOM_ERROR_CONNECT) + { + yaz_log (LOG_LOG, "%s: search failed bib1-code=%d", + t->m_name, error); + error = diag_bib1_to_srw(error); + break; + } + yaz_log (LOG_LOG, "%s: reconnect (search again)", t->m_name); + + /* try once more */ + reconnect(t); + + error = ZOOM_connection_error (t->m_c, &msg, &addinfo); + + if (error) + { + error = ERROR_NO_TARGET; + break; + } + } + } + } + + if (!error && t->m_c && s->m_r) + { + yaz_log (LOG_LOG, "%s: %d hits", t->m_name, + ZOOM_resultset_size(s->m_r)); + res->numberOfRecords = ZOOM_resultset_size(s->m_r); + + if (maximumRecords) + { + int i, j = 0; + int offset = startRecord ? *startRecord -1 : 0; + res->records.record = + soap_malloc(soap, sizeof(*res->records.record) * + *maximumRecords); + + for (i = 0; i < *maximumRecords; i++) + { + char *rec_data = 0; + char *rec_schema = 0; + ZOOM_record zrec = ZOOM_resultset_record (s->m_r, offset + i); + if (!zrec) + { + error = 65; + addinfo = schema; + break; + } + error = fetchone(soap, properties, zrec, schema, + &rec_data, &rec_schema); + if (error) + { + addinfo = rec_data; + break; + } + res->records.record[j] = + soap_malloc(soap, sizeof(**res->records.record)); + res->records.record[j]->recordData = rec_data; + res->records.record[j]->recordSchema = rec_schema; + j++; + } + res->records.__sizeRecords = j; + } + else + res->numberOfRecords = 0; + } + if (error) + { + if (s) + { + ZOOM_resultset_destroy (s->m_r); + s->m_r = 0; + } + if (error == ERROR_NO_TARGET) + { + addinfo = zurl; + ZOOM_connection_destroy (t->m_c); + t->m_c = 0; + } + else + { + res->diagnostics.__sizeDiagnostics = 1; + res->diagnostics.diagnostic = + soap_malloc (soap, sizeof(*res->diagnostics.diagnostic)); + res->diagnostics.diagnostic[0] = + soap_malloc (soap, sizeof(**res->diagnostics.diagnostic)); + + res->diagnostics.diagnostic[0]->code = error; + if (addinfo) + { + res->diagnostics.diagnostic[0]->details = + soap_malloc (soap, strlen(addinfo) + 1); + strcpy (res->diagnostics.diagnostic[0]->details, addinfo); + } + else + res->diagnostics.diagnostic[0]->details = 0; + } + } + else + { + if (s->m_r) + { + struct timeval tv; + const char *setname = ZOOM_resultset_option_get(s->m_r, "setname"); + if (strcmp(setname, "default") && s->m_idle_time) + { + res->resultSetId = soap_malloc(soap, strlen(setname)); + strcpy(res->resultSetId, setname); + res->resultSetIdleTime = s->m_idle_time; + gettimeofday(&tv, 0); + s->m_expiry_sec = res->resultSetIdleTime + tv.tv_sec + 2; + } else { + s->m_expiry_sec = 0; + } + } + } + + if (t) + { + if (properties->optimize_level > 0) + target_leave(t); + else + target_destroy(t); + } + wrbuf_free(wr_log, 1); + if (error == ERROR_NO_TARGET) + return soap_receiver_fault(soap, "Cannot connect to Z39.50 target", 0); + return SOAP_OK; +} + +int main(int argc, char **argv) +{ + struct soap soap; + int ret; + int port = 0; + int no_threads = 40; + char *arg; + const char *host = 0; + struct srw_prop properties; + + properties.optimize_level = 2; + properties.idle_time = 300; + properties.max_sets = 30; + properties.maps = 0; + + while ((ret = options("dO:T:l:hVp:s:x:i:", argv, argc, &arg)) != -2) + { + switch(ret) + { + case 0: + port = atoi(arg); + break; + case 'O': + properties.optimize_level = atoi(arg); + break; + case 'T': + no_threads = atoi(arg); + if (no_threads < 1 || no_threads > 200) + no_threads = 40; + break; + case 's': + if (!properties.maps) + { + properties.maps = xslt_maps_create(); + if (xslt_maps_file(properties.maps, arg)) + { + fprintf (stderr, "maps file %s could not be opened\n", + arg); + exit(1); + } + } + break; + case 'l': + yaz_log_init_file(arg); + break; + case 'V': + puts ("Version: $Id: srw-gateway.c,v 1.1 2003-01-06 08:20:28 adam Exp $" +#if SRW_DEBUG + " DEBUG" +#endif + ); + exit (0); + case 'p': + if (cql_transform_handle == 0) + cql_transform_handle = cql_transform_open_fname(arg); + break; + case 'x': + properties.max_sets = atoi(arg); + break; + case 'i': + properties.idle_time = atoi(arg); + break; + case 'h': + printf ("srw-gateway [options] \n"); + printf (" port port for standalone service; If port is omitted, CGI is used.\n"); + printf (" -O n optimize level. >= 1 cache connections, >=2 cache result sets.\n"); +#if USE_THREADS + printf (" -T n number of threads.\n"); +#else + printf (" -T unsupported in this version.\n"); +#endif + printf (" -l file log to file (instead of stderr).\n"); + printf (" -p file PQF properties.\n"); + printf (" -s file schema maps.\n"); + printf (" -i time idle time.\n"); + printf (" -x sets live sets.\n"); + printf (" -V show version.\n"); + exit (1); + default: + fprintf (stderr, "srw-gateway: bad option -%s ; use -h for help\n", + arg); + exit (1); + break; + + } + } + if (!cql_transform_handle) + cql_transform_handle = cql_transform_open_fname("pqf.properties"); + if (!properties.maps) + { + properties.maps = xslt_maps_create(); + xslt_maps_file(properties.maps, "maps.xml"); + } + soap.encodingStyle = 0; + if (port == 0 && getenv("QUERY_STRING")) + { + properties.optimize_level = 0; + + yaz_log_init_file("srw.log"); + yaz_log (LOG_LOG, "CGI begin"); + soap_init(&soap); + soap.user = &properties; + + yaz_srw_serve(&soap, &properties, searchRetrieve, explain); + + soap_end(&soap); + yaz_log (LOG_LOG, "CGI end"); + } + else if (port) + { + if (!cql_transform_handle) + { + fprintf(stderr, "no properties file; use option -p to specify\n"); + exit (1); + } + yaz_log (LOG_LOG, "standalone service on port %d", port); + + soap_init(&soap); + + standalone(&soap, host, port, no_threads, &properties); + } + else + { + fprintf(stderr, "srw-gateway: no port specified. Use -h for help\n"); + } + xslt_maps_free(properties.maps); + return 0; +} diff --git a/util/Makefile.am b/util/Makefile.am index d2bb9bf..c72fc55 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -1,6 +1,6 @@ -## Copyright (C) 1994-2002, Index Data +## Copyright (C) 1994-2003, Index Data ## All rights reserved. -## $Id: Makefile.am,v 1.14 2002-12-16 13:13:53 adam Exp $ +## $Id: Makefile.am,v 1.15 2003-01-06 08:20:28 adam Exp $ noinst_LTLIBRARIES = libutil.la diff --git a/util/atoin.c b/util/atoin.c index a99a6c1..57f9561 100644 --- a/util/atoin.c +++ b/util/atoin.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1997-2002, Index Data + * Copyright (c) 1997-2003, Index Data * See the file LICENSE for details. * - * $Id: atoin.c,v 1.5 2002-08-27 13:18:26 adam Exp $ + * $Id: atoin.c,v 1.6 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/util/log.c b/util/log.c index 5fa4d5e..4332e92 100644 --- a/util/log.c +++ b/util/log.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: log.c,v 1.32 2002-12-05 12:19:24 adam Exp $ + * $Id: log.c,v 1.33 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/util/marcdisp.c b/util/marcdisp.c index 3259d6c..8b72818 100644 --- a/util/marcdisp.c +++ b/util/marcdisp.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: marcdisp.c,v 1.27 2002-12-17 13:32:04 adam Exp $ + * $Id: marcdisp.c,v 1.28 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/util/marcdump.c b/util/marcdump.c index f28a99b..d8fc19f 100644 --- a/util/marcdump.c +++ b/util/marcdump.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: marcdump.c,v 1.19 2002-12-16 13:13:53 adam Exp $ + * $Id: marcdump.c,v 1.20 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/util/nmem.c b/util/nmem.c index f91ecc1..8415772 100644 --- a/util/nmem.c +++ b/util/nmem.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: nmem.c,v 1.38 2002-12-05 12:19:24 adam Exp $ + * $Id: nmem.c,v 1.39 2003-01-06 08:20:28 adam Exp $ */ /* @@ -460,7 +460,7 @@ void yaz_strerror(char *buf, int max) else *buf = '\0'; #else -#if YAZ_POSIX_THREADS +#if HAVE_STRERROR_R strerror_r(errno, buf, max); #else strcpy(buf, strerror(yaz_errno())); diff --git a/util/oid.c b/util/oid.c index db08d6b..a8c485b 100644 --- a/util/oid.c +++ b/util/oid.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: oid.c,v 1.58 2002-12-01 23:22:10 mike Exp $ + * $Id: oid.c,v 1.59 2003-01-06 08:20:28 adam Exp $ */ /* @@ -295,6 +295,8 @@ static oident standard_oids[] = "Zthes-tagset"}, {PROTO_Z3950, CLASS_NEGOT, VAL_CHARNEG3, {15,3,-1}, "CharSetandLanguageNegotiation-3"}, + {PROTO_Z3950, CLASS_USERINFO,VAL_CQL, {16, 2, -1}, + "CQL"}, {PROTO_GENERAL, CLASS_GENERAL, VAL_UCS2, {1,0,10646,1,0,2,-1}, "UCS-2"}, {PROTO_GENERAL, CLASS_GENERAL, VAL_UCS4, {1,0,10646,1,0,4,-1}, diff --git a/util/siconv.c b/util/siconv.c index b0e5611..73d7148 100644 --- a/util/siconv.c +++ b/util/siconv.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1997-2002, Index Data + * Copyright (c) 1997-2003, Index Data * See the file LICENSE for details. * - * $Id: siconv.c,v 1.8 2002-12-16 13:13:53 adam Exp $ + * $Id: siconv.c,v 1.9 2003-01-06 08:20:28 adam Exp $ */ /* mini iconv and wrapper for system iconv library (if present) */ diff --git a/util/siconvtst.c b/util/siconvtst.c index bc394b8..9f7038e 100644 --- a/util/siconvtst.c +++ b/util/siconvtst.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1997-2002, Index Data + * Copyright (c) 1997-2003, Index Data * See the file LICENSE for details. * - * $Id: siconvtst.c,v 1.7 2002-12-16 13:13:53 adam Exp $ + * $Id: siconvtst.c,v 1.8 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/util/tpath.c b/util/tpath.c index e205321..f04df3e 100644 --- a/util/tpath.c +++ b/util/tpath.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: tpath.c,v 1.8 2002-04-05 12:49:13 adam Exp $ + * $Id: tpath.c,v 1.9 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H #include diff --git a/util/wrbuf.c b/util/wrbuf.c index c3fea1f..338ce09 100644 --- a/util/wrbuf.c +++ b/util/wrbuf.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: wrbuf.c,v 1.11 2002-10-22 14:40:21 adam Exp $ + * $Id: wrbuf.c,v 1.12 2003-01-06 08:20:28 adam Exp $ */ /* diff --git a/util/xmalloc.c b/util/xmalloc.c index dc9b431..96bc73a 100644 --- a/util/xmalloc.c +++ b/util/xmalloc.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 1994-2002, Index Data + * Copyright (C) 1994-2003, Index Data * All rights reserved. * Sebastian Hammer, Adam Dickmeiss * - * $Id: xmalloc.c,v 1.17 2002-06-18 21:30:39 adam Exp $ + * $Id: xmalloc.c,v 1.18 2003-01-06 08:20:28 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/win/LICENSE.txt b/win/LICENSE.txt index 9e177c7..478dc66 100644 --- a/win/LICENSE.txt +++ b/win/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 1995-2002, Index Data. +Copyright (c) 1995-2003, Index Data. Permission to use, copy, modify, distribute, and sell this software and its documentation, in whole or in part, for any purpose, is hereby granted, provided that: diff --git a/win/yaz.rc b/win/yaz.rc index 366020d..98567de 100644 --- a/win/yaz.rc +++ b/win/yaz.rc @@ -75,7 +75,7 @@ BEGIN VALUE "FileDescription", "YAZ Toolkit\0" VALUE "FileVersion", "1, 9, 2, 1\0" VALUE "InternalName", "YAZ\0" - VALUE "LegalCopyright", "Copyright © 1995-2002 Index Data\0" + VALUE "LegalCopyright", "Copyright © 1995-2003 Index Data\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "yaz.rc\0" VALUE "PrivateBuild", "\0" diff --git a/yaz-config.in b/yaz-config.in index efa7398..5faf6d0 100644 --- a/yaz-config.in +++ b/yaz-config.in @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: yaz-config.in,v 1.14 2002-12-09 23:29:00 adam Exp $ +# $Id: yaz-config.in,v 1.15 2003-01-06 08:20:26 adam Exp $ yazprefix=@prefix@ yaz_echo_cflags=no yaz_echo_libs=no @@ -10,7 +10,7 @@ yaz_echo_comp=no yaz_src_root=@YAZ_SRC_ROOT@ yaz_build_root=@YAZ_BUILD_ROOT@ -yazextralibs="@LIBS@" +yazextralibs="@GSOAP_LIB@ @XSLT_LIB@ @LIBS@" YAZVERSION=@VERSION@ usage() diff --git a/z39.50/prt-ext.c b/z39.50/prt-ext.c index 03c1cf5..7e9bc41 100644 --- a/z39.50/prt-ext.c +++ b/z39.50/prt-ext.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * - * $Id: prt-ext.c,v 1.4 2002-12-05 12:07:00 adam Exp $ + * $Id: prt-ext.c,v 1.5 2003-01-06 08:20:28 adam Exp $ */ #include @@ -38,6 +38,7 @@ static Z_ext_typeent type_table[] = {VAL_DES1, Z_External_acfDes1, (Odr_fun) z_DES_RN_Object}, {VAL_KRB1, Z_External_acfKrb1, (Odr_fun) z_KRBObject}, {VAL_MULTISRCH2, Z_External_multisrch2, (Odr_fun) z_MultipleSearchTerms_2}, + {VAL_CQL, Z_External_CQL, (Odr_fun) z_InternationalString}, {VAL_NONE, 0, 0} }; @@ -117,6 +118,8 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) (Odr_fun)z_KRBObject, 0}, {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_multisrch2, (Odr_fun)z_MultipleSearchTerms_2, 0}, + {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_CQL, + (Odr_fun)z_InternationalString, 0}, {-1, -1, -1, -1, 0, 0} }; diff --git a/z39.50/z3950v3.asn b/z39.50/z3950v3.asn index 875e548..42c7ee8 100644 --- a/z39.50/z3950v3.asn +++ b/z39.50/z3950v3.asn @@ -140,7 +140,9 @@ IdAuthentication ::= type-2 [2] OCTET STRING, type-100 [100] OCTET STRING, type-101 [101] IMPLICIT RPNQuery, - type-102 [102] OCTET STRING} + type-102 [102] OCTET STRING, + type-104 [104] IMPLICIT EXTERNAL +} -- -- Definitions for RPN query RPNQuery ::= SEQUENCE{ diff --git a/zoom/Makefile.am b/zoom/Makefile.am index cbb8301..235e489 100644 --- a/zoom/Makefile.am +++ b/zoom/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.6 2002-09-24 08:00:50 adam Exp $ +## $Id: Makefile.am,v 1.7 2003-01-06 08:20:28 adam Exp $ ## Copyright (C) 2001, Index Data AM_CPPFLAGS = -I$(top_srcdir)/include @@ -6,15 +6,15 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_PROGRAMS = zoomtst1 zoomtst2 zoomtst3 zoomtst4 zoomtst5 zoomtst6 zoomtst7 zoomtst8 bin_PROGRAMS = zoomsh -zoomtst1_LDADD = ../lib/libyaz.la -zoomtst2_LDADD = ../lib/libyaz.la -zoomtst3_LDADD = ../lib/libyaz.la -zoomtst4_LDADD = ../lib/libyaz.la -zoomtst5_LDADD = ../lib/libyaz.la -zoomtst6_LDADD = ../lib/libyaz.la -zoomtst7_LDADD =../lib/libyazmalloc.la ../lib/libyaz.la -zoomtst8_LDADD = ../lib/libyaz.la -zoomsh_LDADD = ../lib/libyaz.la $(READLINE_LIBS) +zoomtst1_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomtst2_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomtst3_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomtst4_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomtst5_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomtst6_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomtst7_LDADD = ../lib/libyazmalloc.la ../lib/libyaz.la $(GSOAP_LIB) +zoomtst8_LDADD = ../lib/libyaz.la $(GSOAP_LIB) +zoomsh_LDADD = ../lib/libyaz.la $(GSOAP_LIB) $(READLINE_LIBS) zoomtst1_SOURCES = zoomtst1.c zoomtst2_SOURCES = zoomtst2.c diff --git a/zoom/zoomsh.c b/zoom/zoomsh.c index 6aedbd0..bf35f6a 100644 --- a/zoom/zoomsh.c +++ b/zoom/zoomsh.c @@ -1,5 +1,5 @@ /* - * $Id: zoomsh.c,v 1.11 2002-06-05 21:09:20 adam Exp $ + * $Id: zoomsh.c,v 1.12 2003-01-06 08:20:28 adam Exp $ * * ZOOM-C Shell */ @@ -168,14 +168,14 @@ static void cmd_show (ZOOM_connection *c, ZOOM_resultset *r, for (i = 0; i diff --git a/zutil/logrpn.c b/zutil/logrpn.c index 95460cb..229c59f 100644 --- a/zutil/logrpn.c +++ b/zutil/logrpn.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2001, Index Data * All rights reserved. * - * $Id: logrpn.c,v 1.8 2002-12-28 12:13:03 adam Exp $ + * $Id: logrpn.c,v 1.9 2003-01-06 08:20:29 adam Exp $ */ #include @@ -350,3 +350,17 @@ void log_scan_term (Z_AttributesPlusTerm *zapt, oid_value ast) yaz_log (LOG_LOG, "%*.0s term (not general)", level, ""); zlog_attributes (zapt, level+2, ast); } + +void yaz_log_zquery (Z_Query *q) +{ + static int cql_oid[] = {1, 2, 840, 10003, 16, 2, -1}; + switch (q->which) + { + case Z_Query_type_1: case Z_Query_type_101: + log_rpn_query (q->u.type_1); + break; + case Z_Query_type_104: + if (q->u.type_104->which == Z_External_CQL) + yaz_log (LOG_LOG, "CQL: %s", q->u.type_104->u.cql); + } +} diff --git a/zutil/otherinfo.c b/zutil/otherinfo.c index 2ba4303..9ee8550 100644 --- a/zutil/otherinfo.c +++ b/zutil/otherinfo.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1999-2002, Index Data + * Copyright (c) 1999-2003, Index Data * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: otherinfo.c,v 1.6 2002-02-11 23:25:27 adam Exp $ + * $Id: otherinfo.c,v 1.7 2003-01-06 08:20:29 adam Exp $ */ #include diff --git a/zutil/pquery.c b/zutil/pquery.c index 59e2833..2840557 100644 --- a/zutil/pquery.c +++ b/zutil/pquery.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * - * $Id: pquery.c,v 1.19 2002-12-05 12:07:00 adam Exp $ + * $Id: pquery.c,v 1.20 2003-01-06 08:20:29 adam Exp $ */ #include diff --git a/zutil/yaz-ccl.c b/zutil/yaz-ccl.c index 7da9fbd..12456d3 100644 --- a/zutil/yaz-ccl.c +++ b/zutil/yaz-ccl.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1996-2002, Index Data. + * Copyright (c) 1996-2003, Index Data. * See the file LICENSE for details. * - * $Id: yaz-ccl.c,v 1.17 2002-12-28 12:16:26 adam Exp $ + * $Id: yaz-ccl.c,v 1.18 2003-01-06 08:20:29 adam Exp $ */ #include diff --git a/zutil/z3950oid.c b/zutil/z3950oid.c index 90f6b66..95687a0 100644 --- a/zutil/z3950oid.c +++ b/zutil/z3950oid.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2002, Index Data + * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: z3950oid.c,v 1.4 2002-09-20 22:30:01 adam Exp $ + * $Id: z3950oid.c,v 1.5 2003-01-06 08:20:29 adam Exp $ */ #if HAVE_CONFIG_H diff --git a/zutil/zget.c b/zutil/zget.c index dfbb2a6..9ee6801 100644 --- a/zutil/zget.c +++ b/zutil/zget.c @@ -1,9 +1,9 @@ /* - * Copyright (c) 1995-2002, Index Data. + * Copyright (c) 1995-2003, Index Data. * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: zget.c,v 1.12 2002-04-25 08:34:08 adam Exp $ + * $Id: zget.c,v 1.13 2003-01-06 08:20:29 adam Exp $ */ #include diff --git a/zutil/zoom-c.c b/zutil/zoom-c.c index 8506a26..cf5b67f 100644 --- a/zutil/zoom-c.c +++ b/zutil/zoom-c.c @@ -1,12 +1,15 @@ /* - * Copyright (c) 2000-2002, Index Data + * Copyright (c) 2000-2003, Index Data * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.12 2002-12-16 13:13:54 adam Exp $ + * $Id: zoom-c.c,v 1.13 2003-01-06 08:20:29 adam Exp $ * * ZOOM layer for C, connections, result sets, queries. */ #include +#include +#include "zoom-p.h" + #include #include #include @@ -16,7 +19,6 @@ #include #include -#include "zoom-p.h" #if HAVE_SYS_POLL_H #include @@ -27,7 +29,6 @@ typedef enum { zoom_complete } zoom_ret; - static zoom_ret ZOOM_connection_send_init (ZOOM_connection c); static zoom_ret do_write_ex (ZOOM_connection c, char *buf_out, int len_out); @@ -88,6 +89,17 @@ static void set_bib1_error (ZOOM_connection c, int error) c->diagset = "Bib-1"; } +static void set_ZOOM_error (ZOOM_connection c, int error, + const char *addinfo) +{ + xfree (c->addinfo); + c->addinfo = 0; + c->error = error; + c->diagset = "ZOOM"; + if (addinfo) + c->addinfo = xstrdup(addinfo); +} + static void clear_error (ZOOM_connection c) { @@ -99,9 +111,10 @@ static void clear_error (ZOOM_connection c) case ZOOM_ERROR_CONNECTION_LOST: case ZOOM_ERROR_INIT: case ZOOM_ERROR_INTERNAL: + case ZOOM_ERROR_UNSUPPORTED_PROTOCOL: break; default: - set_bib1_error(c, ZOOM_ERROR_NONE); + set_ZOOM_error(c, ZOOM_ERROR_NONE, 0); } } @@ -174,12 +187,13 @@ ZOOM_connection_create (ZOOM_options options) { ZOOM_connection c = (ZOOM_connection) xmalloc (sizeof(*c)); + c->soap = 0; c->cs = 0; c->mask = 0; c->reconnect_ok = 0; c->state = STATE_IDLE; c->addinfo = 0; - set_bib1_error(c, ZOOM_ERROR_NONE); + set_ZOOM_error(c, ZOOM_ERROR_NONE, 0); c->buf_in = 0; c->len_in = 0; c->buf_out = 0; @@ -333,7 +347,7 @@ ZOOM_connection_connect(ZOOM_connection c, c->async = ZOOM_options_get_bool (c->options, "async", 0); - set_bib1_error(c, ZOOM_ERROR_NONE); + set_ZOOM_error(c, ZOOM_ERROR_NONE, 0); task = ZOOM_connection_add_task (c, ZOOM_TASK_CONNECT); @@ -350,7 +364,7 @@ ZOOM_query_create(void) ZOOM_query s = (ZOOM_query) xmalloc (sizeof(*s)); s->refcount = 1; - s->query = 0; + s->z_query = 0; s->sort_spec = 0; s->odr = odr_createmem (ODR_ENCODE); @@ -375,15 +389,35 @@ ZOOM_query_destroy(ZOOM_query s) ZOOM_API(int) ZOOM_query_prefix(ZOOM_query s, const char *str) { - s->query = (Z_Query *) odr_malloc (s->odr, sizeof(*s->query)); - s->query->which = Z_Query_type_1; - s->query->u.type_1 = p_query_rpn(s->odr, PROTO_Z3950, str); - if (!s->query->u.type_1) + s->z_query = (Z_Query *) odr_malloc (s->odr, sizeof(*s->z_query)); + s->z_query->which = Z_Query_type_1; + s->z_query->u.type_1 = p_query_rpn(s->odr, PROTO_Z3950, str); + if (!s->z_query->u.type_1) return -1; return 0; } ZOOM_API(int) +ZOOM_query_cql(ZOOM_query s, const char *str) +{ + Z_External *ext; + char *buf; + int len; + + ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext)); + ext->direct_reference = odr_getoidbystr(s->odr, "1.2.840.10003.16.2"); + ext->indirect_reference = 0; + ext->descriptor = 0; + ext->which = Z_External_CQL; + ext->u.cql = odr_strdup(s->odr, str); + + s->z_query = (Z_Query *) odr_malloc (s->odr, sizeof(*s->z_query)); + s->z_query->which = Z_Query_type_104; + s->z_query->u.type_104 = ext; + return 0; +} + +ZOOM_API(int) ZOOM_query_sortby(ZOOM_query s, const char *criteria) { s->sort_spec = yaz_sort_spec (s->odr, criteria); @@ -400,6 +434,10 @@ ZOOM_connection_destroy(ZOOM_connection c) ZOOM_resultset r; if (!c) return; +#if HAVE_GSOAP + if (c->soap) + soap_end(c->soap); +#endif if (c->cs) cs_close (c->cs); for (r = c->resultsets; r; r = r->next) @@ -444,7 +482,7 @@ ZOOM_resultset ZOOM_resultset_create () r->count = 0; r->record_cache = 0; r->r_sort_spec = 0; - r->r_query = 0; + r->z_query = 0; r->search = 0; r->connection = 0; r->next = 0; @@ -472,7 +510,7 @@ ZOOM_connection_search(ZOOM_connection c, ZOOM_query q) const char *cp; r->r_sort_spec = q->sort_spec; - r->r_query = q->query; + r->z_query = q->z_query; r->search = q; r->options = ZOOM_options_create_with_parent(c->options); @@ -611,32 +649,46 @@ static zoom_ret do_connect (ZOOM_connection c) yaz_log (LOG_DEBUG, "do_connect host=%s", effective_host); assert (!c->cs); - c->cs = cs_create_host (effective_host, 0, &add); - if (c->cs) + if (memcmp(c->host_port, "http:", 5) == 0) + { +#if HAVE_GSOAP + c->soap = soap_new(); + c->soap->namespaces = srw_namespaces; +#else + c->state = STATE_IDLE; + set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW"); +#endif + } + else { - int ret = cs_connect (c->cs, add); - if (ret == 0) + c->cs = cs_create_host (effective_host, 0, &add); + + if (c->cs) { - ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT); - ZOOM_connection_put_event(c, event); - ZOOM_connection_send_init(c); - c->state = STATE_ESTABLISHED; - return zoom_pending; + int ret = cs_connect (c->cs, add); + if (ret == 0) + { + ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT); + ZOOM_connection_put_event(c, event); + ZOOM_connection_send_init(c); + c->state = STATE_ESTABLISHED; + return zoom_pending; + } + else if (ret > 0) + { + c->state = STATE_CONNECTING; + c->mask = ZOOM_SELECT_EXCEPT; + if (c->cs->io_pending & CS_WANT_WRITE) + c->mask += ZOOM_SELECT_WRITE; + if (c->cs->io_pending & CS_WANT_READ) + c->mask += ZOOM_SELECT_READ; + return zoom_pending; + } } - else if (ret > 0) - { - c->state = STATE_CONNECTING; - c->mask = ZOOM_SELECT_EXCEPT; - if (c->cs->io_pending & CS_WANT_WRITE) - c->mask += ZOOM_SELECT_WRITE; - if (c->cs->io_pending & CS_WANT_READ) - c->mask += ZOOM_SELECT_READ; - return zoom_pending; - } + c->state = STATE_IDLE; + set_ZOOM_error(c, ZOOM_ERROR_CONNECT, effective_host); } - c->state = STATE_IDLE; - set_bib1_error(c, ZOOM_ERROR_CONNECT); return zoom_complete; } @@ -715,7 +767,7 @@ static int encode_APDU(ZOOM_connection c, Z_APDU *a, ODR out) odr_destroy(odr_pr); } yaz_log (LOG_DEBUG, "encoding failed"); - set_bib1_error(c, ZOOM_ERROR_ENCODE); + set_ZOOM_error(c, ZOOM_ERROR_ENCODE, 0); odr_reset(out); return -1; } @@ -880,10 +932,10 @@ static zoom_ret ZOOM_connection_send_search (ZOOM_connection c) mediumSetElementSetName = elementSetName; assert (r); - assert (r->r_query); + assert (r->z_query); /* prepare query for the search request */ - search_req->query = r->r_query; + search_req->query = r->z_query; search_req->databaseNames = set_DatabaseNames (c, r->options, &search_req->num_databaseNames); @@ -979,7 +1031,7 @@ static void response_diag (ZOOM_connection c, Z_DiagRec *p) c->addinfo = 0; if (p->which != Z_DiagRec_defaultFormat) { - set_bib1_error(c, ZOOM_ERROR_DECODE); + set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); return; } r = p->u.defaultFormat; @@ -1235,7 +1287,6 @@ static void record_cache_add (ZOOM_resultset r, Z_NamePlusRecord *npr, int pos) const char *syntax = ZOOM_resultset_option_get (r, "preferredRecordSyntax"); - for (rc = r->record_cache; rc; rc = rc->next) { if (pos == rc->pos) @@ -1332,7 +1383,7 @@ static void handle_records (ZOOM_connection c, Z_Records *sr, if (sr->u.multipleNonSurDiagnostics->num_diagRecs >= 1) response_diag(c, sr->u.multipleNonSurDiagnostics->diagRecs[0]); else - set_bib1_error(c, ZOOM_ERROR_DECODE); + set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); } else { @@ -1357,13 +1408,13 @@ static void handle_records (ZOOM_connection c, Z_Records *sr, if (present_phase && p->num_records == 0) { /* present response and we didn't get any records! */ - c->error = ZOOM_ERROR_DECODE; + set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); } } else if (present_phase) { /* present response and we didn't get any records! */ - set_bib1_error(c, ZOOM_ERROR_DECODE); + set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); } } } @@ -1936,6 +1987,84 @@ ZOOM_package_option_get (ZOOM_package p, const char *key) return ZOOM_options_get (p->options, key); } +#if HAVE_GSOAP +static zoom_ret ZOOM_srw_search(ZOOM_connection c, ZOOM_resultset r, + const char *cql) +{ + int ret; + struct xcql__operandType *xQuery = 0; + char *action = 0; + xsd__integer startRecord = r->start + 1; + xsd__integer maximumRecord = r->count; + const char *schema = ZOOM_resultset_option_get (r, "schema"); + struct zs__searchRetrieveResponse res; + xsd__string recordPacking = 0; + + + if (!schema) + schema = "http://www.loc.gov/marcxml/"; + + ret = soap_call_zs__searchRetrieveRequest(c->soap, c->host_port, + action, + &r->z_query->u.type_104->u.cql, + xQuery, + 0, 0, + &startRecord, &maximumRecord, + (char **) &schema, + &recordPacking, + &res); + if (ret != SOAP_OK) + { + const char **s = soap_faultdetail(c->soap); + xfree (c->addinfo); + c->addinfo = 0; + if (s && *s) + c->addinfo = xstrdup(*s); + c->diagset = "SOAP"; + c->error = ret; + } + else + { + if (res.diagnostics.__sizeDiagnostics > 0) + { + int i = 0; + xfree (c->addinfo); + c->addinfo = 0; + c->diagset = "SRW"; + c->error = res.diagnostics.diagnostic[i]->code; + if (res.diagnostics.diagnostic[i]->details) + c->addinfo = + xstrdup(res.diagnostics.diagnostic[i]->details); + + } + else + { + int i; + r->size = res.numberOfRecords; + if (res.resultSetId) + r->setname = xstrdup(res.resultSetId); + for (i = 0; i < res.records.__sizeRecords; i++) + { + char *rdata = res.records.record[i]->recordData; + if (rdata) + { + Z_NamePlusRecord *npr = + odr_malloc(r->odr, sizeof(*npr)); + Z_External *ext = + z_ext_record(r->odr, VAL_TEXT_XML, + rdata, strlen(rdata)); + npr->databaseName = 0; + npr->which = Z_NamePlusRecord_databaseRecord; + npr->u.databaseRecord = ext; + record_cache_add (r, npr, r->start + i); + } + } + } + } + return zoom_complete; +} +#endif + ZOOM_API(void) ZOOM_package_option_set (ZOOM_package p, const char *key, const char *val) @@ -1955,8 +2084,7 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) } yaz_log (LOG_DEBUG, "ZOOM_connection_exec_task type=%d run=%d", task->which, task->running); - if (c->error != ZOOM_ERROR_NONE || - (!c->cs && task->which != ZOOM_TASK_CONNECT)) + if (c->error != ZOOM_ERROR_NONE) { yaz_log (LOG_DEBUG, "remove tasks because of error = %d", c->error); ZOOM_connection_remove_tasks (c); @@ -1968,23 +2096,67 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) return 0; } task->running = 1; - switch (task->which) + ret = zoom_complete; + if (c->soap) { - case ZOOM_TASK_SEARCH: - ret = ZOOM_connection_send_search (c); - break; - case ZOOM_TASK_RETRIEVE: - ret = send_present (c); - break; - case ZOOM_TASK_CONNECT: - ret = do_connect(c); - break; - case ZOOM_TASK_SCAN: - ret = send_scan(c); - break; - case ZOOM_TASK_PACKAGE: - ret = send_package(c); - break; +#if HAVE_GSOAP + ZOOM_resultset resultset; + switch (task->which) + { + case ZOOM_TASK_SEARCH: + resultset = c->tasks->u.search.resultset; + if (resultset->z_query && + resultset->z_query->which == Z_Query_type_104 + && resultset->z_query->u.type_104->which == Z_External_CQL) + ret = ZOOM_srw_search(c, resultset, + resultset->z_query->u.type_104->u.cql); + break; + case ZOOM_TASK_RETRIEVE: + resultset = c->tasks->u.retrieve.resultset; + resultset->start = c->tasks->u.retrieve.start; + resultset->count = c->tasks->u.retrieve.count; + + if (resultset->start >= resultset->size) + return zoom_complete; + if (resultset->start + resultset->count > resultset->size) + resultset->count = resultset->size - resultset->start; + + if (resultset->z_query && + resultset->z_query->which == Z_Query_type_104 + && resultset->z_query->u.type_104->which == Z_External_CQL) + ret = ZOOM_srw_search(c, resultset, + resultset->z_query->u.type_104->u.cql); + break; + } +#else + ; +#endif + } + else if (c->cs || task->which == ZOOM_TASK_CONNECT) + { + switch (task->which) + { + case ZOOM_TASK_SEARCH: + ret = ZOOM_connection_send_search(c); + break; + case ZOOM_TASK_RETRIEVE: + ret = send_present (c); + break; + case ZOOM_TASK_CONNECT: + ret = do_connect(c); + break; + case ZOOM_TASK_SCAN: + ret = send_scan(c); + break; + case ZOOM_TASK_PACKAGE: + ret = send_package(c); + break; + } + } + else + { + yaz_log (LOG_DEBUG, "remove tasks because no connection exist"); + ZOOM_connection_remove_tasks (c); } if (ret == zoom_complete) { @@ -2046,7 +2218,7 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) initrs->implementationVersion : ""); if (!*initrs->result) { - set_bib1_error(c, ZOOM_ERROR_INIT); + set_ZOOM_error(c, ZOOM_ERROR_INIT, 0); } else { @@ -2124,12 +2296,12 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) } else { - set_bib1_error(c, ZOOM_ERROR_CONNECTION_LOST); + set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, 0); do_close(c); } break; default: - set_bib1_error(c, ZOOM_ERROR_DECODE); + set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); do_close(c); } } @@ -2160,7 +2332,7 @@ static int do_read (ZOOM_connection c) } else { - c->error= ZOOM_ERROR_CONNECTION_LOST; + set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, 0); do_close (c); } } @@ -2173,7 +2345,7 @@ static int do_read (ZOOM_connection c) ZOOM_connection_put_event (c, event); if (!z_APDU (c->odr_in, &apdu, 0, 0)) { - set_bib1_error(c, ZOOM_ERROR_DECODE); + set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); do_close (c); } else @@ -2204,9 +2376,9 @@ static zoom_ret do_write_ex (ZOOM_connection c, char *buf_out, int len_out) return zoom_complete; } if (c->state == STATE_CONNECTING) - set_bib1_error(c, ZOOM_ERROR_CONNECT); + set_ZOOM_error(c, ZOOM_ERROR_CONNECT, 0); else - set_bib1_error(c, ZOOM_ERROR_CONNECTION_LOST); + set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, 0); do_close (c); return zoom_complete; } @@ -2305,6 +2477,8 @@ ZOOM_diag_str (int error) return "Internal failure"; case ZOOM_ERROR_TIMEOUT: return "Timeout"; + case ZOOM_ERROR_UNSUPPORTED_PROTOCOL: + return "Unsupported protocol"; default: return diagbib1_str (error); } @@ -2317,7 +2491,22 @@ ZOOM_connection_error_x (ZOOM_connection c, const char **cp, int error = c->error; if (cp) { - *cp = ZOOM_diag_str(error); + if (!c->diagset) + *cp = ZOOM_diag_str(error); +#if HAVE_GSOAP + else if (!strcmp(c->diagset, "SRW")) + *cp = yaz_srw_diag_str(error); + else if (c->soap && !strcmp(c->diagset, "SOAP")) + { + const char **s = soap_faultstring(c->soap); + if (s && *s) + *cp = *s; + else + *cp = "unknown"; + } +#endif + else + *cp = ZOOM_diag_str(error); } if (addinfo) *addinfo = c->addinfo ? c->addinfo : ""; @@ -2343,7 +2532,7 @@ static int ZOOM_connection_do_io(ZOOM_connection c, int mask) if (r == CS_NONE) { event = ZOOM_Event_create (ZOOM_EVENT_CONNECT); - set_bib1_error(c, ZOOM_ERROR_CONNECT); + set_ZOOM_error(c, ZOOM_ERROR_CONNECT, 0); do_close (c); ZOOM_connection_put_event (c, event); } @@ -2371,7 +2560,7 @@ static int ZOOM_connection_do_io(ZOOM_connection c, int mask) } else { - set_bib1_error(c, ZOOM_ERROR_CONNECT); + set_ZOOM_error(c, ZOOM_ERROR_CONNECT, 0); do_close (c); ZOOM_connection_put_event (c, event); } @@ -2520,7 +2709,7 @@ ZOOM_event (int no, ZOOM_connection *cs) { ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT); /* timeout and this connection was waiting */ - set_bib1_error(c, ZOOM_ERROR_TIMEOUT); + set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT, 0); do_close (c); ZOOM_connection_put_event(c, event); } @@ -2556,7 +2745,7 @@ ZOOM_event (int no, ZOOM_connection *cs) { ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT); /* timeout and this connection was waiting */ - set_bib1_error(c, ZOOM_ERROR_TIMEOUT); + set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT); do_close (c); yaz_log (LOG_DEBUG, "timeout"); ZOOM_connection_put_event(c, event); diff --git a/zutil/zoom-opt.c b/zutil/zoom-opt.c index 9e789b6..02a7ae0 100644 --- a/zutil/zoom-opt.c +++ b/zutil/zoom-opt.c @@ -1,14 +1,13 @@ /* - * $Id: zoom-opt.c,v 1.2 2002-09-24 08:05:42 adam Exp $ + * $Id: zoom-opt.c,v 1.3 2003-01-06 08:20:29 adam Exp $ * * ZOOM layer for C, options handling */ #include -#include -#include - #include "zoom-p.h" +#include + ZOOM_API(ZOOM_options) ZOOM_options_create_with_parent (ZOOM_options parent) { diff --git a/zutil/zoom-p.h b/zutil/zoom-p.h index c8210e0..0f7a81e 100644 --- a/zutil/zoom-p.h +++ b/zutil/zoom-p.h @@ -1,17 +1,25 @@ /* * Private C header for ZOOM C. - * $Id: zoom-p.h,v 1.2 2002-12-09 23:32:29 adam Exp $ + * $Id: zoom-p.h,v 1.3 2003-01-06 08:20:29 adam Exp $ */ + +#if HAVE_GSOAP +#include +#else +struct soap { + int dummy; +}; +#endif + #include #include #include #include #include - typedef struct ZOOM_Event_p *ZOOM_Event; struct ZOOM_query_p { - Z_Query *query; + Z_Query *z_query; Z_SortKeySpecList *sort_spec; int refcount; ODR odr; @@ -26,6 +34,7 @@ struct ZOOM_query_p { #define ZOOM_SELECT_EXCEPT 4 struct ZOOM_connection_p { + struct soap *soap; COMSTACK cs; char *host_port; int error; @@ -75,7 +84,7 @@ struct ZOOM_options_p { typedef struct ZOOM_record_cache_p *ZOOM_record_cache; struct ZOOM_resultset_p { - Z_Query *r_query; + Z_Query *z_query; Z_SortKeySpecList *r_sort_spec; ZOOM_query search; int refcount;