Added support for SRU scan.
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 16 Aug 2007 10:09:36 +0000 (10:09 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 16 Aug 2007 10:09:36 +0000 (10:09 +0000)
NEWS
doc/zoom.xml
src/zoom-c.c
src/zoom-p.h
zoom/zoomsh.c

diff --git a/NEWS b/NEWS
index 8c07270..08ac12d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,5 @@
+Added support for SRU scan.
+
 Added support for the use of the older versions or Extended Service
 Update in ZOOM. To faciliate this, an option "updateVersion" may be
 set to the version , 1=first, 2=second, 3=third. The third version is
 Added support for the use of the older versions or Extended Service
 Update in ZOOM. To faciliate this, an option "updateVersion" may be
 set to the version , 1=first, 2=second, 3=third. The third version is
index 19f5c37..f1a3f79 100644 (file)
@@ -20,7 +20,7 @@ ZOOM_options_set_int(opt, name, value)
 ZOOM_connection_scan1 (ZOOM_connection c, ZOOM_query startterm)
 ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
 -->
 ZOOM_connection_scan1 (ZOOM_connection c, ZOOM_query startterm)
 ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
 -->
-<!-- $Id: zoom.xml,v 1.61 2007-06-29 08:05:07 adam Exp $ -->
+<!-- $Id: zoom.xml,v 1.62 2007-08-16 10:09:36 adam Exp $ -->
  <chapter id="zoom"><title>ZOOM</title>
   <para>
     &zoom; is an acronym for 'Z39.50 Object-Orientation Model' and is
  <chapter id="zoom"><title>ZOOM</title>
   <para>
     &zoom; is an acronym for 'Z39.50 Object-Orientation Model' and is
@@ -831,14 +831,16 @@ ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
    </para>
 
    <para>
    </para>
 
    <para>
-    The Scan interface is Z39.50 only. SRW version 1.0 does not
-    support this.
+    The Scan interface is supported for both Z39.50 and SRU.
    </para>
 
    <synopsis>
     ZOOM_scanset ZOOM_connection_scan(ZOOM_connection c,
                                       const char *startpqf);
 
    </para>
 
    <synopsis>
     ZOOM_scanset ZOOM_connection_scan(ZOOM_connection c,
                                       const char *startpqf);
 
+    ZOOM_scanset ZOOM_connection_scan1(ZOOM_connection c,
+                                       ZOOM_query q);
+
     size_t ZOOM_scanset_size(ZOOM_scanset scan);
 
     const char * ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
     size_t ZOOM_scanset_size(ZOOM_scanset scan);
 
     const char * ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
@@ -894,6 +896,12 @@ ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
      @attr 1=4 @attr 6=2 "science o"
     </literallayout>
    </para>
      @attr 1=4 @attr 6=2 "science o"
     </literallayout>
    </para>
+
+   <para>
+    The <function>ZOOM_connecton_scan1</function> is a newer and
+    more generic alternative to <function>ZOOM_connection_scan</function>
+    which allows to use both CQL and PQF for Scan.
+   </para>
    
    <table frame="top" id="zoom.scanset.options">
     <title>ZOOM Scan Set Options</title>
    
    <table frame="top" id="zoom.scanset.options">
     <title>ZOOM Scan Set Options</title>
index 3ada8d1..6ebcc33 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.140 2007-08-15 17:53:11 mike Exp $
+ * $Id: zoom-c.c,v 1.141 2007-08-16 10:09:36 adam Exp $
  */
 /**
  * \file zoom-c.c
  */
 /**
  * \file zoom-c.c
@@ -180,6 +180,20 @@ static void set_HTTP_error(ZOOM_connection c, int error,
 {
     set_dset_error(c, error, "HTTP", addinfo, addinfo2);
 }
 {
     set_dset_error(c, error, "HTTP", addinfo, addinfo2);
 }
+
+static void set_SRU_error(ZOOM_connection c, Z_SRW_diagnostic *d)
+{
+    const char *uri = d->uri;
+    if (uri)
+    {
+        int code = 0;       
+        const char *cp;
+        if ((cp = strrchr(uri, '/')))
+            code = atoi(cp+1);
+        set_dset_error(c, code, uri, d->details, 0);
+    }
+}
+
 #endif
 
 
 #endif
 
 
@@ -641,7 +655,7 @@ ZOOM_API(int)
     s->query_string = odr_strdup(s->odr, str);
 
     ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext));
     s->query_string = odr_strdup(s->odr, str);
 
     ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext));
-    ext->direct_reference = odr_getoidbystr(s->odr, "1.2.840.10003.16.2");
+    ext->direct_reference = odr_oiddup(s->odr, yaz_oid_userinfo_cql);
     ext->indirect_reference = 0;
     ext->descriptor = 0;
     ext->which = Z_External_CQL;
     ext->indirect_reference = 0;
     ext->descriptor = 0;
     ext->which = Z_External_CQL;
@@ -803,7 +817,6 @@ ZOOM_resultset ZOOM_resultset_create(void)
     r->next = 0;
     r->databaseNames = 0;
     r->num_databaseNames = 0;
     r->next = 0;
     r->databaseNames = 0;
     r->num_databaseNames = 0;
-    r->rpn_iconv = 0;
     return r;
 }
 
     return r;
 }
 
@@ -835,13 +848,6 @@ ZOOM_API(ZOOM_resultset)
 
     r->options = ZOOM_options_create_with_parent(c->options);
     
 
     r->options = ZOOM_options_create_with_parent(c->options);
     
-    {
-        const char *cp = ZOOM_options_get(r->options, "rpnCharset");
-        if (cp)
-            r->rpn_iconv = yaz_iconv_open(cp, "UTF-8");
-    }
-
-
     start = ZOOM_options_get_int(r->options, "start", 0);
     count = ZOOM_options_get_int(r->options, "count", 0);
     {
     start = ZOOM_options_get_int(r->options, "start", 0);
     count = ZOOM_options_get_int(r->options, "count", 0);
     {
@@ -1014,8 +1020,6 @@ static void resultset_destroy(ZOOM_resultset r)
         }
         ZOOM_query_destroy(r->query);
         ZOOM_options_destroy(r->options);
         }
         ZOOM_query_destroy(r->query);
         ZOOM_options_destroy(r->options);
-        if (r->rpn_iconv)
-            yaz_iconv_close(r->rpn_iconv);
         odr_destroy(r->odr);
         xfree(r->setname);
         xfree(r->schema);
         odr_destroy(r->odr);
         xfree(r->setname);
         xfree(r->schema);
@@ -1342,7 +1346,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
                     odr_prepend(c->odr_out, "ZOOM-C",
                                 ireq->implementationName));
     
                     odr_prepend(c->odr_out, "ZOOM-C",
                                 ireq->implementationName));
     
-    version = odr_strdup(c->odr_out, "$Revision: 1.140 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.141 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
@@ -1570,12 +1574,23 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c)
         set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
         return zoom_complete;
     }
         set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
         return zoom_complete;
     }
-    if (r->query->z_query->which == Z_Query_type_1 && r->rpn_iconv)
+    if (r->query->z_query->which == Z_Query_type_1 || 
+        r->query->z_query->which == Z_Query_type_101)
     {
     {
-        search_req->query = yaz_copy_Z_Query(r->query->z_query, c->odr_out);
-        
-        yaz_query_charset_convert_rpnquery(search_req->query->u.type_1,
-                                           c->odr_out, r->rpn_iconv);
+        const char *cp = ZOOM_options_get(r->options, "rpnCharset");
+        if (cp)
+        {
+            yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8");
+            if (cd)
+            {
+                search_req->query = yaz_copy_Z_Query(search_req->query,
+                                                     c->odr_out);
+                
+                yaz_query_charset_convert_rpnquery(search_req->query->u.type_1,
+                                                   c->odr_out, cd);
+                yaz_iconv_close(cd);
+            }
+        }
     }
     search_req->databaseNames = r->databaseNames;
     search_req->num_databaseNames = r->num_databaseNames;
     }
     search_req->databaseNames = r->databaseNames;
     search_req->num_databaseNames = r->num_databaseNames;
@@ -2468,6 +2483,7 @@ static int scan_response(ZOOM_connection c, Z_ScanResponse *res)
     if (res->entries && res->entries->nonsurrogateDiagnostics)
         response_diag(c, res->entries->nonsurrogateDiagnostics[0]);
     scan->scan_response = res;
     if (res->entries && res->entries->nonsurrogateDiagnostics)
         response_diag(c, res->entries->nonsurrogateDiagnostics[0]);
     scan->scan_response = res;
+    scan->srw_scan_response = 0;
     nmem_transfer(odr_getmem(scan->odr), nmem);
     if (res->stepSize)
         ZOOM_options_set_int(scan->options, "stepSize", *res->stepSize);
     nmem_transfer(odr_getmem(scan->odr), nmem);
     if (res->stepSize)
         ZOOM_options_set_int(scan->options, "stepSize", *res->stepSize);
@@ -2668,81 +2684,25 @@ ZOOM_API(ZOOM_scanset)
 ZOOM_API(ZOOM_scanset)
     ZOOM_connection_scan1(ZOOM_connection c, ZOOM_query q)
 {
 ZOOM_API(ZOOM_scanset)
     ZOOM_connection_scan1(ZOOM_connection c, ZOOM_query q)
 {
-    char *start;
-    char *freeme = 0;
     ZOOM_scanset scan = 0;
 
     ZOOM_scanset scan = 0;
 
-    /*
-     * We need to check the query-type, so we can recognise CQL and
-     * CCL and compile them into a form that we can use here.  The
-     * ZOOM_query structure has no explicit `type' member, but
-     * inspection of the ZOOM_query_prefix() and ZOOM_query_cql()
-     * functions shows how the structure is set up in each case.
-     */
     if (!q->z_query)
         return 0;
     if (!q->z_query)
         return 0;
-    else if (q->z_query->which == Z_Query_type_1) 
-    {
-        yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p PQF '%s'",
-                c, q, q->query_string);
-        start = q->query_string;
-    } 
-    else if (q->z_query->which == Z_Query_type_104)
-    {
-        yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p CQL '%s'",
-                c, q, q->query_string);
-        /*
-         * ### This is wrong: if ZOOM_query_cql2rpn() was used, then
-         * the query already been translated to PQF, so we'd be in the
-         * previous branch.  We only get here if the client submitted
-         * CQL to be interepreted by the server using
-         * ZOOM_query_cql(), in which case we should send it as-is.
-         * We can't do that in Z39.50 as the ScanRequest APDU has no
-         * slot in which to place the CQL, but we could and should do
-         * it for SRU connections.  At present, we can't do that
-         * because there is no slot in the ZOOM_scanset structure to
-         * save the CQL so that it can be sent when the ZOOM_TASK_SCAN
-         * fires.
-         */
-        start = freeme = cql2pqf(c, q->query_string);
-        if (start == 0)
-            return 0;
-    } 
-    else
-    {
-        yaz_log(YLOG_FATAL, "%p ZOOM_connection_scan1 q=%p unknown type '%s'",
-                c, q, q->query_string);
-        abort();
-    }
-    
     scan = (ZOOM_scanset) xmalloc(sizeof(*scan));
     scan->connection = c;
     scan->odr = odr_createmem(ODR_DECODE);
     scan->options = ZOOM_options_create_with_parent(c->options);
     scan->refcount = 1;
     scan->scan_response = 0;
     scan = (ZOOM_scanset) xmalloc(sizeof(*scan));
     scan->connection = c;
     scan->odr = odr_createmem(ODR_DECODE);
     scan->options = ZOOM_options_create_with_parent(c->options);
     scan->refcount = 1;
     scan->scan_response = 0;
-    scan->termListAndStartPoint =
-        p_query_scan(scan->odr, PROTO_Z3950, &scan->attributeSet, start);
-    xfree(freeme);
-
-    {
-        const char *cp = ZOOM_options_get(scan->options, "rpnCharset");
-        if (cp)
-        {
-            yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8");
-            if (cd)
-            {
-                yaz_query_charset_convert_apt(scan->termListAndStartPoint,
-                                              scan->odr, cd);
-            }
-        }
-    }
-        
+    scan->srw_scan_response = 0;
 
 
+    scan->query = q;
+    (q->refcount)++;
     scan->databaseNames = set_DatabaseNames(c, c->options,
                                             &scan->num_databaseNames,
                                             scan->odr);
     scan->databaseNames = set_DatabaseNames(c, c->options,
                                             &scan->num_databaseNames,
                                             scan->odr);
-    if (scan->termListAndStartPoint != 0)
+
+    if (1)
     {
         ZOOM_task task = ZOOM_connection_add_task(c, ZOOM_TASK_SCAN);
         task->u.scan.scan = scan;
     {
         ZOOM_task task = ZOOM_connection_add_task(c, ZOOM_TASK_SCAN);
         task->u.scan.scan = scan;
@@ -2765,6 +2725,8 @@ ZOOM_API(void)
     (scan->refcount)--;
     if (scan->refcount == 0)
     {
     (scan->refcount)--;
     if (scan->refcount == 0)
     {
+        ZOOM_query_destroy(scan->query);
+
         odr_destroy(scan->odr);
         
         ZOOM_options_destroy(scan->options);
         odr_destroy(scan->odr);
         
         ZOOM_options_destroy(scan->options);
@@ -2790,7 +2752,7 @@ static zoom_ret send_package(ZOOM_connection c)
     return do_write(c);
 }
 
     return do_write(c);
 }
 
-static zoom_ret send_scan(ZOOM_connection c)
+static zoom_ret ZOOM_connection_send_scan(ZOOM_connection c)
 {
     ZOOM_scanset scan;
     Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_scanRequest);
 {
     ZOOM_scanset scan;
     Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_scanRequest);
@@ -2802,8 +2764,44 @@ static zoom_ret send_scan(ZOOM_connection c)
     assert (c->tasks->which == ZOOM_TASK_SCAN);
     scan = c->tasks->u.scan.scan;
 
     assert (c->tasks->which == ZOOM_TASK_SCAN);
     scan = c->tasks->u.scan.scan;
 
-    req->termListAndStartPoint = scan->termListAndStartPoint;
-    req->attributeSet = scan->attributeSet;
+    /* Z39.50 scan can only carry RPN */
+    if (scan->query->z_query->which == Z_Query_type_1 ||
+        scan->query->z_query->which == Z_Query_type_101)
+    {
+        Z_RPNQuery *rpn = scan->query->z_query->u.type_1;
+        const char *cp = ZOOM_options_get(scan->options, "rpnCharset");
+        if (cp)
+        {
+            yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8");
+            if (cd)
+            {
+                rpn = yaz_copy_z_RPNQuery(rpn, c->odr_out);
+
+                yaz_query_charset_convert_rpnquery(
+                    rpn, c->odr_out, cd);
+                yaz_iconv_close(cd);
+            }
+        }
+        req->attributeSet = rpn->attributeSetId;
+        if (!req->attributeSet)
+            req->attributeSet = odr_oiddup(c->odr_out, yaz_oid_attset_bib_1);
+        if (rpn->RPNStructure->which == Z_RPNStructure_simple &&
+            rpn->RPNStructure->u.simple->which == Z_Operand_APT)
+        {
+            req->termListAndStartPoint =
+                rpn->RPNStructure->u.simple->u.attributesPlusTerm;
+        }
+        else
+        {
+            set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
+            return zoom_complete;
+        }
+    }
+    else
+    {
+        set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
+        return zoom_complete;
+    }
 
     *req->numberOfTermsRequested =
         ZOOM_options_get_int(scan->options, "number", 10);
 
     *req->numberOfTermsRequested =
         ZOOM_options_get_int(scan->options, "number", 10);
@@ -2822,69 +2820,157 @@ static zoom_ret send_scan(ZOOM_connection c)
     return send_APDU(c, apdu);
 }
 
     return send_APDU(c, apdu);
 }
 
+#if YAZ_HAVE_XML2
+static zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
+{
+    ZOOM_scanset scan;
+    Z_SRW_PDU *sr = 0;
+    const char *option_val = 0;
+
+    if (!c->tasks)
+        return zoom_complete;
+    assert (c->tasks->which == ZOOM_TASK_SCAN);
+    scan = c->tasks->u.scan.scan;
+        
+    sr = yaz_srw_get(c->odr_out, Z_SRW_scan_request);
+
+    /* SRU scan can only carry CQL and PQF */
+    if (scan->query->z_query->which == Z_Query_type_104)
+    {
+        sr->u.scan_request->query_type = Z_SRW_query_type_cql;
+        sr->u.scan_request->scanClause.cql = scan->query->query_string;
+    }
+    else if (scan->query->z_query->which == Z_Query_type_1
+             || scan->query->z_query->which == Z_Query_type_101)
+    {
+        sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
+        sr->u.scan_request->scanClause.pqf = scan->query->query_string;
+    }
+    else
+    {
+        set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_QUERY, 0);
+        return zoom_complete;
+    }
+
+    sr->u.scan_request->maximumTerms = odr_intdup(
+        c->odr_out, ZOOM_options_get_int(scan->options, "number", 10));
+    
+    sr->u.scan_request->responsePosition = odr_intdup(
+        c->odr_out, ZOOM_options_get_int(scan->options, "position", 1));
+    
+    option_val = ZOOM_options_get(scan->options, "extraArgs");
+    if (option_val)
+        sr->extra_args = odr_strdup(c->odr_out, option_val);
+    return send_srw(c, sr);
+}
+#else
+static zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
+{
+    return zoom_complete;
+}
+#endif
+
+
 ZOOM_API(size_t)
     ZOOM_scanset_size(ZOOM_scanset scan)
 {
 ZOOM_API(size_t)
     ZOOM_scanset_size(ZOOM_scanset scan)
 {
-    if (!scan || !scan->scan_response || !scan->scan_response->entries)
+    if (!scan)
         return 0;
         return 0;
-    return scan->scan_response->entries->num_entries;
+
+    if (scan->scan_response && scan->scan_response->entries)
+        return scan->scan_response->entries->num_entries;
+    else if (scan->srw_scan_response)
+        return scan->srw_scan_response->num_terms;
+    return 0;
 }
 
 }
 
-ZOOM_API(const char *)
-    ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
-                      int *occ, int *len)
+static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos,
+                                int *occ,
+                                const char **value_term, size_t *value_len,
+                                const char **disp_term, size_t *disp_len)
 {
 {
-    const char *term = 0;
     size_t noent = ZOOM_scanset_size(scan);
     size_t noent = ZOOM_scanset_size(scan);
-    Z_ScanResponse *res = scan->scan_response;
     
     
-    *len = 0;
+    *value_term = 0;
+    *value_len = 0;
+
+    *disp_term = 0;
+    *disp_len = 0;
+
     *occ = 0;
     *occ = 0;
-    if (pos >= noent)
-        return 0;
-    if (res->entries->entries[pos]->which == Z_Entry_termInfo)
+    if (pos >= noent || pos < 0)
+        return;
+    if (scan->scan_response)
     {
     {
-        Z_TermInfo *t = res->entries->entries[pos]->u.termInfo;
-        
-        if (t->term->which == Z_Term_general)
+        Z_ScanResponse *res = scan->scan_response;
+        if (res->entries->entries[pos]->which == Z_Entry_termInfo)
         {
         {
-            term = (const char *) t->term->u.general->buf;
-            *len = t->term->u.general->len;
+            Z_TermInfo *t = res->entries->entries[pos]->u.termInfo;
+            
+            *value_term = (const char *) t->term->u.general->buf;
+            *value_len = t->term->u.general->len;
+            if (t->displayTerm)
+            {
+                *disp_term = t->displayTerm;
+                *disp_len = strlen(*disp_term);
+            }
+            else if (t->term->which == Z_Term_general)
+            {
+                *disp_term = (const char *) t->term->u.general->buf;
+                *disp_len = t->term->u.general->len;
+            }
+            *occ = t->globalOccurrences ? *t->globalOccurrences : 0;
+        }
+    }
+    if (scan->srw_scan_response)
+    {
+        Z_SRW_scanResponse *res = scan->srw_scan_response;
+        Z_SRW_scanTerm *t = res->terms + pos;
+        if (t)
+        {
+            *value_term = t->value;
+            *value_len = strlen(*value_term);
+
+            if (t->displayTerm)
+                *disp_term = t->displayTerm;
+            else
+                *disp_term = t->value;
+            *disp_len = strlen(*disp_term);
+            *occ = t->numberOfRecords ? *t->numberOfRecords : 0;
         }
         }
-        *occ = t->globalOccurrences ? *t->globalOccurrences : 0;
     }
     }
-    return term;
+}
+
+ZOOM_API(const char *)
+    ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
+                      int *occ, int *len)
+{
+    const char *value_term = 0;
+    size_t value_len = 0;
+    const char *disp_term = 0;
+    size_t disp_len = 0;
+
+    ZOOM_scanset_term_x(scan, pos, occ, &value_term, &value_len,
+                        &disp_term, &disp_len);
+    
+    *len = value_len;
+    return value_term;
 }
 
 ZOOM_API(const char *)
     ZOOM_scanset_display_term(ZOOM_scanset scan, size_t pos,
                               int *occ, int *len)
 {
 }
 
 ZOOM_API(const char *)
     ZOOM_scanset_display_term(ZOOM_scanset scan, size_t pos,
                               int *occ, int *len)
 {
-    const char *term = 0;
-    size_t noent = ZOOM_scanset_size(scan);
-    Z_ScanResponse *res = scan->scan_response;
-    
-    *len = 0;
-    *occ = 0;
-    if (pos >= noent)
-        return 0;
-    if (res->entries->entries[pos]->which == Z_Entry_termInfo)
-    {
-        Z_TermInfo *t = res->entries->entries[pos]->u.termInfo;
+    const char *value_term = 0;
+    size_t value_len = 0;
+    const char *disp_term = 0;
+    size_t disp_len = 0;
 
 
-        if (t->displayTerm)
-        {
-            term = t->displayTerm;
-            *len = strlen(term);
-        }
-        else if (t->term->which == Z_Term_general)
-        {
-            term = (const char *) t->term->u.general->buf;
-            *len = t->term->u.general->len;
-        }
-        *occ = t->globalOccurrences ? *t->globalOccurrences : 0;
-    }
-    return term;
+    ZOOM_scanset_term_x(scan, pos, occ, &value_term, &value_len,
+                        &disp_term, &disp_len);
+    
+    *len = disp_len;
+    return disp_term;
 }
 
 ZOOM_API(const char *)
 }
 
 ZOOM_API(const char *)
@@ -3454,7 +3540,10 @@ static int ZOOM_connection_exec_task(ZOOM_connection c)
             ret = do_connect(c);
             break;
         case ZOOM_TASK_SCAN:
             ret = do_connect(c);
             break;
         case ZOOM_TASK_SCAN:
-            ret = send_scan(c);
+            if (c->proto == PROTO_HTTP)
+                ret = ZOOM_connection_srw_send_scan(c);
+            else
+                ret = ZOOM_connection_send_scan(c);
             break;
         case ZOOM_TASK_PACKAGE:
             ret = send_package(c);
             break;
         case ZOOM_TASK_PACKAGE:
             ret = send_package(c);
@@ -3769,18 +3858,7 @@ static void handle_srw_response(ZOOM_connection c,
         record_cache_add(resultset, npr, pos, syntax, elementSetName);
     }
     if (res->num_diagnostics > 0)
         record_cache_add(resultset, npr, pos, syntax, elementSetName);
     }
     if (res->num_diagnostics > 0)
-    {
-        const char *uri = res->diagnostics[0].uri;
-        if (uri)
-        {
-            int code = 0;       
-            const char *cp;
-            if ((cp = strrchr(uri, '/')))
-                code = atoi(cp+1);
-            set_dset_error(c, code, uri,
-                           res->diagnostics[0].details, 0);
-        }
-    }
+        set_SRU_error(c, &res->diagnostics[0]);
     nmem = odr_extract_mem(c->odr_in);
     nmem_transfer(odr_getmem(resultset->odr), nmem);
     nmem_destroy(nmem);
     nmem = odr_extract_mem(c->odr_in);
     nmem_transfer(odr_getmem(resultset->odr), nmem);
     nmem_destroy(nmem);
@@ -3788,6 +3866,29 @@ static void handle_srw_response(ZOOM_connection c,
 #endif
 
 #if YAZ_HAVE_XML2
 #endif
 
 #if YAZ_HAVE_XML2
+static void handle_srw_scan_response(ZOOM_connection c,
+                                     Z_SRW_scanResponse *res)
+{
+    NMEM nmem = odr_extract_mem(c->odr_in);
+    ZOOM_scanset scan;
+
+    if (!c->tasks || c->tasks->which != ZOOM_TASK_SCAN)
+        return;
+    scan = c->tasks->u.scan.scan;
+
+    if (res->num_diagnostics > 0)
+        set_SRU_error(c, &res->diagnostics[0]);
+
+    scan->scan_response = 0;
+    scan->srw_scan_response = res;
+    nmem_transfer(odr_getmem(scan->odr), nmem);
+
+    ZOOM_options_set_int(scan->options, "number", res->num_terms);
+    nmem_destroy(nmem);
+}
+#endif
+
+#if YAZ_HAVE_XML2
 static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
 {
     int ret = -1;
 static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
 {
     int ret = -1;
@@ -3816,6 +3917,8 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
             Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p;
             if (sr->which == Z_SRW_searchRetrieve_response)
                 handle_srw_response(c, sr->u.response);
             Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p;
             if (sr->which == Z_SRW_searchRetrieve_response)
                 handle_srw_response(c, sr->u.response);
+            else if (sr->which == Z_SRW_scan_response)
+                handle_srw_scan_response(c, sr->u.scan_response);
             else
                 ret = -1;
         }
             else
                 ret = -1;
         }
index bee6458..174d952 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-p.h,v 1.20 2007-05-05 11:55:22 adam Exp $
+ * $Id: zoom-p.h,v 1.21 2007-08-16 10:09:36 adam Exp $
  */
 /**
  * \file zoom-p.h
  */
 /**
  * \file zoom-p.h
@@ -14,6 +14,8 @@
 #include <yaz/wrbuf.h>
 #include <yaz/zoom.h>
 #include <yaz/sortspec.h>
 #include <yaz/wrbuf.h>
 #include <yaz/zoom.h>
 #include <yaz/sortspec.h>
+#include <yaz/srw.h>
+
 typedef struct ZOOM_Event_p *ZOOM_Event;
 
 struct ZOOM_query_p {
 typedef struct ZOOM_Event_p *ZOOM_Event;
 
 struct ZOOM_query_p {
@@ -118,7 +120,6 @@ struct ZOOM_resultset_p {
     ZOOM_resultset next;
     char **databaseNames;
     int num_databaseNames;
     ZOOM_resultset next;
     char **databaseNames;
     int num_databaseNames;
-    yaz_iconv_t rpn_iconv;
 };
 
 struct ZOOM_record_p {
 };
 
 struct ZOOM_record_p {
@@ -143,9 +144,10 @@ struct ZOOM_scanset_p {
     ODR odr;
     ZOOM_options options;
     ZOOM_connection connection;
     ODR odr;
     ZOOM_options options;
     ZOOM_connection connection;
-    Z_AttributesPlusTerm *termListAndStartPoint;
-    Z_AttributeSetId *attributeSet;
+    ZOOM_query query;
     Z_ScanResponse *scan_response;
     Z_ScanResponse *scan_response;
+    Z_SRW_scanResponse *srw_scan_response;
+
     char **databaseNames;
     int num_databaseNames;
 };
     char **databaseNames;
     int num_databaseNames;
 };
index 8b790f1..d25c674 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoomsh.c,v 1.47 2007-04-17 20:26:19 adam Exp $
+ * $Id: zoomsh.c,v 1.48 2007-08-16 10:09:37 adam Exp $
  */
 
 /** \file zoomsh.c
  */
 
 /** \file zoomsh.c
@@ -31,7 +31,7 @@
 
 #define MAX_CON 100
 
 
 #define MAX_CON 100
 
-static int next_token (const char **cpp, const char **t_start)
+static int next_token(const char **cpp, const char **t_start)
 {
     int len = 0;
     const char *cp = *cpp;
 {
     int len = 0;
     const char *cp = *cpp;
@@ -64,10 +64,10 @@ static int next_token (const char **cpp, const char **t_start)
     return len;  /* return -1 if no token was read .. */
 }
 
     return len;  /* return -1 if no token was read .. */
 }
 
-static int next_token_copy (const char **cpp, char *buf_out, int buf_max)
+static int next_token_copy(const char **cpp, char *buf_out, int buf_max)
 {
     const char *start;
 {
     const char *start;
-    int len = next_token (cpp, &start);
+    int len = next_token(cpp, &start);
     if (len < 0)
     {
         *buf_out = 0;
     if (len < 0)
     {
         *buf_out = 0;
@@ -75,51 +75,51 @@ static int next_token_copy (const char **cpp, char *buf_out, int buf_max)
     }
     if (len >= buf_max)
         len = buf_max-1;
     }
     if (len >= buf_max)
         len = buf_max-1;
-    memcpy (buf_out, start, len);
+    memcpy(buf_out, start, len);
     buf_out[len] = '\0';
     return len;
 }
 
     buf_out[len] = '\0';
     return len;
 }
 
-static int is_command (const char *cmd_str, const char *this_str, int this_len)
+static int is_command(const char *cmd_str, const char *this_str, int this_len)
 {
     int cmd_len = strlen(cmd_str);
     if (cmd_len != this_len)
         return 0;
 {
     int cmd_len = strlen(cmd_str);
     if (cmd_len != this_len)
         return 0;
-    if (memcmp (cmd_str, this_str, cmd_len))
+    if (memcmp(cmd_str, this_str, cmd_len))
         return 0;
     return 1;
 }
 
         return 0;
     return 1;
 }
 
-static void cmd_set (ZOOM_connection *c, ZOOM_resultset *r,
-                     ZOOM_options options,
-                     const char **args)
+static void cmd_set(ZOOM_connection *c, ZOOM_resultset *r,
+                    ZOOM_options options,
+                    const char **args)
 {
     char key[40], val[80];
 
 {
     char key[40], val[80];
 
-    if (next_token_copy (args, key, sizeof(key)) < 0)
+    if (next_token_copy(args, key, sizeof(key)) < 0)
     {
     {
-        printf ("missing argument for set\n");
+        printf("missing argument for set\n");
         return ;
     }
         return ;
     }
-    if (next_token_copy (args, val, sizeof(val)) < 0)
+    if (next_token_copy(args, val, sizeof(val)) < 0)
         ZOOM_options_set(options, key, 0);
     else
         ZOOM_options_set(options, key, val);
 }
 
         ZOOM_options_set(options, key, 0);
     else
         ZOOM_options_set(options, key, val);
 }
 
-static void cmd_get (ZOOM_connection *c, ZOOM_resultset *r,
-                     ZOOM_options options,
-                     const char **args)
+static void cmd_get(ZOOM_connection *c, ZOOM_resultset *r,
+                    ZOOM_options options,
+                    const char **args)
 {
     char key[40];
 {
     char key[40];
-    if (next_token_copy (args, key, sizeof(key)) < 0)
+    if (next_token_copy(args, key, sizeof(key)) < 0)
     {
     {
-        printf ("missing argument for get\n");
+        printf("missing argument for get\n");
     }
     else
     {
         const char *val = ZOOM_options_get(options, key);
     }
     else
     {
         const char *val = ZOOM_options_get(options, key);
-        printf ("%s = %s\n", key, val ? val : "<null>");
+        printf("%s = %s\n", key, val ? val : "<null>");
     }
 }
 
     }
 }
 
@@ -128,9 +128,9 @@ static void cmd_rget(ZOOM_connection *c, ZOOM_resultset *r,
                      const char **args)
 {
     char key[40];
                      const char **args)
 {
     char key[40];
-    if (next_token_copy (args, key, sizeof(key)) < 0)
+    if (next_token_copy(args, key, sizeof(key)) < 0)
     {
     {
-        printf ("missing argument for get\n");
+        printf("missing argument for get\n");
     }
     else
     {
     }
     else
     {
@@ -142,47 +142,47 @@ static void cmd_rget(ZOOM_connection *c, ZOOM_resultset *r,
                 continue;
             
             val = ZOOM_resultset_option_get(r[i], key);
                 continue;
             
             val = ZOOM_resultset_option_get(r[i], key);
-            printf ("%s = %s\n", key, val ? val : "<null>");
+            printf("%s = %s\n", key, val ? val : "<null>");
         }
     }
 }
 
         }
     }
 }
 
-static void cmd_close (ZOOM_connection *c, ZOOM_resultset *r,
-                       ZOOM_options options,
-                       const char **args)
+static void cmd_close(ZOOM_connection *c, ZOOM_resultset *r,
+                      ZOOM_options options,
+                      const char **args)
 {
     char host[60];
     int i;
 {
     char host[60];
     int i;
-    next_token_copy (args, host, sizeof(host));
+    next_token_copy(args, host, sizeof(host));
     for (i = 0; i<MAX_CON; i++)
     {
         const char *h;
         if (!c[i])
             continue;
         if ((h = ZOOM_connection_option_get(c[i], "host"))
     for (i = 0; i<MAX_CON; i++)
     {
         const char *h;
         if (!c[i])
             continue;
         if ((h = ZOOM_connection_option_get(c[i], "host"))
-            && !strcmp (h, host))
+            && !strcmp(h, host))
         {
         {
-            ZOOM_connection_destroy (c[i]);
+            ZOOM_connection_destroy(c[i]);
             c[i] = 0;
         }
         else if (*host == '\0')
         {
             c[i] = 0;
         }
         else if (*host == '\0')
         {
-            ZOOM_connection_destroy (c[i]);
+            ZOOM_connection_destroy(c[i]);
             c[i] = 0;
         }
     }
 }
 
             c[i] = 0;
         }
     }
 }
 
-static void display_records (ZOOM_connection c,
-                             ZOOM_resultset r,
-                             int start, int count)
+static void display_records(ZOOM_connection c,
+                            ZOOM_resultset r,
+                            int start, int count)
 {
     int i;
     for (i = 0; i<count; i++)
     {
         int pos = i + start;
 {
     int i;
     for (i = 0; i<count; i++)
     {
         int pos = i + start;
-        ZOOM_record rec = ZOOM_resultset_record (r, pos);
-        const char *db = ZOOM_record_get (rec, "database", 0);
+        ZOOM_record rec = ZOOM_resultset_record(r, pos);
+        const char *db = ZOOM_record_get(rec, "database", 0);
         
         if (ZOOM_record_error(rec, 0, 0, 0))
         {
         
         if (ZOOM_record_error(rec, 0, 0, 0))
         {
@@ -197,41 +197,41 @@ static void display_records (ZOOM_connection c,
         else
         {
             int len, opac_len;
         else
         {
             int len, opac_len;
-            const char *render = ZOOM_record_get (rec, "render", &len);
-            const char *opac_render = ZOOM_record_get (rec, "opac", &opac_len);
-            const char *syntax = ZOOM_record_get (rec, "syntax", 0);
+            const char *render = ZOOM_record_get(rec, "render", &len);
+            const char *opac_render = ZOOM_record_get(rec, "opac", &opac_len);
+            const char *syntax = ZOOM_record_get(rec, "syntax", 0);
             /* if rec is non-null, we got a record for display */
             if (rec)
             {
             /* if rec is non-null, we got a record for display */
             if (rec)
             {
-                printf ("%d %s %s\n",
-                        pos, (db ? db : "unknown"), syntax);
+                printf("%d %s %s\n",
+                       pos, (db ? db : "unknown"), syntax);
                 if (render)
                 if (render)
-                    fwrite (render, 1, len, stdout);
-                printf ("\n");
+                    fwrite(render, 1, len, stdout);
+                printf("\n");
                 if (opac_render)
                 if (opac_render)
-                    fwrite (opac_render, 1, opac_len, stdout);
+                    fwrite(opac_render, 1, opac_len, stdout);
             }
         }
             
     }
 }
 
             }
         }
             
     }
 }
 
-static void cmd_show (ZOOM_connection *c, ZOOM_resultset *r,
-                      ZOOM_options options,
-                      const char **args)
+static void cmd_show(ZOOM_connection *c, ZOOM_resultset *r,
+                     ZOOM_options options,
+                     const char **args)
 {
     int i;
     char start_str[10], count_str[10];
 
 {
     int i;
     char start_str[10], count_str[10];
 
-    if (next_token_copy (args, start_str, sizeof(start_str)) >= 0)
-        ZOOM_options_set (options, "start", start_str);
+    if (next_token_copy(args, start_str, sizeof(start_str)) >= 0)
+        ZOOM_options_set(options, "start", start_str);
 
 
-    if (next_token_copy (args, count_str, sizeof(count_str)) >= 0)
-        ZOOM_options_set (options, "count", count_str);
+    if (next_token_copy(args, count_str, sizeof(count_str)) >= 0)
+        ZOOM_options_set(options, "count", count_str);
 
     for (i = 0; i<MAX_CON; i++)
 
     for (i = 0; i<MAX_CON; i++)
-        ZOOM_resultset_records (r[i], 0, atoi(start_str), atoi(count_str));
-    while (ZOOM_event (MAX_CON, c))
+        ZOOM_resultset_records(r[i], 0, atoi(start_str), atoi(count_str));
+    while (ZOOM_event(MAX_CON, c))
         ;
 
     for (i = 0; i<MAX_CON; i++)
         ;
 
     for (i = 0; i<MAX_CON; i++)
@@ -242,45 +242,45 @@ static void cmd_show (ZOOM_connection *c, ZOOM_resultset *r,
         if (!c[i])
             continue;
         if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
         if (!c[i])
             continue;
         if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
-            printf ("%s error: %s (%s:%d) %s\n",
-                     ZOOM_connection_option_get(c[i], "host"), errmsg,
-                     dset, error, addinfo);
+            printf("%s error: %s (%s:%d) %s\n",
+                   ZOOM_connection_option_get(c[i], "host"), errmsg,
+                   dset, error, addinfo);
         else if (r[i])
         {
             /* OK, no major errors. Display records... */
         else if (r[i])
         {
             /* OK, no major errors. Display records... */
-            int start = ZOOM_options_get_int (options, "start", 0);
-            int count = ZOOM_options_get_int (options, "count", 0);
-            display_records (c[i], r[i], start, count);
+            int start = ZOOM_options_get_int(options, "start", 0);
+            int count = ZOOM_options_get_int(options, "count", 0);
+            display_records(c[i], r[i], start, count);
         }
     }
         }
     }
-    ZOOM_options_set (options, "count", "0");
-    ZOOM_options_set (options, "start", "0");
+    ZOOM_options_set(options, "count", "0");
+    ZOOM_options_set(options, "start", "0");
 }
 
 }
 
-static void cmd_ext (ZOOM_connection *c, ZOOM_resultset *r,
-                     ZOOM_options options,
-                     const char **args)
+static void cmd_ext(ZOOM_connection *c, ZOOM_resultset *r,
+                    ZOOM_options options,
+                    const char **args)
 {
     ZOOM_package p[MAX_CON];
     char ext_type_str[10];
     
     int i;
 
 {
     ZOOM_package p[MAX_CON];
     char ext_type_str[10];
     
     int i;
 
-    if (next_token_copy (args, ext_type_str, sizeof(ext_type_str)) < 0)
+    if (next_token_copy(args, ext_type_str, sizeof(ext_type_str)) < 0)
         return;
     
     for (i = 0; i<MAX_CON; i++)
     {
         if (c[i])
         {
         return;
     
     for (i = 0; i<MAX_CON; i++)
     {
         if (c[i])
         {
-            p[i] = ZOOM_connection_package (c[i], 0);
+            p[i] = ZOOM_connection_package(c[i], 0);
             ZOOM_package_send(p[i], ext_type_str);
         }
         else
             p[i] = 0;
     }
 
             ZOOM_package_send(p[i], ext_type_str);
         }
         else
             p[i] = 0;
     }
 
-    while (ZOOM_event (MAX_CON, c))
+    while (ZOOM_event(MAX_CON, c))
         ;
 
     for (i = 0; i<MAX_CON; i++)
         ;
 
     for (i = 0; i<MAX_CON; i++)
@@ -291,63 +291,65 @@ static void cmd_ext (ZOOM_connection *c, ZOOM_resultset *r,
         if (!p[i])
             continue;
         if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
         if (!p[i])
             continue;
         if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
-            printf ("%s error: %s (%s:%d) %s\n",
-                     ZOOM_connection_option_get(c[i], "host"), errmsg,
-                     dset, error, addinfo);
+            printf("%s error: %s (%s:%d) %s\n",
+                   ZOOM_connection_option_get(c[i], "host"), errmsg,
+                   dset, error, addinfo);
         else if (p[i])
         {
             const char *v;
         else if (p[i])
         {
             const char *v;
-            printf ("ok\n");
-            v = ZOOM_package_option_get (p[i], "targetReference");
+            printf("ok\n");
+            v = ZOOM_package_option_get(p[i], "targetReference");
             if (v)
                 printf("targetReference: %s\n", v);
             if (v)
                 printf("targetReference: %s\n", v);
-            v = ZOOM_package_option_get (p[i], "xmlUpdateDoc");
+            v = ZOOM_package_option_get(p[i], "xmlUpdateDoc");
             if (v)
                 printf("xmlUpdateDoc: %s\n", v);
         }
             if (v)
                 printf("xmlUpdateDoc: %s\n", v);
         }
-        ZOOM_package_destroy (p[i]);
+        ZOOM_package_destroy(p[i]);
     }
 }
 
     }
 }
 
-static void cmd_debug (ZOOM_connection *c, ZOOM_resultset *r,
-                       ZOOM_options options,
-                       const char **args)
+static void cmd_debug(ZOOM_connection *c, ZOOM_resultset *r,
+                      ZOOM_options options,
+                      const char **args)
 {
     yaz_log_init_level(YLOG_ALL);
 }
 
 {
     yaz_log_init_level(YLOG_ALL);
 }
 
-static void cmd_search (ZOOM_connection *c, ZOOM_resultset *r,
-                        ZOOM_options options,
-                        const char **args)
+static void cmd_search(ZOOM_connection *c, ZOOM_resultset *r,
+                       ZOOM_options options,
+                       const char **args)
 {
     ZOOM_query s;
     const char *query_str = *args;
     int i;
     
 {
     ZOOM_query s;
     const char *query_str = *args;
     int i;
     
-    s = ZOOM_query_create ();
+    s = ZOOM_query_create();
     while (*query_str == ' ')
         query_str++;
     if (memcmp(query_str, "cql:", 4) == 0)
     {
     while (*query_str == ' ')
         query_str++;
     if (memcmp(query_str, "cql:", 4) == 0)
     {
-        ZOOM_query_cql (s, query_str + 4);
+        ZOOM_query_cql(s, query_str + 4);
     }
     }
-    else if (ZOOM_query_prefix (s, query_str))
+    else if (ZOOM_query_prefix(s, query_str))
     {
     {
-        printf ("Bad PQF: %s\n", query_str);
+        printf("Bad PQF: %s\n", query_str);
         return;
     }
     for (i = 0; i<MAX_CON; i++)
     {
         return;
     }
     for (i = 0; i<MAX_CON; i++)
     {
+
         if (c[i])
         {
         if (c[i])
         {
-            ZOOM_resultset_destroy (r[i]);
+            ZOOM_resultset_destroy(r[i]);
             r[i] = 0;
         }
         if (c[i])
             r[i] = 0;
         }
         if (c[i])
-            r[i] = ZOOM_connection_search (c[i], s);
+            r[i] = ZOOM_connection_search(c[i], s);
     }
     }
+    ZOOM_query_destroy(s);
 
 
-    while (ZOOM_event (MAX_CON, c))
+    while (ZOOM_event(MAX_CON, c))
         ;
 
     for (i = 0; i<MAX_CON; i++)
         ;
 
     for (i = 0; i<MAX_CON; i++)
@@ -358,46 +360,68 @@ static void cmd_search (ZOOM_connection *c, ZOOM_resultset *r,
         if (!c[i])
             continue;
         if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
         if (!c[i])
             continue;
         if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
-            printf ("%s error: %s (%s:%d) %s\n",
-                    ZOOM_connection_option_get(c[i], "host"), errmsg,
-                    dset, error, addinfo);
+            printf("%s error: %s (%s:%d) %s\n",
+                   ZOOM_connection_option_get(c[i], "host"), errmsg,
+                   dset, error, addinfo);
         else if (r[i])
         {
             /* OK, no major errors. Look at the result count */
         else if (r[i])
         {
             /* OK, no major errors. Look at the result count */
-            int start = ZOOM_options_get_int (options, "start", 0);
-            int count = ZOOM_options_get_int (options, "count", 0);
+            int start = ZOOM_options_get_int(options, "start", 0);
+            int count = ZOOM_options_get_int(options, "count", 0);
 
 
-            printf ("%s: %ld hits\n", ZOOM_connection_option_get(c[i], "host"),
-                    (long) ZOOM_resultset_size(r[i]));
+            printf("%s: %ld hits\n", ZOOM_connection_option_get(c[i], "host"),
+                   (long) ZOOM_resultset_size(r[i]));
             /* and display */
             /* and display */
-            display_records (c[i], r[i], start, count);
+            display_records(c[i], r[i], start, count);
         }
     }
         }
     }
-    ZOOM_query_destroy (s);
 }
 
 }
 
-static void cmd_scan (ZOOM_connection *c, ZOOM_resultset *r,
-                      ZOOM_options options,
-                      const char **args)
+static void cmd_scan(ZOOM_connection *c, ZOOM_resultset *r,
+                     ZOOM_options options,
+                     const char **args)
 {
 {
-    const char *start_term = *args;
+    const char *query_str = *args;
+    ZOOM_query query = ZOOM_query_create();
     int i;
     ZOOM_scanset s[MAX_CON];
     
     int i;
     ZOOM_scanset s[MAX_CON];
     
-    while (*start_term == ' ')
-        start_term++;
+    while (*query_str == ' ')
+        query_str++;
+
+    if (memcmp(query_str, "cql:", 4) == 0)
+    {
+        ZOOM_query_cql(query, query_str + 4);
+    }
+    else if (ZOOM_query_prefix(query, query_str))
+    {
+        printf("Bad PQF: %s\n", query_str);
+        return;
+    }
 
     for (i = 0; i<MAX_CON; i++)
     {
         if (c[i])
 
     for (i = 0; i<MAX_CON; i++)
     {
         if (c[i])
-            s[i] = ZOOM_connection_scan(c[i], start_term);
+            s[i] = ZOOM_connection_scan1(c[i], query);
         else
             s[i] = 0;
     }
         else
             s[i] = 0;
     }
+    ZOOM_query_destroy(query);
+
     while (ZOOM_event(MAX_CON, c))
         ;
     for (i = 0; i<MAX_CON; i++)
     {
     while (ZOOM_event(MAX_CON, c))
         ;
     for (i = 0; i<MAX_CON; i++)
     {
+        int error;
+        const char *errmsg, *addinfo, *dset;
+        /* display errors if any */
+        if (!c[i])
+            continue;
+        if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
+            printf("%s error: %s (%s:%d) %s\n",
+                   ZOOM_connection_option_get(c[i], "host"), errmsg,
+                   dset, error, addinfo);
+
         if (s[i]) {
             size_t p, sz = ZOOM_scanset_size(s[i]);
             for (p = 0; p < sz; p++)
         if (s[i]) {
             size_t p, sz = ZOOM_scanset_size(s[i]);
             for (p = 0; p < sz; p++)
@@ -405,18 +429,18 @@ static void cmd_scan (ZOOM_connection *c, ZOOM_resultset *r,
                 int occ = 0;
                 int len = 0;
                 const char *term = ZOOM_scanset_display_term(s[i], p,
                 int occ = 0;
                 int len = 0;
                 const char *term = ZOOM_scanset_display_term(s[i], p,
-                                &occ, &len);
+                                                             &occ, &len);
                 fwrite(term, 1, len, stdout);
                 fwrite(term, 1, len, stdout);
-                printf (" %d\n", occ);
+                printf(" %d\n", occ);
             }            
             ZOOM_scanset_destroy(s[i]);
         }
     }
 }
 
             }            
             ZOOM_scanset_destroy(s[i]);
         }
     }
 }
 
-static void cmd_sort (ZOOM_connection *c, ZOOM_resultset *r,
-                      ZOOM_options options,
-                      const char **args)
+static void cmd_sort(ZOOM_connection *c, ZOOM_resultset *r,
+                     ZOOM_options options,
+                     const char **args)
 {
     const char *sort_spec = *args;
     int i;
 {
     const char *sort_spec = *args;
     int i;
@@ -433,59 +457,59 @@ static void cmd_sort (ZOOM_connection *c, ZOOM_resultset *r,
         ;
 }
 
         ;
 }
 
-static void cmd_help (ZOOM_connection *c, ZOOM_resultset *r,
-                      ZOOM_options options,
-                      const char **args)
+static void cmd_help(ZOOM_connection *c, ZOOM_resultset *r,
+                     ZOOM_options options,
+                     const char **args)
 {
 {
-    printf ("connect <zurl>\n");
-    printf ("search <pqf>\n");
-    printf ("show [<start> [<count>]\n");
-    printf ("scan <term>\n");
-    printf ("quit\n");
-    printf ("close <zurl>\n");
-    printf ("ext <type>\n");
-    printf ("set <option> [<value>]\n");
-    printf ("get <option>\n");
-    printf ("\n");
-    printf ("options:\n");
-    printf (" start\n");
-    printf (" count\n");
-    printf (" databaseName\n");
-    printf (" preferredRecordSyntax\n");
-    printf (" proxy\n");
-    printf (" elementSetName\n");
-    printf (" maximumRecordSize\n");
-    printf (" preferredRecordSize\n");
-    printf (" async\n");
-    printf (" piggyback\n");
-    printf (" group\n");
-    printf (" user\n");
-    printf (" password\n");
-    printf (" implementationName\n");
-    printf (" charset\n");
-    printf (" lang\n");
+    printf("connect <zurl>\n");
+    printf("search <pqf>\n");
+    printf("show [<start> [<count>]\n");
+    printf("scan <term>\n");
+    printf("quit\n");
+    printf("close <zurl>\n");
+    printf("ext <type>\n");
+    printf("set <option> [<value>]\n");
+    printf("get <option>\n");
+    printf("\n");
+    printf("options:\n");
+    printf(" start\n");
+    printf(" count\n");
+    printf(" databaseName\n");
+    printf(" preferredRecordSyntax\n");
+    printf(" proxy\n");
+    printf(" elementSetName\n");
+    printf(" maximumRecordSize\n");
+    printf(" preferredRecordSize\n");
+    printf(" async\n");
+    printf(" piggyback\n");
+    printf(" group\n");
+    printf(" user\n");
+    printf(" password\n");
+    printf(" implementationName\n");
+    printf(" charset\n");
+    printf(" lang\n");
 }
 
 }
 
-static void cmd_connect (ZOOM_connection *c, ZOOM_resultset *r,
-                         ZOOM_options options,
-                         const char **args)
+static void cmd_connect(ZOOM_connection *c, ZOOM_resultset *r,
+                        ZOOM_options options,
+                        const char **args)
 {
     int error;
     const char *errmsg, *addinfo, *dset;
     char host[60];
     int j, i;
 {
     int error;
     const char *errmsg, *addinfo, *dset;
     char host[60];
     int j, i;
-    if (next_token_copy (args, host, sizeof(host)) < 0)
+    if (next_token_copy(args, host, sizeof(host)) < 0)
     {
     {
-        printf ("missing host after connect\n");
+        printf("missing host after connect\n");
         return ;
     }
     for (j = -1, i = 0; i<MAX_CON; i++)
     {
         const char *h;
         if (c[i] && (h = ZOOM_connection_option_get(c[i], "host")) &&
         return ;
     }
     for (j = -1, i = 0; i<MAX_CON; i++)
     {
         const char *h;
         if (c[i] && (h = ZOOM_connection_option_get(c[i], "host")) &&
-            !strcmp (h, host))
+            !strcmp(h, host))
         {
         {
-            ZOOM_connection_destroy (c[i]);
+            ZOOM_connection_destroy(c[i]);
             break;
         }
         else if (c[i] == 0 && j == -1)
             break;
         }
         else if (c[i] == 0 && j == -1)
@@ -495,62 +519,62 @@ static void cmd_connect (ZOOM_connection *c, ZOOM_resultset *r,
     {
         if (j == -1)
         {
     {
         if (j == -1)
         {
-            printf ("no more connection available\n");
+            printf("no more connection available\n");
             return;
         }
         i = j;   /* OK, use this one is available */
     }
             return;
         }
         i = j;   /* OK, use this one is available */
     }
-    c[i] = ZOOM_connection_create (options);
-    ZOOM_connection_connect (c[i], host, 0);
+    c[i] = ZOOM_connection_create(options);
+    ZOOM_connection_connect(c[i], host, 0);
         
     if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
         
     if ((error = ZOOM_connection_error_x(c[i], &errmsg, &addinfo, &dset)))
-       printf ("%s error: %s (%s:%d) %s\n",
-            ZOOM_connection_option_get(c[i], "host"), errmsg,
-            dset, error, addinfo);
+        printf("%s error: %s (%s:%d) %s\n",
+               ZOOM_connection_option_get(c[i], "host"), errmsg,
+               dset, error, addinfo);
 }
 
 }
 
-static int cmd_parse (ZOOM_connection *c, ZOOM_resultset *r,
-                      ZOOM_options options, 
-                      const char **buf)
+static int cmd_parse(ZOOM_connection *c, ZOOM_resultset *r,
+                     ZOOM_options options, 
+                     const char **buf)
 {
     int cmd_len;
     const char *cmd_str;
 
 {
     int cmd_len;
     const char *cmd_str;
 
-    cmd_len = next_token (buf, &cmd_str);
+    cmd_len = next_token(buf, &cmd_str);
     if (cmd_len < 0)
         return 1;
     if (cmd_len < 0)
         return 1;
-    if (is_command ("quit", cmd_str, cmd_len))
+    if (is_command("quit", cmd_str, cmd_len))
         return 0;
         return 0;
-    else if (is_command ("set", cmd_str, cmd_len))
-        cmd_set (c, r, options, buf);
-    else if (is_command ("get", cmd_str, cmd_len))
-        cmd_get (c, r, options, buf);
-    else if (is_command ("rget", cmd_str, cmd_len))
-        cmd_rget (c, r, options, buf);
-    else if (is_command ("connect", cmd_str, cmd_len))
-        cmd_connect (c, r, options, buf);
-    else if (is_command ("open", cmd_str, cmd_len))
-        cmd_connect (c, r, options, buf);
-    else if (is_command ("search", cmd_str, cmd_len))
-        cmd_search (c, r, options, buf);
-    else if (is_command ("find", cmd_str, cmd_len))
-        cmd_search (c, r, options, buf);
-    else if (is_command ("show", cmd_str, cmd_len))
-        cmd_show (c, r, options, buf);
-    else if (is_command ("close", cmd_str, cmd_len))
-        cmd_close (c, r, options, buf);
-    else if (is_command ("help", cmd_str, cmd_len))
+    else if (is_command("set", cmd_str, cmd_len))
+        cmd_set(c, r, options, buf);
+    else if (is_command("get", cmd_str, cmd_len))
+        cmd_get(c, r, options, buf);
+    else if (is_command("rget", cmd_str, cmd_len))
+        cmd_rget(c, r, options, buf);
+    else if (is_command("connect", cmd_str, cmd_len))
+        cmd_connect(c, r, options, buf);
+    else if (is_command("open", cmd_str, cmd_len))
+        cmd_connect(c, r, options, buf);
+    else if (is_command("search", cmd_str, cmd_len))
+        cmd_search(c, r, options, buf);
+    else if (is_command("find", cmd_str, cmd_len))
+        cmd_search(c, r, options, buf);
+    else if (is_command("show", cmd_str, cmd_len))
+        cmd_show(c, r, options, buf);
+    else if (is_command("close", cmd_str, cmd_len))
+        cmd_close(c, r, options, buf);
+    else if (is_command("help", cmd_str, cmd_len))
         cmd_help(c, r, options, buf);
         cmd_help(c, r, options, buf);
-    else if (is_command ("ext", cmd_str, cmd_len))
+    else if (is_command("ext", cmd_str, cmd_len))
         cmd_ext(c, r, options, buf);
         cmd_ext(c, r, options, buf);
-    else if (is_command ("debug", cmd_str, cmd_len))
+    else if (is_command("debug", cmd_str, cmd_len))
         cmd_debug(c, r, options, buf);
         cmd_debug(c, r, options, buf);
-    else if (is_command ("scan", cmd_str, cmd_len))
+    else if (is_command("scan", cmd_str, cmd_len))
         cmd_scan(c, r, options, buf);
         cmd_scan(c, r, options, buf);
-    else if (is_command ("sort", cmd_str, cmd_len))
+    else if (is_command("sort", cmd_str, cmd_len))
         cmd_sort(c, r, options, buf);
     else
         cmd_sort(c, r, options, buf);
     else
-        printf ("unknown command %.*s\n", cmd_len, cmd_str);
+        printf("unknown command %.*s\n", cmd_len, cmd_str);
     return 2;
 }
 
     return 2;
 }
 
@@ -576,15 +600,15 @@ void shell(ZOOM_connection *c, ZOOM_resultset *r,
             break;
         };
         strcpy(buf,line_in);
             break;
         };
         strcpy(buf,line_in);
-        free (line_in);
+        free(line_in);
 #else    
 #else    
-        printf ("ZOOM>"); fflush (stdout);
-        if (!fgets (buf, 999, stdin))
+        printf("ZOOM>"); fflush(stdout);
+        if (!fgets(buf, 999, stdin))
             break;
 #endif 
         if ((cp = strchr(buf, '\n')))
             *cp = '\0';
             break;
 #endif 
         if ((cp = strchr(buf, '\n')))
             *cp = '\0';
-        if (!cmd_parse (c, r, options, &bp))
+        if (!cmd_parse(c, r, options, &bp))
             break;
     }
 }
             break;
     }
 }
@@ -645,7 +669,7 @@ int main(int argc, char **argv)
         yaz_log_init_level(mask);
     }
     zoomsh(argc, argv);
         yaz_log_init_level(mask);
     }
     zoomsh(argc, argv);
-    exit (0);
+    exit(0);
 }
 /*
  * Local variables:
 }
 /*
  * Local variables: