SOAP, SRW codecs and HTTP transport for YAZ using libxml2.
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 12 Feb 2003 15:06:42 +0000 (15:06 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 12 Feb 2003 15:06:42 +0000 (15:06 +0000)
Updated ASN.1 for Z39.50 amendment String Identifiers for Schemas.

44 files changed:
CHANGELOG
Makefile.am
client/client.c
configure.in
include/yaz/Makefile.am
include/yaz/backend.h
include/yaz/odr.h
include/yaz/proto.h
include/yaz/soap.h [new file with mode: 0644]
include/yaz/srw-util.h [deleted file]
include/yaz/srw.h [new file with mode: 0644]
include/yaz/yaz-iconv.h
lib/Makefile.am
odr/ber_any.c
odr/odr.c
server/Makefile.am
server/eventl.c
server/eventl.h
server/requestq.c
server/seshigh.c
server/session.h
server/statserv.c
srw/Makefile.am [deleted file]
srw/srw-diag.c [deleted file]
srw/srw-namespace.c [deleted file]
srw/srw-server.c [deleted file]
srw/srw-xcql.c [deleted file]
srw/srw-xslt.c [deleted file]
srw/zing.h [deleted file]
srwapps/Makefile.am [deleted file]
srwapps/srw-client.c [deleted file]
srwapps/srw-gateway.c [deleted file]
util/matchstr.c
yaz-config.in
z39.50/z3950v3.asn
zoom/Makefile.am
ztest/Makefile.am
zutil/Makefile.am
zutil/logrpn.c
zutil/soap.c [new file with mode: 0644]
zutil/srw.c [new file with mode: 0644]
zutil/yaz-ccl.c
zutil/zgdu.c [new file with mode: 0644]
zutil/zoom-c.c

index 0bbd392..29dc685 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,9 +3,8 @@ Possible compatibility problems with earlier versions marked with '*'.
 --- 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. 
+libxml and libxslt to operate. Enable it by specifying --with-xslt for
+configure. 
 
 Z39.50 Query Type-104 added - to facilitate CQL within Z39.50.
 
index 4c1ea35..bf83b43 100644 (file)
@@ -1,10 +1,10 @@
 ## Copyright (C) 1994-2003, Index Data
 ## All rights reserved.
-## $Id: Makefile.am,v 1.18 2003-01-06 08:20:26 adam Exp $
+## $Id: Makefile.am,v 1.19 2003-02-12 15:06:42 adam Exp $
 
 AUTOMAKE_OPTIONS = foreign 
 
-SUBDIRS = util odr comstack z39.50 ill srw zutil ccl cql server include lib client ztest zoom srwapps doc etc
+SUBDIRS = util odr comstack z39.50 ill zutil ccl cql server include lib client ztest zoom doc etc
 
 aclocaldir=$(datadir)/aclocal
 
index bb3b465..ddeacaf 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: client.c,v 1.179 2003-01-27 21:31:35 adam Exp $
+ * $Id: client.c,v 1.180 2003-02-12 15:06:43 adam Exp $
  */
 
 #include <stdio.h>
@@ -1788,13 +1788,14 @@ static int send_presentRequest(char *arg)
 
         compo.u.complex->generic = (Z_Specification *)
             odr_malloc(out, sizeof(*compo.u.complex->generic));
-        compo.u.complex->generic->schema = (Odr_oid *)
+        compo.u.complex->generic->which = Z_Specification_oid;
+        compo.u.complex->generic->u.oid = (Odr_oid *)
             odr_oiddup(out, oid_ent_to_oid(&prefschema, oid));
-        if (!compo.u.complex->generic->schema)
+        if (!compo.u.complex->generic->u.oid)
         {
             /* OID wasn't a schema! Try record syntax instead. */
             prefschema.oclass = CLASS_RECSYN;
-            compo.u.complex->generic->schema = (Odr_oid *)
+            compo.u.complex->generic->u.oid = (Odr_oid *)
                 odr_oiddup(out, oid_ent_to_oid(&prefschema, oid));
         }
         if (!elementSetNames)
index f8a4a0e..4763db1 100644 (file)
@@ -1,6 +1,6 @@
 dnl YAZ Toolkit, Index Data 1994-2003
 dnl See the file LICENSE for details.
-dnl $Id: configure.in,v 1.102 2003-02-10 08:59:00 adam Exp $
+dnl $Id: configure.in,v 1.103 2003-02-12 15:06:42 adam Exp $
 AC_INIT(include/yaz/yaz-version.h)
 AM_INIT_AUTOMAKE(yaz, 1.9.3)
 dnl
@@ -308,35 +308,6 @@ 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)
@@ -384,7 +355,6 @@ yaz.spec
 util/Makefile
 odr/Makefile
 z39.50/Makefile
-srw/Makefile
 ill/Makefile
 zutil/Makefile
 comstack/Makefile
@@ -393,7 +363,6 @@ cql/Makefile
 server/Makefile
 include/Makefile
 include/yaz/Makefile
-srwapps/Makefile
 lib/Makefile
 client/Makefile
 ztest/Makefile
index 5bf7713..db28269 100644 (file)
@@ -1,8 +1,8 @@
-## $Id: Makefile.am,v 1.19 2003-01-06 08:20:27 adam Exp $
+## $Id: Makefile.am,v 1.20 2003-02-12 15:06:43 adam Exp $
 
 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 srw-util.h statserv.h \
+ options.h otherinfo.h pquery.h prt-ext.h readconf.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 \
  \
@@ -11,5 +11,5 @@ pkginclude_HEADERS= backend.h ccl.h cql.h comstack.h \
  z-grs.h z-mterm2.h z-opac.h z-rrf1.h z-rrf2.h z-sum.h z-sutrs.h z-uifr1.h \
  z-univ.h zes-expi.h zes-exps.h zes-order.h zes-pquery.h \
  zes-psched.h zes-admin.h zes-pset.h zes-update.h zes-update0.h \
- zoom.h z-charneg.h charneg.h
+ zoom.h z-charneg.h charneg.h soap.h srw.h
 
index 27343c2..1e0ffff 100644 (file)
@@ -23,7 +23,7 @@
  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  *
- * $Id: backend.h,v 1.17 2003-01-06 08:20:27 adam Exp $
+ * $Id: backend.h,v 1.18 2003-02-12 15:06:43 adam Exp $
  */
 
 #ifndef BACKEND_H
@@ -259,8 +259,38 @@ typedef struct statserv_options_block
     char service_dependencies[128]; /* The services we are dependent on */
     char service_display_name[128]; /* The service display name */
 #endif /* WIN32 */
+    struct bend_soap_handler *soap_handlers;
 } statserv_options_block;
 
+struct bend_http_rr {
+    void *handle;
+    ODR stream;           /* encoding stream */
+    ODR decode;           /* decoding stream */
+    ODR print;            /* print stream */
+    Z_HTTP_Request *hreq; /* whole HTTP request */
+    char *buf;
+    int len;
+};
+
+struct bend_soap_rr {
+    void *handle;         /* user handle */
+    ODR stream;
+    ODR decode;
+    ODR print;
+    const char *ns_env;         /* SOAP NS */
+    const char *ns_enc;         /* SOAP Encoding NS */
+    void *request_method;
+    void *response_body;
+    char *fault_code;
+    char *fault_string;
+};
+
+struct bend_soap_handler {
+    char *ns;
+    int (*handler)(struct bend_soap_rr *rr);
+    struct bend_soap_handler *next;
+};
+    
 YAZ_EXPORT int statserv_main(
     int argc, char **argv,
     bend_initresult *(*bend_init)(bend_initrequest *r),
@@ -271,6 +301,9 @@ YAZ_EXPORT statserv_options_block *statserv_getcontrol(void);
 YAZ_EXPORT void statserv_setcontrol(statserv_options_block *block);
 YAZ_EXPORT int check_ip_tcpd(void *cd, const char *addr, int len, int type);
 
+YAZ_EXPORT void statserv_add_soap_handler(int (*h)(struct bend_soap_rr *rr),
+                                          const char *ns);
+
 YAZ_END_CDECL
 
 #endif
index 629b7f6..a95d9e1 100644 (file)
@@ -23,7 +23,7 @@
  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  *
- * $Id: odr.h,v 1.7 2003-01-06 08:20:27 adam Exp $
+ * $Id: odr.h,v 1.8 2003-02-12 15:06:43 adam Exp $
  */
 
 #ifndef ODR_H
@@ -178,6 +178,7 @@ typedef struct odr_arm
 #define OSTACK          9
 #define OCONLEN        10
 #define OLENOV         11
+#define OHTTP          12
 
 extern char *odr_errlist[];
 
index cf3858b..f1bf623 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: proto.h,v 1.6 2003-01-06 08:20:27 adam Exp $
+ * $Id: proto.h,v 1.7 2003-02-12 15:06:43 adam Exp $
  */
 #ifndef Z_PROTO_H
 #define Z_PROTO_H
@@ -110,6 +110,51 @@ YAZ_EXPORT const char* yaz_z3950_oid_value_to_str(oid_value ov, oid_class oc);
 
 YAZ_EXPORT void yaz_display_grs1(WRBUF wrbuf, Z_GenericRecord *r, int flags);
 
+typedef struct Z_HTTP_Header Z_HTTP_Header;
+
+struct Z_HTTP_Header {
+    char *name;
+    char *value;
+    Z_HTTP_Header *next;
+};
+
+typedef struct {
+    char *method;
+    char *version;
+    char *path;
+    Z_HTTP_Header *headers;
+    char *content_buf;
+    int content_len;
+} Z_HTTP_Request;
+
+typedef struct {
+    int code;
+    char *version;
+    Z_HTTP_Header *headers;
+    char *content_buf;
+    int content_len;
+} Z_HTTP_Response;
+
+#define Z_GDU_Z3950         1
+#define Z_GDU_HTTP_Request  2
+#define Z_GDU_HTTP_Response 3
+typedef struct {
+    int which;
+    union {
+        Z_APDU *z3950;
+        Z_HTTP_Request *HTTP_Request;
+        Z_HTTP_Response *HTTP_Response;
+    } u;
+} Z_GDU ;
+YAZ_EXPORT int z_GDU (ODR o, Z_GDU **p, int opt, const char *name);
+YAZ_EXPORT void z_HTTP_header_add(ODR o, Z_HTTP_Header **hp, const char *n,
+                                  const char *v);
+YAZ_EXPORT const char *z_HTTP_header_lookup(Z_HTTP_Header *hp, const char *n);
+
+YAZ_EXPORT const char *z_HTTP_errmsg(int code);
+
+YAZ_EXPORT Z_GDU *z_get_HTTP_Response(ODR o, int code);
+
 YAZ_END_CDECL
 
 #include <yaz/prt-ext.h>
diff --git a/include/yaz/soap.h b/include/yaz/soap.h
new file mode 100644 (file)
index 0000000..9c60462
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2002-2003, Index Data.
+ * See the file LICENSE for details.
+ *
+ * $Id: soap.h,v 1.1 2003-02-12 15:06:43 adam Exp $
+ */
+
+#ifndef YAZ_SOAP_H
+#define YAZ_SOAP_H
+
+#include <yaz/odr.h>
+
+#if HAVE_XSLT
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#endif
+
+typedef struct {
+    char *fault_code;
+    char *fault_string;
+    char *details;
+} Z_SOAP_Fault;
+
+typedef struct {
+    int no;
+    char *ns;
+    void *p;
+} Z_SOAP_Generic;
+
+#define Z_SOAP_fault 1
+#define Z_SOAP_generic 2
+#define Z_SOAP_error 3
+typedef struct {
+    int which;
+    union {
+        Z_SOAP_Fault   *fault;
+        Z_SOAP_Generic *generic;
+        Z_SOAP_Fault   *soap_error;
+    } u;
+    const char *ns;
+} Z_SOAP;
+
+typedef struct {
+    char *ns;
+    void *client_data;
+    int (*f)(ODR o, xmlNodePtr ptr, void **handler_data,
+             void *client_data, const char *ns);
+} Z_SOAP_Handler;
+
+YAZ_EXPORT int z_soap_codec(ODR o, Z_SOAP **pp, 
+                            char **content_buf, int *content_len,
+                            Z_SOAP_Handler *handlers);
+
+#endif
diff --git a/include/yaz/srw-util.h b/include/yaz/srw-util.h
deleted file mode 100644 (file)
index a180c0a..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* $Id: srw-util.h,v 1.2 2003-01-20 13:04:50 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 <yaz/cql.h>
-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,
-                    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/srw.h b/include/yaz/srw.h
new file mode 100644 (file)
index 0000000..5f29e40
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2002-2003, Index Data.
+ * See the file LICENSE for details.
+ *
+ * $Id: srw.h,v 1.1 2003-02-12 15:06:43 adam Exp $
+ */
+
+#ifndef YAZ_SRW_H
+#define YAZ_SRW_H
+
+#include <yaz/soap.h>
+
+typedef struct {
+    char *recordSchema;
+    char *recordData_buf;
+    int recordData_len;
+    int *recordPosition;
+} Z_SRW_record;
+
+typedef struct {
+    int  *code;
+    char *details;
+} Z_SRW_diagnostic;
+    
+typedef struct {
+    char *query;
+    char *pQuery;
+    void *xQuery;
+    char *sortKeys;
+    void *xSortKeys;
+    int *startRecord;
+    int  *maximumRecords;
+    char *recordSchema;
+    char *recordPacking;
+} Z_SRW_searchRetrieveRequest;
+
+typedef struct {
+    int * numberOfRecords;
+    char * resultSetId;
+    int * resultSetIdleTime;
+    
+    Z_SRW_record *records;
+    int num_records;
+
+    Z_SRW_diagnostic *diagnostics;
+    int num_diagnostics;
+    int *nextRecordPosition;
+} Z_SRW_searchRetrieveResponse;
+
+#define Z_SRW_searchRetrieve_request  1
+#define Z_SRW_searchRetrieve_response 2
+
+typedef struct {
+    int which;
+    union {
+        Z_SRW_searchRetrieveRequest *request;
+        Z_SRW_searchRetrieveResponse *response;
+    } u;
+} Z_SRW_searchRetrieve;
+
+YAZ_EXPORT int yaz_srw_codec(ODR o, xmlNodePtr pptr,
+                             Z_SRW_searchRetrieve **handler_data,
+                             void *client_data, const char *ns);
+YAZ_EXPORT Z_SRW_searchRetrieve *yaz_srw_get(ODR o, int which);
+#endif
index a039280..322f7f7 100644 (file)
@@ -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.2 2003-01-06 08:20:27 adam Exp $
+ * $Id: yaz-iconv.h,v 1.3 2003-02-12 15:06:43 adam Exp $
  */
 
 #ifndef YAZ_ICONV_H
@@ -49,6 +49,8 @@ YAZ_EXPORT int yaz_iconv_isbuiltin(yaz_iconv_t cd);
 
 YAZ_EXPORT int yaz_matchstr(const char *s1, const char *s2);
 
+YAZ_EXPORT int yaz_strcmp_del(const char *a, const char *b, const char *b_del);
+
 YAZ_END_CDECL
 
 #endif
index 8fd9e3b..549ce23 100644 (file)
@@ -1,10 +1,4 @@
-## $Id: Makefile.am,v 1.25 2003-01-06 08:20:27 adam Exp $
-
-if SRW
-libsrw=../srw/libsrw.la
-else
-libsrw=
-endif
+## $Id: Makefile.am,v 1.26 2003-02-12 15:06:43 adam Exp $
 
 if ISTHR
 extra=libyazthread.la
@@ -81,5 +75,5 @@ 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 ../cql/libcql.la ../zutil/libzutil.la \
- ../ill/libill.la ../z39.50/libz39.50.la $(libsrw)
+ ../ill/libill.la ../z39.50/libz39.50.la
 
index 1280040..5328dee 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: ber_any.c,v 1.20 2003-01-06 08:20:27 adam Exp $
+ * $Id: ber_any.c,v 1.21 2003-02-12 15:06:43 adam Exp $
  */
 #if HAVE_CONFIG_H
 #include <config.h>
@@ -47,6 +47,47 @@ int completeBER(const unsigned char *buf, int len)
        return 0;
     if (!buf[0] && !buf[1])
        return 0;
+    if (len > 5 && buf[0] >= 0x20 && buf[0] < 0x7f
+               && buf[1] >= 0x20 && buf[1] < 0x7f
+               && buf[2] >= 0x20 && buf[2] < 0x7f)
+    {
+        /* deal with HTTP request/response */
+       int i = 2, content_len = 0;
+
+        while (i <= len-4)
+        {
+            if (buf[i] == '\r' && buf[i+1] == '\n')
+            {
+                i += 2;
+                if (buf[i] == '\r' && buf[i+1] == '\n')
+                {
+                    /* i += 2 seems not to work with GCC -O2 .. 
+                       so i+2 is used instead .. */
+                    if (len >= (i+2)+ content_len)
+                        return (i+2)+ content_len;
+                    break;
+                }
+                if (i < len-18)
+                {
+                    if (!memcmp(buf+i, "Content-Length:", 15))
+                    {
+                        i+= 15;
+                        if (buf[i] == ' ')
+                            i++;
+                        content_len = 0;
+                        while (i <= len-4 && isdigit(buf[i]))
+                            content_len = content_len*10 + (buf[i++] - '0');
+                        if (content_len < 0) /* prevent negative offsets */
+                            content_len = 0;
+                    }
+                }
+            }
+            else
+                i++;
+        }
+        return 0;
+    }
+    /* BER from now on .. */
     if ((res = ber_dectag(b, &zclass, &tag, &cons)) <= 0)
        return 0;
     if (res > len)
index 22f9b21..1f8a625 100644 (file)
--- a/odr/odr.c
+++ b/odr/odr.c
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: odr.c,v 1.39 2003-01-06 08:20:27 adam Exp $
+ * $Id: odr.c,v 1.40 2003-02-12 15:06:43 adam Exp $
  *
  */
 #if HAVE_CONFIG_H
@@ -35,7 +35,8 @@ char *odr_errlist[] =
     "Malformed data",
     "Stack overflow",
     "Length of constructed type different from sum of members",
-    "Overflow writing definite length of constructed type"
+    "Overflow writing definite length of constructed type",
+    "HTTP Bad Request"
 };
 
 char *odr_errmsg(int n)
index 9c209d5..9bc6a8a 100644 (file)
@@ -1,4 +1,4 @@
-## $Id: Makefile.am,v 1.7 2002-09-11 21:25:57 adam Exp $
+## $Id: Makefile.am,v 1.8 2003-02-12 15:06:43 adam Exp $
 
 noinst_LTLIBRARIES=libserver.la
 
@@ -7,4 +7,4 @@ libserver_la_SOURCES = eventl.c seshigh.c statserv.c requestq.c tcpdchk.c \
 
 EXTRA_DIST=service.c
 
-AM_CPPFLAGS=-I$(top_srcdir)/include 
+AM_CPPFLAGS=-I$(top_srcdir)/include  $(XSLT_CFLAGS)
index ce38bd8..541bba4 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * Copyright (c) 1995-2001, Index Data
+ * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: eventl.c,v 1.34 2002-11-26 16:56:21 adam Exp $
+ * $Id: eventl.c,v 1.35 2003-02-12 15:06:43 adam Exp $
  */
 
 #include <stdio.h>
@@ -74,6 +74,8 @@ int event_loop(IOCHAN *iochans)
        max = 0;
        for (p = *iochans; p; p = p->next)
        {
+            yaz_log(LOG_LOG, "fd=%d flags=%d force_event=%d",
+                    p->fd, p->flags, p->force_event);
            if (p->force_event)
                timeout = &nullto;        /* polling select */
            if (p->flags & EVENT_INPUT)
@@ -85,7 +87,9 @@ int event_loop(IOCHAN *iochans)
            if (p->fd > max)
                max = p->fd;
        }
+        yaz_log(LOG_LOG, "select start");
        res = YAZ_EV_SELECT(max + 1, &in, &out, &except, timeout);
+        yaz_log(LOG_LOG, "select end");
        if (res < 0)
        {
            if (yaz_errno() == EINTR)
index db3e636..95e45a4 100644 (file)
@@ -1,44 +1,9 @@
 /*
- * Copyright (c) 1995-1999, Index Data
+ * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Log: eventl.h,v $
- * Revision 1.11  1999-04-20 09:56:48  adam
- * Added 'name' paramter to encoder/decoder routines (typedef Odr_fun).
- * Modified all encoders/decoders to reflect this change.
- *
- * Revision 1.10  1998/01/29 13:30:23  adam
- * Better event handle system for NT/Unix.
- *
- * Revision 1.9  1997/09/01 09:31:48  adam
- * Removed definition statserv_remove from statserv.h to eventl.h.
- *
- * Revision 1.8  1995/06/19 12:39:09  quinn
- * Fixed bug in timeout code. Added BER dumper.
- *
- * Revision 1.7  1995/06/16  10:31:34  quinn
- * Added session timeout.
- *
- * Revision 1.6  1995/05/16  08:51:02  quinn
- * License, documentation, and memory fixes
- *
- * Revision 1.5  1995/05/15  11:56:37  quinn
- * Asynchronous facilities. Restructuring of seshigh code.
- *
- * Revision 1.4  1995/03/27  08:34:23  quinn
- * Added dynamic server functionality.
- * Released bindings to session.c (is now redundant)
- *
- * Revision 1.3  1995/03/15  08:37:42  quinn
- * Now we're pretty much set for nonblocking I/O.
- *
- * Revision 1.2  1995/03/14  10:28:00  quinn
- * More work on demo server.
- *
- * Revision 1.1  1995/03/10  18:22:45  quinn
- * The rudiments of an asynchronous server.
- *
+ * $Id: eventl.h,v 1.12 2003-02-12 15:06:43 adam Exp $
  */
 
 #ifndef EVENTL_H
index 7c8ee00..26d9b43 100644 (file)
@@ -4,7 +4,11 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: requestq.c,v $
- * Revision 1.8  2001-07-19 19:51:41  adam
+ * Revision 1.9  2003-02-12 15:06:43  adam
+ * SOAP, SRW codecs and HTTP transport for YAZ using libxml2.
+ * Updated ASN.1 for Z39.50 amendment String Identifiers for Schemas.
+ *
+ * Revision 1.8  2001/07/19 19:51:41  adam
  * Added typecasts to make C++ happy.
  *
  * Revision 1.7  1999/11/30 13:47:12  adam
@@ -108,6 +112,7 @@ request *request_get(request_q *q)
     r->q = q;
     r->len_refid = 0;
     r->refid = 0;
+    r->gdu_request = 0;
     r->apdu_request = 0;
     r->request_mem = 0;
     r->len_response = 0;
index 59361f5..9ba52f6 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: seshigh.c,v 1.133 2003-01-06 08:20:28 adam Exp $
+ * $Id: seshigh.c,v 1.134 2003-02-12 15:06:43 adam Exp $
  */
 
 /*
 #include <yaz/diagbib1.h>
 #include <yaz/charneg.h>
 #include <yaz/otherinfo.h>
+#include <yaz/yaz-util.h>
 
+#include <yaz/srw.h>
 #include <yaz/backend.h>
 
-static int process_request(association *assoc, request *req, char **msg);
+static void process_gdu_request(association *assoc, request *req);
+static int process_z_request(association *assoc, request *req, char **msg);
 void backend_response(IOCHAN i, int event);
-static int process_response(association *assoc, request *req, Z_APDU *res);
+static int process_gdu_response(association *assoc, request *req, Z_GDU *res);
+static int process_z_response(association *assoc, request *req, Z_APDU *res);
 static Z_APDU *process_initRequest(association *assoc, request *reqb);
 static Z_APDU *process_searchRequest(association *assoc, request *reqb,
     int *fd);
@@ -72,9 +76,7 @@ static Z_APDU *process_segmentRequest (association *assoc, request *reqb);
 static FILE *apduf = 0; /* for use in static mode */
 static statserv_options_block *control_block = 0;
 
-/* Chas: Added in from DALI */
 static Z_APDU *process_ESRequest(association *assoc, request *reqb, int *fd);
-/* Chas: End of addition from DALI */
 
 /*
  * Create and initialize a new association-handle.
@@ -195,7 +197,7 @@ static void do_close_req(association *a, int reason, char *message,
        apdu.u.close = cls;
        *cls->closeReason = reason;
        cls->diagnosticInformation = message;
-       process_response(a, req, &apdu);
+       process_z_response(a, req, &apdu);
        iochan_settimeout(a->client_chan, 60);
     }
     else
@@ -305,22 +307,34 @@ void ir_session(IOCHAN h, int event)
                iochan_setevent(h, EVENT_INPUT);
                
            /* we got a complete PDU. Let's decode it */
-           yaz_log(LOG_DEBUG, "Got PDU, %d bytes", res);
+           yaz_log(LOG_DEBUG, "Got PDU, %d bytes: lead=%02X %02X %02X", res,
+                           assoc->input_buffer[0] & 0xff,
+                           assoc->input_buffer[1] & 0xff,
+                           assoc->input_buffer[2] & 0xff);
            req = request_get(&assoc->incoming); /* get a new request structure */
            odr_reset(assoc->decode);
            odr_setbuf(assoc->decode, assoc->input_buffer, res, 0);
-           if (!z_APDU(assoc->decode, &req->apdu_request, 0, 0))
+           if (!z_GDU(assoc->decode, &req->gdu_request, 0, 0))
            {
                yaz_log(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
                        odr_errmsg(odr_geterror(assoc->decode)),
                        odr_offset(assoc->decode));
-               yaz_log(LOG_LOG, "PDU dump:");
-               odr_dumpBER(yaz_log_file(), assoc->input_buffer, res);
-               do_close(assoc, Z_Close_protocolError, "Malformed package");
+                if (assoc->decode->error != OHTTP)
+                {
+                    yaz_log(LOG_LOG, "PDU dump:");
+                    odr_dumpBER(yaz_log_file(), assoc->input_buffer, res);
+                    do_close(assoc, Z_Close_protocolError, "Malformed package");
+                }
+                else
+                {
+                    Z_GDU *p = z_get_HTTP_Response(assoc->encode, 400);
+                    assoc->state = ASSOC_DEAD;
+                    process_gdu_response(assoc, req, p);
+                }
                return;
            }
            req->request_mem = odr_extract_mem(assoc->decode);
-           if (assoc->print && !z_APDU(assoc->print, &req->apdu_request, 0, 0))
+           if (assoc->print && !z_GDU(assoc->print, &req->gdu_request, 0, 0))
            {
                yaz_log(LOG_WARN, "ODR print error: %s", 
                    odr_errmsg(odr_geterror(assoc->print)));
@@ -333,10 +347,8 @@ void ir_session(IOCHAN h, int event)
        req = request_head(&assoc->incoming);
        if (req->state == REQUEST_IDLE)
        {
-           char *msg;
            request_deq(&assoc->incoming);
-           if (process_request(assoc, req, &msg) < 0)
-               do_close_req(assoc, Z_Close_systemProblem, msg, req);
+           process_gdu_request(assoc, req);
        }
     }
     if (event & assoc->cs_put_mask)
@@ -345,7 +357,7 @@ void ir_session(IOCHAN h, int event)
 
        assoc->cs_put_mask = 0;
        yaz_log(LOG_DEBUG, "ir_session (output)");
-       req->state = REQUEST_PENDING;
+        req->state = REQUEST_PENDING;
        switch (res = cs_put(conn, req->response, req->len_response))
        {
        case -1:
@@ -356,6 +368,10 @@ void ir_session(IOCHAN h, int event)
            break;
        case 0: /* all sent - release the request structure */
            yaz_log(LOG_DEBUG, "Wrote PDU, %d bytes", req->len_response);
+#if 0
+           yaz_log(LOG_DEBUG, "HTTP out:\n%.*s", req->len_response,
+                    req->response);
+#endif
            nmem_destroy(req->request_mem);
            request_deq(&assoc->outgoing);
            request_release(req);
@@ -363,9 +379,15 @@ void ir_session(IOCHAN h, int event)
            {   /* restore mask for cs_get operation ... */
                iochan_clearflag(h, EVENT_OUTPUT|EVENT_INPUT);
                iochan_setflag(h, assoc->cs_get_mask);
+                yaz_log(LOG_LOG, "queue empty mask=%d", assoc->cs_get_mask);
+                if (assoc->state == ASSOC_DEAD)
+                    iochan_setevent(assoc->client_chan, EVENT_TIMEOUT);
            }
             else
+            {
                 assoc->cs_put_mask = EVENT_OUTPUT;
+                yaz_log(LOG_LOG, "queue not empty");
+            }
            break;
        default:
            if (conn->io_pending & CS_WANT_WRITE)
@@ -384,10 +406,341 @@ void ir_session(IOCHAN h, int event)
     }
 }
 
+static int process_z_request(association *assoc, request *req, char **msg);
+
+static int srw_bend_init(association *assoc)
+{
+    bend_initresult *binitres;
+    statserv_options_block *cb = statserv_getcontrol();
+    
+    assoc->init = (bend_initrequest *) xmalloc (sizeof(*assoc->init));
+
+    assoc->init->stream = assoc->encode;
+    assoc->init->print = assoc->print;
+    assoc->init->auth = 0;
+    assoc->init->referenceId = 0;
+    assoc->init->implementation_version = 0;
+    assoc->init->implementation_id = 0;
+    assoc->init->implementation_name = 0;
+    assoc->init->bend_sort = NULL;
+    assoc->init->bend_search = NULL;
+    assoc->init->bend_present = NULL;
+    assoc->init->bend_esrequest = NULL;
+    assoc->init->bend_delete = NULL;
+    assoc->init->bend_scan = NULL;
+    assoc->init->bend_segment = NULL;
+    assoc->init->bend_fetch = NULL;
+    assoc->init->charneg_request = NULL;
+    assoc->init->charneg_response = NULL;
+    assoc->init->decode = assoc->decode;
+
+    assoc->init->peer_name =
+       odr_strdup (assoc->encode, cs_addrstr(assoc->client_link));
+    if (!(binitres = (*cb->bend_init)(assoc->init)))
+    {
+       yaz_log(LOG_WARN, "Bad response from backend.");
+       return 0;
+    }
+    assoc->backend = binitres->handle;
+    return 1;
+}
+
+static void srw_bend_fetch(association *assoc, int pos,
+                           Z_SRW_searchRetrieveRequest *srw_req,
+                           Z_SRW_record *record)
+{
+    bend_fetch_rr rr;
+    ODR o = assoc->encode;
+
+    rr.setname = "default";
+    rr.number = pos;
+    rr.referenceId = 0;
+    rr.request_format = VAL_TEXT_XML;
+    rr.request_format_raw = yaz_oidval_to_z3950oid(assoc->decode,
+                                                   CLASS_TRANSYN,
+                                                   VAL_TEXT_XML);
+    rr.comp = odr_malloc(assoc->decode, sizeof(*rr.comp));
+    rr.comp->which = Z_RecordComp_complex;
+    rr.comp->u.complex = odr_malloc(assoc->decode, sizeof(Z_CompSpec));
+    rr.comp->u.complex->selectAlternativeSyntax = (bool_t *)
+        odr_malloc(assoc->encode, sizeof(bool_t));
+    *rr.comp->u.complex->selectAlternativeSyntax = 0;    
+    rr.comp->u.complex->num_dbSpecific = 0;
+    rr.comp->u.complex->dbSpecific = 0;
+    rr.comp->u.complex->num_recordSyntax = 0; 
+    rr.comp->u.complex->recordSyntax = 0;
+
+    rr.comp->u.complex->generic = odr_malloc(assoc->decode,
+                                             sizeof(Z_Specification));
+    rr.comp->u.complex->generic->which = Z_Specification_uri;
+    rr.comp->u.complex->generic->u.uri = srw_req->recordSchema;
+    rr.comp->u.complex->generic->elementSpec = 0;
+    
+    rr.stream = assoc->encode;
+    rr.print = assoc->print;
+
+    rr.basename = 0;
+    rr.len = 0;
+    rr.record = 0;
+    rr.last_in_set = 0;
+    rr.output_format = VAL_TEXT_XML;
+    rr.output_format_raw = 0;
+    rr.errcode = 0;
+    rr.errstring = 0;
+    rr.surrogate_flag = 0;
+    
+    (*assoc->init->bend_fetch)(assoc->backend, &rr);
+
+    if (rr.len >= 0)
+    {
+        record->recordData_buf = rr.record;
+        record->recordData_len = rr.len;
+        record->recordPosition = odr_intdup(o, pos);
+        record->recordSchema = odr_strdup(o, srw_req->recordSchema);
+    }
+}
+
+static void srw_bend_search(association *assoc, request *req,
+                            Z_SRW_searchRetrieveRequest *srw_req,
+                            Z_SRW_searchRetrieveResponse *srw_res)
+{
+    char *base = "Default";
+    bend_search_rr rr;
+    Z_External *ext;
+
+    if (!assoc->init)
+        srw_bend_init(assoc);
+
+    rr.setname = "default";
+    rr.replace_set = 1;
+    rr.num_bases = 1;
+    rr.basenames = &base;
+    rr.referenceId = 0;
+
+    ext = (Z_External *) odr_malloc(assoc->decode, sizeof(*ext));
+    ext->direct_reference = odr_getoidbystr(assoc->decode, 
+                                            "1.2.840.10003.16.2");
+    ext->indirect_reference = 0;
+    ext->descriptor = 0;
+    ext->which = Z_External_CQL;
+    if (srw_req->query)
+        ext->u.cql = srw_req->query;
+    else
+        ext->u.cql = "noterm";
+    
+    rr.query = (Z_Query *) odr_malloc (assoc->decode, sizeof(*rr.query));
+    rr.query->which = Z_Query_type_104;
+    rr.query->u.type_104 =  ext;
+    
+    rr.stream = assoc->encode;
+    rr.decode = assoc->decode;
+    rr.print = assoc->print;
+    rr.request = req;
+    rr.association = assoc;
+    rr.fd = 0;
+    rr.hits = 0;
+    rr.errcode = 0;
+    rr.errstring = 0;
+    rr.search_info = 0;
+    (assoc->init->bend_search)(assoc->backend, &rr);
+    srw_res->numberOfRecords = odr_intdup(assoc->encode, rr.hits);
+    if (rr.errcode)
+    {
+        srw_res->num_diagnostics = 1;
+        srw_res->diagnostics =
+            odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics));
+        srw_res->diagnostics[0].code = 
+            odr_intdup(assoc->encode, rr.errcode);
+    }
+    else
+    {
+        srw_res->numberOfRecords = odr_intdup(assoc->encode, rr.hits);
+        if (srw_req->maximumRecords && *srw_req->maximumRecords > 0)
+        {
+            int number = *srw_req->maximumRecords;
+            int start = 1;
+            int i;
+            if (srw_req->startRecord)
+                start = *srw_req->startRecord;
+            if (start <= rr.hits)
+            {
+                int j = 0;
+                if (start + number > rr.hits)
+                    number = rr.hits - start + 1;
+                srw_res->records = 
+                    odr_malloc(assoc->encode,
+                               number * sizeof(*srw_res->records));
+                for (i = 0; i<number; i++)
+                {
+                    srw_res->records[j].recordData_buf = 0;
+                    srw_bend_fetch(assoc, i+start, srw_req,
+                                   srw_res->records + j);
+                    if (srw_res->records[j].recordData_buf)
+                        j++;
+                }
+                srw_res->num_records = j;
+                if (!j)
+                    srw_res->records = 0;
+                yaz_log(LOG_LOG, "got %d records", j);
+            }
+        }
+    }
+}
+
+static void process_http_request(association *assoc, request *req)
+{
+    Z_HTTP_Request *hreq = req->gdu_request->u.HTTP_Request;
+    Z_HTTP_Header *hp;
+    ODR o = assoc->encode;
+    Z_GDU *p;
+    Z_HTTP_Response *hres = 0;
+    int keepalive = 1;
+
+#if 0
+    yaz_log(LOG_LOG, "HTTP Request. method=%s Version=%s Path=%s",
+            hreq->method, hreq->version, hreq->path);
+
+    for (hp = hreq->headers; hp; hp = hp->next)
+       yaz_log(LOG_LOG, "%s: %s", hp->name, hp->value);
+#endif
+
+    if (!strcmp(hreq->method, "GET"))
+    {
+        if (!strcmp(hreq->path, "/")) 
+        {
+            p = z_get_HTTP_Response(o, 200);
+            hres = p->u.HTTP_Response;
+            hres->content_buf = odr_malloc(o, 400);
+            sprintf (hres->content_buf, 
+                     "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
+                     "<HTML>\n"
+                     " <HEAD>\n"
+                     "  <TITLE>YAZ " YAZ_VERSION "</TITLE>\n"
+                     " </HEAD>\n"
+                     " <BODY>\n"
+                     "  <P><A HREF=\"http://www.indexdata.dk/yaz/\">YAZ</A> " 
+                     YAZ_VERSION "</P>\n"
+                     " </BODY>\n"
+                     "</HTML>\n");
+            hres->content_len = strlen(hres->content_buf);
+            z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html");
+        }
+        else
+        {
+            p = z_get_HTTP_Response(o, 404);
+        }
+    }
+    else if (!strcmp(hreq->method, "POST"))
+    {
+        const char *content_type = z_HTTP_header_lookup(hreq->headers,
+                                                        "Content-Type");
+        const char *soap_action = z_HTTP_header_lookup(hreq->headers,
+                                                       "SOAPAction");
+        p = 0;  /* no response yet */
+        if (content_type && soap_action && 
+            !yaz_strcmp_del("text/xml", content_type, "; "))
+        {
+            Z_SOAP *soap_package = 0;
+            int ret;
+            int http_code = 500;
+
+            static Z_SOAP_Handler soap_handlers[2] = {
+                {"http://www.loc.gov/zing/srw/v1.0/", 0, yaz_srw_codec},
+                {0, 0, 0}
+            };
+
+            ret = z_soap_codec(assoc->decode, &soap_package, 
+                               &hreq->content_buf, &hreq->content_len,
+                               soap_handlers);
+            
+            if (!ret && soap_package->which == Z_SOAP_generic &&
+                soap_package->u.generic->no == 0)
+            {
+                /* SRW package */
+                Z_SRW_searchRetrieve *sr = soap_package->u.generic->p;
+                
+                if (sr->which == Z_SRW_searchRetrieve_request)
+                {
+                    Z_SRW_searchRetrieve *res =
+                        yaz_srw_get(assoc->encode,
+                                    Z_SRW_searchRetrieve_response);
+                    
+                    srw_bend_search(assoc, req, sr->u.request, res->u.response);
+                    
+                    soap_package->u.generic->p = res;
+                    http_code = 200;
+                }
+            }
+
+            p = z_get_HTTP_Response(o, 200);
+            hres = p->u.HTTP_Response;
+            ret = z_soap_codec(assoc->encode, &soap_package,
+                               &hres->content_buf, &hres->content_len,
+                               soap_handlers);
+            hres->code = http_code;
+        }
+        if (!p) /* still no response ? */
+            p = z_get_HTTP_Response(o, 500);
+    }
+    else
+    {
+        p = z_get_HTTP_Response(o, 405);
+        hres = p->u.HTTP_Response;
+
+        z_HTTP_header_add(o, &hres->headers, "Allow", "GET, POST");
+    }
+    hres = p->u.HTTP_Response;
+    if (!strcmp(hreq->version, "1.0")) 
+    {
+        const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
+        if (v && !strcmp(v, "Keep-Alive"))
+            keepalive = 1;
+        else
+            keepalive = 0;
+        hres->version = "1.0";
+    }
+    else
+    {
+        const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
+        if (v && !strcmp(v, "close"))
+            keepalive = 0;
+        else
+            keepalive = 1;
+        hres->version = "1.1";
+    }
+    if (!keepalive)
+    {
+        z_HTTP_header_add(o, &hres->headers, "Connection", "close");
+        assoc->state = ASSOC_DEAD;
+    }
+    else
+    {
+        z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive");
+    }
+    process_gdu_response(assoc, req, p);
+}
+
+static void process_gdu_request(association *assoc, request *req)
+{
+    if (req->gdu_request->which == Z_GDU_Z3950)
+    {
+        char *msg = 0;
+        req->apdu_request = req->gdu_request->u.z3950;
+        if (process_z_request(assoc, req, &msg) < 0)
+            do_close_req(assoc, Z_Close_systemProblem, msg, req);
+    }
+    else if (req->gdu_request->which == Z_GDU_HTTP_Request)
+        process_http_request(assoc, req);
+    else
+    {
+        do_close_req(assoc, Z_Close_systemProblem, "bad protocol packet", req);
+    }
+}
+
 /*
  * Initiate request processing.
  */
-static int process_request(association *assoc, request *req, char **msg)
+static int process_z_request(association *assoc, request *req, char **msg)
 {
     int fd = -1;
     Z_APDU *res;
@@ -465,7 +818,7 @@ static int process_request(association *assoc, request *req, char **msg)
     if (res)
     {
        yaz_log(LOG_DEBUG, "  result immediately available");
-       retval = process_response(assoc, req, res);
+       retval = process_z_response(assoc, req, res);
     }
     else if (fd < 0)
     {
@@ -515,7 +868,7 @@ void backend_response(IOCHAN i, int event)
            yaz_log(LOG_WARN, "Serious programmer's lapse or bug");
            abort();
     }
-    if ((res && process_response(assoc, req, res) < 0) || fd < 0)
+    if ((res && process_z_response(assoc, req, res) < 0) || fd < 0)
     {
        yaz_log(LOG_LOG, "Fatal error when talking to backend");
        do_close(assoc, Z_Close_systemProblem, 0);
@@ -532,7 +885,46 @@ void backend_response(IOCHAN i, int event)
 /*
  * Encode response, and transfer the request structure to the outgoing queue.
  */
-static int process_response(association *assoc, request *req, Z_APDU *res)
+static int process_gdu_response(association *assoc, request *req, Z_GDU *res)
+{
+    odr_setbuf(assoc->encode, req->response, req->size_response, 1);
+
+    if (assoc->print && !z_GDU(assoc->print, &res, 0, 0))
+    {
+       yaz_log(LOG_WARN, "ODR print error: %s", 
+           odr_errmsg(odr_geterror(assoc->print)));
+       odr_reset(assoc->print);
+    }
+    if (!z_GDU(assoc->encode, &res, 0, 0))
+    {
+       yaz_log(LOG_WARN, "ODR error when encoding response: %s",
+           odr_errmsg(odr_geterror(assoc->decode)));
+       return -1;
+    }
+    req->response = odr_getbuf(assoc->encode, &req->len_response,
+       &req->size_response);
+    odr_setbuf(assoc->encode, 0, 0, 0); /* don'txfree if we abort later */
+    odr_reset(assoc->encode);
+    req->state = REQUEST_IDLE;
+    request_enq(&assoc->outgoing, req);
+    /* turn the work over to the ir_session handler */
+    iochan_setflag(assoc->client_chan, EVENT_OUTPUT);
+    assoc->cs_put_mask = EVENT_OUTPUT;
+    /* Is there more work to be done? give that to the input handler too */
+#if 1
+    if (request_head(&assoc->incoming))
+    {
+       yaz_log (LOG_DEBUG, "more work to be done");
+       iochan_setevent(assoc->client_chan, EVENT_WORK);
+    }
+#endif
+    return 0;
+}
+
+/*
+ * Encode response, and transfer the request structure to the outgoing queue.
+ */
+static int process_z_response(association *assoc, request *req, Z_APDU *res)
 {
     odr_setbuf(assoc->encode, req->response, req->size_response, 1);
 
@@ -1555,7 +1947,7 @@ void save_referenceId (request *reqb, Z_ReferenceId *refid)
 
 void bend_request_send (bend_association a, bend_request req, Z_APDU *res)
 {
-    process_response (a, req, res);
+    process_z_response (a, req, res);
 }
 
 bend_request bend_request_mk (bend_association a)
@@ -1588,7 +1980,7 @@ int bend_backend_respond (bend_association a, bend_request req)
 {
     char *msg;
     int r;
-    r = process_request (a, req, &msg);
+    r = process_z_request (a, req, &msg);
     if (r < 0)
        yaz_log (LOG_WARN, "%s", msg);
     return r;
@@ -1623,7 +2015,8 @@ static Z_APDU *process_ESRequest(association *assoc, request *reqb, int *fd)
 {
     bend_esrequest_rr esrequest;
 
-    Z_ExtendedServicesRequest *req = reqb->apdu_request->u.extendedServicesRequest;
+    Z_ExtendedServicesRequest *req =
+        reqb->apdu_request->u.extendedServicesRequest;
     Z_APDU *apdu = zget_APDU(assoc->encode, Z_APDU_extendedServicesResponse);
 
     Z_ExtendedServicesResponse *resp = apdu->u.extendedServicesResponse;
@@ -1680,3 +2073,4 @@ static Z_APDU *process_ESRequest(association *assoc, request *reqb, int *fd)
     yaz_log(LOG_DEBUG,"Send the result apdu");
     return apdu;
 }
+
index 6e8f8b0..72623f3 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: session.h,v 1.27 2003-01-06 08:20:28 adam Exp $
+ * $Id: session.h,v 1.28 2003-02-12 15:06:43 adam Exp $
  */
 
 #ifndef SESSION_H
@@ -28,7 +28,8 @@ typedef struct request
     char *refid;            /* referenceid */
     request_state state;
 
-    Z_APDU *apdu_request;   /* Current request */
+    Z_GDU *gdu_request;     /* Current request */
+    Z_APDU *apdu_request;   /* Current Z39.50 request */
     NMEM request_mem;    /* memory handle for request */
 
     int size_response;     /* size of buffer */
index c4a7e9d..dd3dc75 100644 (file)
@@ -6,7 +6,7 @@
  * NT threaded server code by
  *   Chas Woodfield, Fretwell Downing Informatics.
  *
- * $Id: statserv.c,v 1.90 2003-01-14 08:21:14 adam Exp $
+ * $Id: statserv.c,v 1.91 2003-02-12 15:06:43 adam Exp $
  */
 
 #include <stdio.h>
@@ -70,13 +70,14 @@ statserv_options_block control_block = {
     0,                          /* default value for inet deamon */
     0,                          /* handle (for service, etc) */
     0,                          /* bend_init handle */
-    0                           /* bend_close handle */
+    0,                          /* bend_close handle */
 #ifdef WIN32
-    ,"Z39.50 Server",           /* NT Service Name */
+    "Z39.50 Server",            /* NT Service Name */
     "Server",                   /* NT application Name */
     "",                         /* NT Service Dependencies */
-    "Z39.50 Server"             /* NT Service Display Name */
+    "Z39.50 Server",            /* NT Service Display Name */
 #endif /* WIN32 */
+    0                           /* SOAP handlers */
 };
 
 /*
@@ -446,7 +447,7 @@ static void listener(IOCHAN h, int event)
        if ((res = cs_listen_check(line, 0, 0, control_block.check_ip,
                                   control_block.daemon_name)) < 0)
        {
-           yaz_log(LOG_WARN, "cs_listen failed");
+           yaz_log(LOG_WARN|LOG_ERRNO, "cs_listen failed");
            return;
        }
        else if (res == 1)
@@ -691,6 +692,32 @@ void statserv_setcontrol(statserv_options_block *block)
     memcpy(&control_block, block, sizeof(*block));
 }
 
+void statserv_add_soap_handler(int (*h)(struct bend_soap_rr *rr),
+                               const char *ns)
+{
+    struct bend_soap_handler *sh = xmalloc(sizeof(*sh));
+
+    sh->handler = h;
+    sh->ns = xstrdup(ns);
+    sh->next = control_block.soap_handlers;
+    control_block.soap_handlers = sh;
+    yaz_log(LOG_LOG, "soap handler added");
+}
+
+static void statserv_reset(void)
+{
+    struct bend_soap_handler *sh = control_block.soap_handlers;
+
+    control_block.soap_handlers = 0;
+    while (sh)
+    {
+        struct bend_soap_handler *sh_next = sh->next;
+        xfree (sh->ns);
+        xfree (sh);
+        sh = sh_next;
+    }
+}
+
 int statserv_start(int argc, char **argv)
 {
     int ret;
@@ -921,6 +948,7 @@ void StopAppService(void *pHandle)
 {
     /* Stops the app */
     statserv_closedown();
+    statserv_reset();
 }
 /* WIN32 */
 #else
@@ -938,6 +966,7 @@ int statserv_main(int argc, char **argv,
     statserv_setcontrol(cb);
     ret = statserv_start (argc, argv);
     statserv_closedown ();
+    statserv_reset();
     return ret;
 }
 #endif
diff --git a/srw/Makefile.am b/srw/Makefile.am
deleted file mode 100644 (file)
index 13b9a7f..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# $Id: Makefile.am,v 1.2 2003-01-15 14:26:55 adam Exp $
-AM_CPPFLAGS = -I$(top_srcdir)/include $(GSOAP_INCLUDE) $(XSLT_CFLAGS)
-
-EXTRA_DIST = zing.h
-
-if SRW
-noinst_LTLIBRARIES = libsrw.la
-
-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)
-
-# 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 
-endif
diff --git a/srw/srw-diag.c b/srw/srw-diag.c
deleted file mode 100644 (file)
index e514c95..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $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 <yaz/srw-util.h>
-
-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
deleted file mode 100644 (file)
index 1659536..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $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
deleted file mode 100644 (file)
index 5a2ab0a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-
-#include <yaz/srw-util.h>
-#include <yaz/xmalloc.h>
-
-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,
-                    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 = soap->user;
-    soap->user = &info;
-    soap->namespaces = srw_namespaces;
-    soap_serve(soap);
-}
-
diff --git a/srw/srw-xcql.c b/srw/srw-xcql.c
deleted file mode 100644 (file)
index bdd16fd..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* $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 <yaz/srw-util.h>
-
-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
deleted file mode 100644 (file)
index c3dbac0..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* $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 <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxslt/xsltutils.h>
-#include <libxslt/transform.h>
-#endif
-
-#include <yaz/srw-util.h>
-
-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
deleted file mode 100644 (file)
index 8224be3..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* $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/Makefile.am b/srwapps/Makefile.am
deleted file mode 100644 (file)
index a024153..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-## $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
deleted file mode 100644 (file)
index e867562..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/* $Id: srw-client.c,v 1.2 2003-01-13 14:32:41 adam Exp $
-   Copyright (C) 2002-2003
-   Index Data Aps
-
-This file is part of the YAZ toolkit.
-
-See file LICENSE for details.
-*/
-
-#include <stdio.h>
-
-#include <yaz/options.h>
-#include <yaz/srw-util.h>
-
-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] <service> <query>\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; i<res.records.__sizeRecords;
-                 i++)
-            {
-                if (res.records.record[i]->recordData)
-                {
-                    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
deleted file mode 100644 (file)
index aa0f458..0000000
+++ /dev/null
@@ -1,911 +0,0 @@
-/* $Id: srw-gateway.c,v 1.2 2003-01-20 13:04:50 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 <pthread.h>
-#define USE_THREADS 1
-#else
-#define USE_THREADS 0
-#endif
-
-#include <yaz/srw-util.h>
-#include <yaz/xmalloc.h>
-#include <yaz/zoom.h>
-#include <yaz/log.h>
-#include <yaz/options.h>
-#include <yaz/wrbuf.h>
-
-#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);
-}
-
-#if USE_THREADS
-static void *p_serve (void *p)
-{
-    struct soap *soap = p;
-    yaz_srw_serve(soap, searchRetrieve, explain);
-}
-#endif
-
-
-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<max_thr; i++)
-        soap_thr[i] = 0;
-
-    while (!stop)
-    {
-        for (i = 0; i<max_thr; i++)
-        {
-            s = soap_accept(soap);
-            if (s < 0)
-                break;
-            cno++;
-            if (!soap_thr[i])
-            {
-                soap_thr[i] = soap_new();
-                if (!soap_thr[i])
-                {
-                    stop = 1;
-                    break;
-                }
-            }
-            else
-            {
-#if USE_THREADS
-                if (max_thr > 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],
-                              searchRetrieve, explain);  /* static mode .. */
-            else
-                pthread_create(&tid[i], 0, p_serve, soap_thr[i]);
-#else
-            yaz_srw_serve(soap_thr[i],
-                          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 = 
-        "<explain>\n"
-        "  <!-- not implemented -->\n"
-        "</explain>\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") || !strcmp(schema, "http://www.loc.gov/marcxml/"))
-    {
-        *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.2 2003-01-20 13:04:50 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] <port>\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, 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;
-}
index 0863781..538b435 100644 (file)
@@ -1,50 +1,9 @@
 /*
- * Copyright (c) 1995-2000, Index Data.
+ * Copyright (c) 1995-2003, Index Data.
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Log: matchstr.c,v $
- * Revision 1.5  2000-02-29 13:44:55  adam
- * Check for config.h (currently not generated).
- *
- * Revision 1.4  1999/11/30 13:47:12  adam
- * Improved installation. Moved header files to include/yaz.
- *
- * Revision 1.3  1999/10/19 12:35:42  adam
- * Minor bug fix (bug introduced by previous commit).
- *
- * Revision 1.2  1999/10/15 11:35:41  adam
- * Character '.' matches any single character.
- *
- * Revision 1.1  1999/06/08 10:10:16  adam
- * New sub directory zutil. Moved YAZ Compiler to be part of YAZ tree.
- *
- * Revision 1.7  1997/09/30 11:47:47  adam
- * Added function 'cause checkergcc doesn't include assert handler.
- *
- * Revision 1.6  1997/09/04 07:54:34  adam
- * Right hande side operand of yaz_matchstr may include a ? in
- * which case it returns "match ok".
- *
- * Revision 1.5  1997/07/21 12:48:11  adam
- * Removed windows DLL stubs.
- *
- * Revision 1.4  1997/05/01 15:07:55  adam
- * Added DLL entry point routines.
- *
- * Revision 1.3  1996/10/29 13:36:28  adam
- * Added header.
- *
- * Revision 1.2  1996/02/20 17:58:42  adam
- * Added const to yaz_matchstr.
- *
- * Revision 1.1  1996/02/20  16:33:06  quinn
- * Moved matchstr to global util
- *
- * Revision 1.1  1995/11/01  11:56:08  quinn
- * Added Retrieval (data management) functions en masse.
- *
- *
+ * $Id: matchstr.c,v 1.6 2003-02-12 15:06:44 adam Exp $
  */
 #if HAVE_CONFIG_H
 #include <config.h>
@@ -91,6 +50,20 @@ int yaz_matchstr(const char *s1, const char *s2)
     return *s1 || *s2;
 }
 
+int yaz_strcmp_del(const char *a, const char *b, const char *b_del)
+{
+    while (*a && *b)
+    {
+        if (*a != *b)
+            return *a - *b;
+        a++;
+        b++;
+    }
+    if (b_del && strchr(b_del, *b))
+        return *a;
+    return *a - *b;
+}
+
 #ifdef __GNUC__
 #ifdef __CHECKER__
 void __assert_fail (const char *assertion, const char *file, 
index 5faf6d0..7824d02 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: yaz-config.in,v 1.15 2003-01-06 08:20:26 adam Exp $
+# $Id: yaz-config.in,v 1.16 2003-02-12 15:06:42 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="@GSOAP_LIB@ @XSLT_LIB@ @LIBS@"
+yazextralibs="@XSLT_LIB@ @LIBS@"
 YAZVERSION=@VERSION@
 
 usage()
index 42c7ee8..09185f1 100644 (file)
@@ -101,7 +101,7 @@ IdAuthentication ::=
       accessCtrl       (6),
       scan         (7),
       sort        (8), 
-      --        (9) (reserved)
+      -- (not used) (9),
       extendedServices    (10),
       level-1Segmentation    (11),
       level-2Segmentation    (12),
@@ -109,9 +109,12 @@ IdAuthentication ::=
       namedResultSets    (14),
       encapsulation    (15),
       resultCount    (16),
-      negotiationModel    (17),
-      duplicateDetection    (18),
-      queryType104    (19)}
+      negotiationModel (17),
+      duplicateDetection (18),
+      queryType104 (19),
+      pQESCorrection (20),
+      stringSchema (21)
+}
 -- end auxiliary definitions for Init PDUs
 
 
@@ -355,7 +358,10 @@ SearchResponse ::= SEQUENCE{
                -- selectAlternativeSyntax is 'true'.
         }
   Specification ::= SEQUENCE{
-  schema    [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
+  schema CHOICE {
+              oid [1]   IMPLICIT OBJECT IDENTIFIER,
+              uri [300] IMPLICIT InternationalString
+  } OPTIONAL,
   elementSpec    [2] CHOICE{
               elementSetName   [1] IMPLICIT InternationalString,
           externalEspec  [2] IMPLICIT EXTERNAL} OPTIONAL}
index 235e489..4283b6f 100644 (file)
@@ -1,4 +1,4 @@
-## $Id: Makefile.am,v 1.7 2003-01-06 08:20:28 adam Exp $
+## $Id: Makefile.am,v 1.8 2003-02-12 15:06:44 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 $(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_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomtst2_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomtst3_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomtst4_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomtst5_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomtst6_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomtst7_LDADD = ../lib/libyazmalloc.la ../lib/libyaz.la $(XSLT_LIB)
+zoomtst8_LDADD = ../lib/libyaz.la $(XSLT_LIB)
+zoomsh_LDADD = ../lib/libyaz.la $(XSLT_LIB) $(READLINE_LIBS) 
 
 zoomtst1_SOURCES = zoomtst1.c
 zoomtst2_SOURCES = zoomtst2.c
index 1f17acb..3922dd8 100644 (file)
@@ -1,4 +1,4 @@
-## $Id: Makefile.am,v 1.11 2002-04-15 09:44:44 adam Exp $
+## $Id: Makefile.am,v 1.12 2003-02-12 15:06:44 adam Exp $
 
 if ISSSL
 sslbin=yaz-ztest-ssl
@@ -16,11 +16,11 @@ extra=../lib/libyazthread.la
 endif
 
 yaz_ztest_LDADD=$(extra) ../lib/libyaz.la \
- $(LIBTHREAD)
+ $(XSLT_LIB) $(LIBTHREAD)
 
 yaz_ztest_ssl_LDADD=$(extra) ../lib/libyazssl.la ../lib/libyaz.la \
- $(SSL_LIBS) $(LIBTHREAD)
+ $(SSL_LIBS) $(XSLT_LIB) $(LIBTHREAD)
 
 AM_CFLAGS=@CFLAGSTHREADS@
 
-AM_CPPFLAGS=-I$(top_srcdir)/include
+AM_CPPFLAGS=-I$(top_srcdir)/include $(XSLT_CFLAGS)
index 2b848ba..08c742c 100644 (file)
@@ -1,8 +1,13 @@
-## $Id: Makefile.am,v 1.14 2003-01-06 08:20:29 adam Exp $
+## $Id: Makefile.am,v 1.15 2003-02-12 15:06:44 adam Exp $
 noinst_LTLIBRARIES = libzutil.la
 
-AM_CPPFLAGS=-I$(top_srcdir)/include -I$(top_srcdir)/srw
+AM_CPPFLAGS=-I$(top_srcdir)/include -I$(top_srcdir)/srw $(XSLT_CFLAGS)
 
 libzutil_la_SOURCES = zget.c yaz-ccl.c diagbib1.c logrpn.c \
   otherinfo.c pquery.c sortspec.c z3950oid.c charneg.c \
-  zoom-c.c zoom-opt.c zoom-p.h grs1disp.c
+  zoom-c.c zoom-opt.c zoom-p.h grs1disp.c zgdu.c soap.c srw.c
+
+srwtst_LDADD = ../odr/libodr.la libzutil.la $(XSLT_LIB) ../util/libutil.la
+srwtst_SOURCES = srwtst.c
+
+noinst_PROGRAMS = srwtst
\ No newline at end of file
index 229c59f..9d46fad 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2001, Index Data
  * All rights reserved.
  *
- * $Id: logrpn.c,v 1.9 2003-01-06 08:20:29 adam Exp $
+ * $Id: logrpn.c,v 1.10 2003-02-12 15:06:44 adam Exp $
  */
 #include <stdio.h>
 
@@ -353,7 +353,6 @@ void log_scan_term (Z_AttributesPlusTerm *zapt, oid_value 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:
diff --git a/zutil/soap.c b/zutil/soap.c
new file mode 100644 (file)
index 0000000..911f367
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2002-2003, Index Data.
+ * See the file LICENSE for details.
+ *
+ * $Id: soap.c,v 1.1 2003-02-12 15:06:44 adam Exp $
+ */
+
+#include <yaz/soap.h>
+
+static const char *soap_v1_1 = "http://schemas.xmlsoap.org/soap/envelope/";
+static const char *soap_v1_2 = "http://www.w3.org/2001/06/soap-envelope";
+
+int z_soap_error(ODR o, Z_SOAP *p,
+                 const char *fault_code, const char *fault_string,
+                 const char *details)
+{
+    p->which = Z_SOAP_error;
+    p->u.soap_error = odr_malloc(o, sizeof(*p->u.soap_error));
+    p->u.soap_error->fault_code = odr_strdup(o, fault_code);
+    p->u.soap_error->fault_string = odr_strdup(o, fault_string);
+    if (details)
+        p->u.soap_error->details = odr_strdup(o, details);
+    else
+        p->u.soap_error->details = 0;
+    return -1;
+}
+
+int z_soap_codec(ODR o, Z_SOAP **pp, 
+                 char **content_buf, int *content_len,
+                 Z_SOAP_Handler *handlers)
+{
+    if (o->direction == ODR_DECODE)
+    {
+        Z_SOAP *p;
+        xmlNodePtr ptr, pptr;
+        xmlDocPtr doc;
+        int i, ret;
+
+        if (!content_buf || !*content_buf || !content_len)
+            return -1;
+
+        *pp = p = odr_malloc(o, sizeof(*p));
+        p->ns = soap_v1_1;
+
+        doc = xmlParseMemory(*content_buf, *content_len);
+        if (!doc)
+            return z_soap_error(o, p, "SOAP-ENV:Client",
+                                "Bad XML Document", 0);
+        /* check that root node is Envelope */
+        ptr = xmlDocGetRootElement(doc);
+        if (!ptr || ptr->type != XML_ELEMENT_NODE ||
+            strcmp(ptr->name, "Envelope"))
+        {
+            xmlFreeDoc(doc);
+            return z_soap_error(o, p, "SOAP-ENV:Client",
+                                "No Envelope element", 0);
+        }
+        else
+        {
+            /* determine SOAP version */
+            const char * ns_envelope = ptr->ns->href;
+            if (!strcmp(ns_envelope, soap_v1_1))
+                p->ns = soap_v1_1;
+            else if (!strcmp(ns_envelope, soap_v1_2))
+                p->ns = soap_v1_2;
+            else
+            {
+                xmlFreeDoc(doc);
+                return z_soap_error(o, p, "SOAP-ENV:Client",
+                                    "Bad SOAP version", 0);
+            }
+        }
+        ptr = ptr->children;
+        while(ptr && ptr->type == XML_TEXT_NODE)
+            ptr = ptr->next;
+        if (ptr && ptr->type == XML_ELEMENT_NODE &&
+            !strcmp(ptr->ns->href, p->ns) &&
+            !strcmp(ptr->name, "Header"))
+        {
+            ptr = ptr->next;
+            while(ptr && ptr->type == XML_TEXT_NODE)
+                ptr = ptr->next;
+        }
+        /* check that Body is present */
+        if (!ptr || ptr->type != XML_ELEMENT_NODE || 
+            strcmp(ptr->name, "Body"))
+        {
+            xmlFreeDoc(doc);
+            return z_soap_error(o, p, "SOAP-ENV:Client",
+                                "SOAP Body element not found", 0);
+        }
+        if (strcmp(ptr->ns->href, p->ns))
+        {
+            xmlFreeDoc(doc);
+            return z_soap_error(o, p, "SOAP-ENV:Client",
+                                "SOAP bad NS for Body element", 0);
+        }
+        pptr = ptr;
+        ptr = ptr->children;
+        while (ptr && ptr->type == XML_TEXT_NODE)
+            ptr = ptr->next;
+        if (!ptr || ptr->type != XML_ELEMENT_NODE)
+        {
+            xmlFreeDoc(doc);
+            return z_soap_error(o, p, "SOAP-ENV:Client",
+                                "SOAP No content for Body", 0);
+        }
+        /* check for fault package */
+        if (!strcmp(ptr->ns->href, p->ns)
+            && !strcmp(ptr->name, "Fault") && ptr->children)
+        {
+            ptr = ptr->children;
+
+            p->which = Z_SOAP_fault;
+            p->u.fault = odr_malloc(o, sizeof(*p->u.fault));
+            p->u.fault->fault_code = 0;
+            p->u.fault->fault_string = 0;
+            p->u.fault->details = 0;
+            while (ptr)
+            {
+                if (ptr->children && ptr->children->type == XML_TEXT_NODE)
+                {
+                    if (!strcmp(ptr->name, "faultcode"))
+                        p->u.fault->fault_code =
+                            odr_strdup(o, ptr->children->content);
+                    if (!strcmp(ptr->name, "faultstring"))
+                        p->u.fault->fault_string =
+                            odr_strdup(o, ptr->children->content);
+                    if (!strcmp(ptr->name, "details"))
+                        p->u.fault->details =
+                            odr_strdup(o, ptr->children->content);
+                }
+                ptr = ptr->next;
+            }
+            ret = 0;
+        }
+        else
+        {
+            for (i = 0; handlers[i].ns; i++)
+                if (!strcmp(ptr->ns->href, handlers[i].ns))
+                    break;
+            if (handlers[i].ns)
+            {
+                void *handler_data = 0;
+                ret = (*handlers[i].f)(o, pptr, &handler_data,
+                                       handlers[i].client_data,
+                                       handlers[i].ns);
+                if (ret || !handler_data)
+                    z_soap_error(o, p, "SOAP-ENV:Client",
+                                 "SOAP Handler returned error", 0);
+                else
+                {
+                    p->which = Z_SOAP_generic;
+                    p->u.generic = odr_malloc(o, sizeof(*p->u.generic));
+                    p->u.generic->no = i;
+                    p->u.generic->ns = handlers[i].ns;
+                    p->u.generic->p = handler_data;
+                }
+            }
+            else
+            {
+                ret = z_soap_error(o, p, "SOAP-ENV:Client", 
+                                   "No handler for NS", 0);
+            }
+        }
+        xmlFreeDoc(doc);
+        return ret;
+    }
+    else if (o->direction == ODR_ENCODE)
+    {
+        Z_SOAP *p = *pp;
+        xmlNsPtr ns_env;
+        xmlNodePtr envelope_ptr, body_ptr;
+        xmlChar *buf_out;
+        int len_out;
+
+        xmlDocPtr doc = xmlNewDoc("1.0");
+
+        envelope_ptr = xmlNewNode(0, "Envelope");
+        ns_env = xmlNewNs(envelope_ptr, p->ns, "SOAP-ENV");
+        body_ptr = xmlNewChild(envelope_ptr, ns_env, "Body", 0);
+        xmlDocSetRootElement(doc, envelope_ptr);
+
+        if (p->which == Z_SOAP_fault || p->which == Z_SOAP_error)
+        {
+            Z_SOAP_Fault *f = p->u.fault;
+            xmlNodePtr fault_ptr = xmlNewChild(body_ptr, ns_env, "Fault", 0);
+            xmlNewChild(fault_ptr, ns_env, "faultcode",  f->fault_code);
+            xmlNewChild(fault_ptr, ns_env, "faultstring", f->fault_string);
+            if (f->details)
+                xmlNewChild(fault_ptr, ns_env, "details", f->details);
+        }
+        else if (p->which == Z_SOAP_generic)
+        {
+            int ret, no = p->u.generic->no;
+            
+            ret = (*handlers[no].f)(o, body_ptr, &p->u.generic->p,
+                                    handlers[no].client_data,
+                                    handlers[no].ns);
+            if (ret)
+                return ret;
+        }
+        xmlDocDumpMemory(doc, &buf_out, &len_out);
+        *content_buf = odr_malloc(o, len_out);
+        *content_len = len_out;
+        memcpy(*content_buf, buf_out, len_out);
+        xmlFree(buf_out);
+        xmlFreeDoc(doc);
+        return 0;
+    }
+    return 0;
+}
diff --git a/zutil/srw.c b/zutil/srw.c
new file mode 100644 (file)
index 0000000..1fa9fca
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2002-2003, Index Data.
+ * See the file LICENSE for details.
+ *
+ * $Id: srw.c,v 1.1 2003-02-12 15:06:44 adam Exp $
+ */
+
+#include <yaz/srw.h>
+
+static void add_xsd_string_n(xmlNodePtr ptr, const char *elem, char *val,
+                             int len)
+{
+    if (val)
+    {
+        xmlNodePtr c = xmlNewChild(ptr, 0, elem, 0);
+        xmlNodePtr t = xmlNewTextLen(val, len);
+        xmlAddChild(c, t);
+    }
+}
+
+static void add_xsd_string(xmlNodePtr ptr, const char *elem, char *val)
+{
+    if (val)
+        xmlNewChild(ptr, 0, elem, val);
+}
+
+static void add_xsd_integer(xmlNodePtr ptr, const char *elem, int *val)
+{
+    if (val)
+    {
+        char str[30];
+        sprintf(str, "%d", *val);
+        xmlNewChild(ptr, 0, elem, str);
+    }
+}
+
+static int match_element(xmlNodePtr ptr, const char *elem)
+{
+    if (ptr->type == XML_ELEMENT_NODE && !strcmp(ptr->name, elem))
+        return 1;
+    return 0;
+}
+
+static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
+                              char **val, int *len)
+{
+    struct _xmlAttr *attr;
+    if (!match_element(ptr, elem))
+        return 0;
+    for (attr = ptr->properties; attr; attr = attr->next)
+        if (!strcmp(attr->name, "type") &&
+            attr->children && attr->children->type == XML_TEXT_NODE)
+        {
+            const char *t = strchr(attr->children->content, ':');
+            if (t)
+                t = t + 1;
+            else
+                t = attr->children->content;
+            if (!strcmp(t, "string"))
+                break;
+        }
+    if (!attr)
+        return 0;
+    ptr = ptr->children;
+    if (!ptr || ptr->type != XML_TEXT_NODE)
+        return 0;
+    *val = odr_strdup(o, ptr->content);
+    if (len)
+        *len = strlen(ptr->content);
+    return 1;
+}
+
+
+static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
+                            char **val)
+{
+    return match_xsd_string_n(ptr, elem, o, val, 0);
+}
+                     
+static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val)
+{
+    struct _xmlAttr *attr;
+    if (!match_element(ptr, elem))
+        return 0;
+    for (attr = ptr->properties; attr; attr = attr->next)
+        if (!strcmp(attr->name, "type") &&
+            attr->children && attr->children->type == XML_TEXT_NODE)
+        {
+            const char *t = strchr(attr->children->content, ':');
+            if (t)
+                t = t + 1;
+            else
+                t = attr->children->content;
+            if (!strcmp(t, "integer"))
+                break;
+        }
+    if (!attr)
+        return 0;
+    ptr = ptr->children;
+    if (!ptr || ptr->type != XML_TEXT_NODE)
+        return 0;
+    *val = odr_intdup(o, atoi(ptr->content));
+    return 1;
+}
+
+static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
+                           int *num, void *client_data, const char *ns)
+{
+    if (o->direction == ODR_DECODE)
+    {
+        int i;
+        xmlNodePtr ptr;
+        *num = 0;
+        for (ptr = pptr->children; ptr; ptr = ptr->next)
+        {
+            if (ptr->type == XML_ELEMENT_NODE &&
+                !strcmp(ptr->name, "record"))
+                (*num)++;
+        }
+        if (!*num)
+            return 1;
+        *recs = odr_malloc(o, *num * sizeof(**recs));
+        for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
+        {
+            if (ptr->type == XML_ELEMENT_NODE &&
+                !strcmp(ptr->name, "record"))
+            {
+                xmlNodePtr rptr;
+                (*recs)[i].recordSchema = 0;
+                (*recs)[i].recordData_buf = 0;
+                (*recs)[i].recordData_len = 0;
+                (*recs)[i].recordPosition = 0;
+                for (rptr = ptr->children; rptr; rptr = rptr->next)
+                {
+                    if (match_xsd_string(rptr, "recordSchema", o, 
+                                         &(*recs)[i].recordSchema))
+                        ;
+                    else if (match_xsd_string_n(rptr, "recordData", o, 
+                                                &(*recs)[i].recordData_buf,
+                                                &(*recs)[i].recordData_len))
+                        ;
+                    else if (match_xsd_integer(rptr, "recordPosition", o, 
+                                               &(*recs)[i].recordPosition))
+                        ;
+                }
+            }
+        }
+    }
+    else if (o->direction == ODR_ENCODE)
+    {
+        int i;
+        for (i = 0; i < *num; i++)
+        {
+            xmlNodePtr rptr = xmlNewChild(pptr, 0, "record", 0);
+            add_xsd_string(rptr, "recordSchema", (*recs)[i].recordSchema);
+            add_xsd_string_n(rptr, "recordData", (*recs)[i].recordData_buf,
+                             (*recs)[i].recordData_len);
+            add_xsd_integer(rptr, "recordPosition", (*recs)[i].recordPosition);
+        }
+    }
+    return 0;
+}
+
+static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
+                               int *num, void *client_data, const char *ns)
+{
+    if (o->direction == ODR_DECODE)
+    {
+        int i;
+        xmlNodePtr ptr;
+        *num = 0;
+        for (ptr = pptr->children; ptr; ptr = ptr->next)
+        {
+            if (ptr->type == XML_ELEMENT_NODE &&
+                !strcmp(ptr->name, "diagnostic"))
+                (*num)++;
+        }
+        if (!*num)
+            return 1;
+        *recs = odr_malloc(o, *num * sizeof(**recs));
+        for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
+        {
+            if (ptr->type == XML_ELEMENT_NODE &&
+                !strcmp(ptr->name, "diagnostic"))
+            {
+                xmlNodePtr rptr;
+                (*recs)[i].code = 0;
+                (*recs)[i].details = 0;
+                for (rptr = ptr->children; rptr; rptr = rptr->next)
+                {
+                    if (match_xsd_integer(rptr, "code", o, 
+                                               &(*recs)[i].code))
+                        ;
+                    else if (match_xsd_string(rptr, "details", o, 
+                                              &(*recs)[i].details))
+                        ;
+                }
+                i++;
+            }
+        }
+    }
+    else if (o->direction == ODR_ENCODE)
+    {
+        int i;
+        for (i = 0; i < *num; i++)
+        {
+            xmlNodePtr rptr = xmlNewChild(pptr, 0, "diagnostic", 0);
+            add_xsd_integer(rptr, "code", (*recs)[i].code);
+            add_xsd_string(rptr, "details", (*recs)[i].details);
+        }
+    }
+    return 0;
+}
+
+
+int yaz_srw_codec(ODR o, xmlNodePtr pptr, Z_SRW_searchRetrieve **handler_data,
+                  void *client_data, const char *ns)
+{
+    if (o->direction == ODR_DECODE)
+    {
+        xmlNodePtr method = pptr->children;
+
+        while (method && method->type == XML_TEXT_NODE)
+            method = method->next;
+        
+        if (method->type != XML_ELEMENT_NODE)
+            return -1;
+        if (method && !strcmp(method->name, "searchRetrieveRequest"))
+        {
+            Z_SRW_searchRetrieve **p = handler_data;
+            xmlNodePtr ptr = method->children;
+            Z_SRW_searchRetrieveRequest *req;
+
+            *p = odr_malloc(o, sizeof(**p));
+            (*p)->which = Z_SRW_searchRetrieve_request;
+            req = (*p)->u.request = odr_malloc(o, sizeof(*req));
+            req->query = 0;
+            req->xQuery = 0;
+            req->sortKeys = 0;
+            req->xSortKeys = 0;
+            req->startRecord = 0;
+            req->maximumRecords = 0;
+            req->recordSchema = 0;
+            req->recordPacking = 0;
+
+            for (; ptr; ptr = ptr->next)
+            {
+                if (match_xsd_string(ptr, "query", o, 
+                                     &req->query))
+                    ;
+                else if (match_xsd_string(ptr, "pQuery", o, 
+                                     &req->pQuery))
+                    ;
+                else if (match_xsd_string(ptr, "sortKeys", o, 
+                                          &req->sortKeys))
+                    ;
+                else if (match_xsd_string(ptr, "recordSchema", o, 
+                                          &req->recordSchema))
+                    ;
+                else if (match_xsd_string(ptr, "recordPacking", o,
+                                          &req->recordPacking))
+                    ;
+                else if (match_xsd_integer(ptr, "startRecord", o,
+                                           &req->startRecord))
+                    ;
+                else if (match_xsd_integer(ptr, "maximumRecords", o,
+                                           &req->maximumRecords))
+                    ;
+                /* missing is xQuery, xSortKeys .. */
+            }
+        }
+        else if (method && !strcmp(method->name, "searchRetrieveResponse"))
+        {
+            Z_SRW_searchRetrieve **p = handler_data;
+            xmlNodePtr ptr = method->children;
+            Z_SRW_searchRetrieveResponse *res;
+
+            *p = odr_malloc(o, sizeof(**p));
+            (*p)->which = Z_SRW_searchRetrieve_response;
+            res = (*p)->u.response = odr_malloc(o, sizeof(*res));
+
+            res->numberOfRecords = 0;
+            res->resultSetId = 0;
+            res->resultSetIdleTime = 0;
+            res->records = 0;
+            res->num_records = 0;
+            res->diagnostics = 0;
+            res->num_diagnostics = 0;
+            res->nextRecordPosition = 0;
+
+            for (; ptr; ptr = ptr->next)
+            {
+                if (match_xsd_integer(ptr, "numberOfRecords", o, 
+                                      &res->numberOfRecords))
+                    ;
+                else if (match_xsd_string(ptr, "resultSetId", o, 
+                                          &res->resultSetId))
+                    ;
+                else if (match_xsd_integer(ptr, "resultSetIdleTime", o, 
+                                           &res->resultSetIdleTime))
+                    ;
+                else if (match_element(ptr, "records"))
+                    yaz_srw_records(o, ptr, &res->records,
+                                    &res->num_records, client_data,
+                                    ns);
+                else if (match_element(ptr, "diagnostics"))
+                    yaz_srw_diagnostics(o, ptr, &res->diagnostics,
+                                        &res->num_diagnostics,
+                                        client_data, ns);
+                else if (match_xsd_integer(ptr, "nextRecordPosition", o,
+                                           &res->nextRecordPosition))
+                    ;
+            }
+
+        }
+        else
+            return -1;
+
+    }
+    else if (o->direction == ODR_ENCODE)
+    {
+        Z_SRW_searchRetrieve **p = handler_data;
+        if ((*p)->which == Z_SRW_searchRetrieve_request)
+        {
+            Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
+            xmlNsPtr ns_srw = xmlNewNs(pptr, ns, "zs");
+            xmlNodePtr ptr = xmlNewChild(pptr, ns_srw,
+                                         "searchRetrieveRequest", 0);
+
+            add_xsd_string(ptr, "query", req->query);
+            add_xsd_string(ptr, "pQuery", req->pQuery);
+            add_xsd_string(ptr, "sortKeys", req->sortKeys);
+            add_xsd_integer(ptr, "startRecord", req->startRecord);
+            add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
+            add_xsd_string(ptr, "recordSchema", req->recordSchema);
+            add_xsd_string(ptr, "recordPacking", req->recordPacking);
+        }
+        else if ((*p)->which == Z_SRW_searchRetrieve_response)
+        {
+            Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
+            xmlNsPtr ns_srw = xmlNewNs(pptr, ns, "zs");
+            xmlNodePtr ptr = xmlNewChild(pptr, ns_srw,
+                                         "searchRetrieveResponse", 0);
+
+            add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
+            add_xsd_string(ptr, "resultSetId", res->resultSetId);
+            add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);
+            if (res->num_records)
+            {
+                xmlNodePtr rptr = xmlNewChild(ptr, 0, "records", 0);
+                yaz_srw_records(o, rptr, &res->records, &res->num_records,
+                                client_data, ns);
+            }
+            if (res->num_diagnostics)
+            {
+                xmlNodePtr rptr = xmlNewChild(ptr, 0, "diagnostics", 0);
+                yaz_srw_diagnostics(o, rptr, &res->diagnostics,
+                                    &res->num_diagnostics, client_data, ns);
+            }
+            add_xsd_integer(ptr, "nextRecordPosition", res->nextRecordPosition);
+        }
+        else
+            return -1;
+
+    }
+    return 0;
+}
+
+Z_SRW_searchRetrieve *yaz_srw_get(ODR o, int which)
+{
+    Z_SRW_searchRetrieve *sr = odr_malloc(o, sizeof(*o));
+    sr->which = which;
+    switch(which)
+    {
+    case Z_SRW_searchRetrieve_request:
+        sr->u.request = odr_malloc(o, sizeof(*sr->u.request));
+        sr->u.request->query = 0;
+        sr->u.request->xQuery = 0;
+        sr->u.request->sortKeys = 0;
+        sr->u.request->xSortKeys = 0;
+        sr->u.request->startRecord = 0;
+        sr->u.request->maximumRecords = 0;
+        sr->u.request->recordSchema = 0;
+        sr->u.request->recordPacking = 0;
+        break;
+    case Z_SRW_searchRetrieve_response:
+        sr->u.response = odr_malloc(o, sizeof(*sr->u.response));
+        sr->u.response->numberOfRecords = 0;
+        sr->u.response->resultSetId = 0;
+        sr->u.response->resultSetIdleTime = 0;
+        sr->u.response->records = 0;
+        sr->u.response->num_records = 0;
+        sr->u.response->diagnostics = 0;
+        sr->u.response->num_diagnostics = 0;
+        sr->u.response->nextRecordPosition = 0;
+    }
+    return sr;
+}
index 12456d3..4e67499 100644 (file)
@@ -2,12 +2,13 @@
  * Copyright (c) 1996-2003, Index Data.
  * See the file LICENSE for details.
  *
- * $Id: yaz-ccl.c,v 1.18 2003-01-06 08:20:29 adam Exp $
+ * $Id: yaz-ccl.c,v 1.19 2003-02-12 15:06:44 adam Exp $
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #include <yaz/yaz-ccl.h>
 #include <yaz/pquery.h>
diff --git a/zutil/zgdu.c b/zutil/zgdu.c
new file mode 100644 (file)
index 0000000..c06777e
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2002-2003, Index Data.
+ * See the file LICENSE for details.
+ *
+ * $Id: zgdu.c,v 1.1 2003-02-12 15:06:44 adam Exp $
+ */
+
+#include <yaz/proto.h>
+
+#define HTTP_DEBUG 0
+
+static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers,
+                                  char **content_buf, int *content_len)
+{
+    int i = off;
+
+    *headers = 0;
+    while (i < o->size-1 && o->buf[i] == '\r')
+    {
+        int po;
+        i++;
+        if (o->buf[i] != '\n')
+        {
+            o->error = OHTTP;
+            return 0;
+        }
+       i++;
+       if (o->buf[i] == '\r')
+            break;
+        for (po = i; ; i++)
+        {
+            if (i == o->size)
+            {
+                o->error = OHTTP;
+                return 0;
+            }
+            else if (o->buf[i] == ':')
+                break;
+        }
+        *headers = odr_malloc(o, sizeof(**headers));
+        (*headers)->name = odr_malloc(o, i - po + 1);
+        memcpy ((*headers)->name, o->buf + po, i - po);
+        (*headers)->name[i - po] = '\0';
+        i++;
+        while (i < o->size-1 && o->buf[i] == ' ')
+            i++;
+        for (po = i; i < o->size-1 && o->buf[i] != '\r' ; i++)
+           ;
+        
+        (*headers)->value = odr_malloc(o, i - po + 1);
+        memcpy ((*headers)->value, o->buf + po, i - po);
+        (*headers)->value[i - po] = '\0';
+        
+        headers = &(*headers)->next;
+    }
+    *headers = 0;
+    i++;
+    if (o->buf[i] != '\n')
+    {
+        o->error = OHTTP;
+        return 0;
+    }
+    i++;
+
+    if (i > o->size)
+    {
+        o->error = OHTTP;
+        return 0;
+    }
+    else if (i == o->size)
+    {
+        *content_buf = 0;
+        *content_len = 0;
+    }
+    else 
+    {
+        *content_len = o->size - i;
+        *content_buf = odr_malloc(o, *content_len + 1);
+        memcpy(*content_buf, o->buf + i, *content_len);
+        (*content_buf)[*content_len] = '\0';
+    }
+    return 1;
+}
+
+void z_HTTP_header_add(ODR o, Z_HTTP_Header **hp, const char *n,
+                       const char *v)
+{
+    while (*hp)
+        hp = &(*hp)->next;
+    *hp = odr_malloc(o, sizeof(**hp));
+    (*hp)->name = odr_strdup(o, n);
+    (*hp)->value = odr_strdup(o, v);
+    (*hp)->next = 0;
+}
+
+const char *z_HTTP_header_lookup(Z_HTTP_Header *hp, const char *n)
+{
+    for (; hp; hp = hp->next)
+        if (!strcmp(hp->name, n))
+            return hp->value;
+    return 0;
+}
+
+
+Z_GDU *z_get_HTTP_Response(ODR o, int code)
+{
+    Z_GDU *p = odr_malloc(o, sizeof(*p));
+    Z_HTTP_Response *hres;
+
+    p->which = Z_GDU_HTTP_Response;
+    hres = p->u.HTTP_Response = odr_malloc(o, sizeof(*hres));
+    hres->headers = 0;
+    hres->content_len = 0;
+    hres->content_buf = 0;
+    hres->code = code;
+    hres->version = "1.1";
+    z_HTTP_header_add(o, &hres->headers, "Server",
+                      "YAZ/" YAZ_VERSION);
+    if (code != 200)
+    {
+        hres->content_buf = odr_malloc(o, 400);
+        sprintf (hres->content_buf, 
+                 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
+                 "<HTML>\n"
+                 " <HEAD>\n"
+                 "  <TITLE>YAZ " YAZ_VERSION "</TITLE>\n"
+                 " </HEAD>\n"
+                 " <BODY>\n"
+                 "  <P><A HREF=\"http://www.indexdata.dk/yaz/\">YAZ</A> " 
+                 YAZ_VERSION "</P>\n"
+                 "  <P>Error: %d</P>\n"
+                 "  <P>Description: %.50s</P>\n"
+                 " </BODY>\n"
+                 "</HTML>\n",
+                 code, z_HTTP_errmsg(code));
+        hres->content_len = strlen(hres->content_buf);
+        z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html");
+    }
+    return p;
+}
+
+const char *z_HTTP_errmsg(int code)
+{
+    if (code == 200)
+        return "OK";
+    else if (code == 400)
+        return "Bad Request";
+    else if (code == 404)
+        return "Not Found";
+    else if (code == 405)
+        return "Method Not Allowed";
+    else if (code == 500)
+        return "Internal Error";
+    else
+        return "Unknown Error";
+}
+
+int z_GDU (ODR o, Z_GDU **p, int opt, const char *name)
+{
+    if (o->direction == ODR_DECODE) {
+        *p = odr_malloc(o, sizeof(**p));
+        if (o->size > 10 && !memcmp(o->buf, "HTTP/", 5))
+        {
+            int i, po;
+            Z_HTTP_Response *hr;
+           (*p)->which = Z_GDU_HTTP_Response;
+
+            hr = (*p)->u.HTTP_Response = odr_malloc(o, sizeof(*hr));
+
+            po = i = 5;
+            while (i < o->size-2 && o->buf[i] != ' ' && o->buf[i] != '\r')
+                i++;
+            hr->version = odr_malloc(o, i - po + 1);
+            if (i - po)
+                memcpy(hr->version, o->buf + po, i - po);
+            hr->version[i-po] = 0;
+            if (o->buf[i] != ' ')
+            {
+                o->error = OHTTP;
+                return 0;
+            }
+            i++;
+            hr->code = 0;
+            while (i < o->size-2 && o->buf[i] >= '0' && o->buf[i] <= '9')
+            {
+                hr->code = hr->code*10 + (o->buf[i] - '0');
+                i++;
+            }
+            while (i < o->size-1 && o->buf[i] != '\r')
+                i++;
+            return decode_headers_content(o, i, &hr->headers,
+                                          &hr->content_buf, &hr->content_len);            
+        }
+        else if (o->size > 5 &&
+            o->buf[0] >= 0x20 && o->buf[0] < 0x7f
+            && o->buf[1] >= 0x20 && o->buf[1] < 0x7f
+            && o->buf[2] >= 0x20 && o->buf[2] < 0x7f
+            && o->buf[3] >= 0x20 && o->buf[3] < 0x7f)
+        {
+            int i, po;
+            Z_HTTP_Request *hr;
+
+#if HTTP_DEBUG
+           fprintf(stderr, "HTTP decode:\n%.*s\n", o->size, o->buf);
+#endif
+           (*p)->which = Z_GDU_HTTP_Request;
+            hr = (*p)->u.HTTP_Request = odr_malloc(o, sizeof(*hr));
+
+            /* method .. */
+            for (i = 0; o->buf[i] != ' '; i++)
+                if (i >= o->size-5 || i > 30)
+                {
+                    o->error = OHTTP;
+                    return 0;
+                }
+            hr->method = odr_malloc(o, i+1);
+            memcpy (hr->method, o->buf, i);
+            hr->method[i] = '\0';
+            /* path */
+            po = i+1;
+            for (i = po; o->buf[i] != ' '; i++)
+                if (i >= o->size-5)
+                {
+                    o->error = OHTTP;
+                    return 0;
+                }
+            hr->path = odr_malloc(o, i - po + 1);
+            memcpy (hr->path, o->buf+po, i - po);
+            hr->path[i - po] = '\0';
+            /* HTTP version */
+            i++;
+            if (i > o->size-5 || memcmp(o->buf+i, "HTTP/", 5))
+            {
+                o->error = OHTTP;
+                return 0;
+            }
+            i+= 5;
+            po = i;
+            while (o->buf[i] != '\r')
+            {
+                if (i >= o->size-1)
+                {
+                    o->error = OHTTP;
+                    return 0;
+                }
+                i++;
+            }
+            hr->version = odr_malloc(o, i - po + 1);
+            memcpy(hr->version, o->buf + po, i - po);
+            hr->version[i - po] = '\0';
+            /* headers */
+            return decode_headers_content(o, i, &hr->headers,
+                                          &hr->content_buf, &hr->content_len);
+
+        }
+        else
+        {
+           (*p)->which = Z_GDU_Z3950;
+            return z_APDU(o, &(*p)->u.z3950, opt, 0);
+        }
+    }
+    else if (o->direction == ODR_ENCODE)
+    {
+        char sbuf[80];
+        Z_HTTP_Header *h;
+        switch((*p)->which)
+        {
+        case Z_GDU_HTTP_Response:
+            sprintf(sbuf, "HTTP/%s %d %s\r\n", (*p)->u.HTTP_Response->version,
+                    (*p)->u.HTTP_Response->code,
+                    z_HTTP_errmsg((*p)->u.HTTP_Response->code));
+            odr_write(o, sbuf, strlen(sbuf));
+            /* apply Content-Length if not already applied */
+            if (!z_HTTP_header_lookup((*p)->u.HTTP_Response->headers,
+                                      "Content-Length"))
+            {
+                char lstr[20];
+                sprintf(lstr, "%d", (*p)->u.HTTP_Response->content_len);
+                z_HTTP_header_add(o,
+                                  &(*p)->u.HTTP_Response->headers,
+                                  "Content-Length", lstr);
+            }
+            for (h = (*p)->u.HTTP_Response->headers; h; h = h->next)
+            {
+                odr_write(o, h->name, strlen(h->name));
+                odr_write(o, ": ", 2);
+                odr_write(o, h->value, strlen(h->value));
+                odr_write(o, "\r\n", 2);
+            }
+            odr_write(o, "\r\n", 2);
+            if ((*p)->u.HTTP_Response->content_buf)
+                odr_write(o, (*p)->u.HTTP_Response->content_buf,
+                          (*p)->u.HTTP_Response->content_len);
+#if HTTP_DEBUG
+            fprintf(stderr, "HTTP response:\n%.*s\n", o->top, o->buf);
+#endif
+            break;
+        case Z_GDU_HTTP_Request:
+            odr_write(o, (*p)->u.HTTP_Request->method,
+                      strlen((*p)->u.HTTP_Request->method));
+            odr_write(o, " ", 1);
+            odr_write(o, (*p)->u.HTTP_Request->path,
+                      strlen((*p)->u.HTTP_Request->path));
+            odr_write(o, " HTTP/", 6);
+            odr_write(o, (*p)->u.HTTP_Request->version,
+                      strlen((*p)->u.HTTP_Request->version));
+            odr_write(o, "\r\n", 2);
+            for (h = (*p)->u.HTTP_Request->headers; h; h = h->next)
+            {
+                odr_write(o, h->name, strlen(h->name));
+                odr_write(o, ": ", 2);
+                odr_write(o, h->value, strlen(h->value));
+                odr_write(o, "\r\n", 2);
+            }
+            odr_write(o, "\r\n", 2);
+            if ((*p)->u.HTTP_Request->content_buf)
+                odr_write(o, (*p)->u.HTTP_Request->content_buf,
+                          (*p)->u.HTTP_Request->content_len);
+#if HTTP_DEBUG
+            fprintf(stderr, "HTTP request:\n%.*s\n", o->top, o->buf);
+#endif
+            break;
+        case Z_GDU_Z3950:
+            return z_APDU(o, &(*p)->u.z3950, opt, 0);
+        }
+    }
+    else if (o->direction == ODR_PRINT)
+    {
+        switch((*p)->which)
+        {
+        case Z_GDU_HTTP_Response:
+            fprintf (stderr, "not implemented");
+            break;
+        case Z_GDU_HTTP_Request:
+            fprintf (stderr, "not implemented");
+            break;
+        case Z_GDU_Z3950:
+            return z_APDU(o, &(*p)->u.z3950, opt, 0);
+        }
+    }
+    return 1;
+}
+
index aaf9c90..a414e45 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2000-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.16 2003-01-24 12:15:45 adam Exp $
+ * $Id: zoom-c.c,v 1.17 2003-02-12 15:06:44 adam Exp $
  *
  * ZOOM layer for C, connections, result sets, queries.
  */
@@ -401,8 +401,6 @@ 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");
@@ -1582,14 +1580,15 @@ static zoom_ret send_present (ZOOM_connection c)
         compo->u.complex->generic = (Z_Specification *)
             odr_malloc(c->odr_out, sizeof(*compo->u.complex->generic));
 
-        compo->u.complex->generic->schema = (Odr_oid *)
+        compo->u.complex->generic->which = Z_Specification_oid;
+        compo->u.complex->generic->u.oid = (Odr_oid *)
             yaz_str_to_z3950oid (c->odr_out, CLASS_SCHEMA, schema);
 
-        if (!compo->u.complex->generic->schema)
+        if (!compo->u.complex->generic->u.oid)
         {
             /* OID wasn't a schema! Try record syntax instead. */
 
-            compo->u.complex->generic->schema = (Odr_oid *)
+            compo->u.complex->generic->u.oid = (Odr_oid *)
                 yaz_str_to_z3950oid (c->odr_out, CLASS_RECSYN, schema);
         }
         if (elementSetName && *elementSetName)