Link SSL with libyaz.la and yaz-client only.
[yaz-moved-to-github.git] / src / seshigh.c
index 0e3186b..d1205ad 100644 (file)
@@ -1,8 +1,6 @@
-/*
- * Copyright (C) 1995-2007, Index Data ApS
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2008 Index Data
  * See the file LICENSE for details.
- *
- * $Id: seshigh.c,v 1.111 2007-03-13 09:12:09 adam Exp $
  */
 /**
  * \file seshigh.c
@@ -62,7 +60,7 @@
 #include "session.h"
 #include "mime.h"
 #include <yaz/proto.h>
-#include <yaz/oid.h>
+#include <yaz/oid_db.h>
 #include <yaz/log.h>
 #include <yaz/logrpn.h>
 #include <yaz/querytowrbuf.h>
 #include <yaz/otherinfo.h>
 #include <yaz/yaz-util.h>
 #include <yaz/pquery.h>
+#include <yaz/oid_db.h>
 
 #include <yaz/srw.h>
 #include <yaz/backend.h>
+#include <yaz/yaz-ccl.h>
 
 static void process_gdu_request(association *assoc, request *req);
 static int process_z_request(association *assoc, request *req, char **msg);
@@ -495,6 +495,8 @@ static void assoc_init_reset(association *assoc)
     assoc->init->implementation_version = 0;
     assoc->init->implementation_id = 0;
     assoc->init->implementation_name = 0;
+    assoc->init->query_charset = 0;
+    assoc->init->records_in_same_charset = 0;
     assoc->init->bend_sort = NULL;
     assoc->init->bend_search = NULL;
     assoc->init->bend_present = NULL;
@@ -531,14 +533,15 @@ static int srw_bend_init(association *assoc, Z_SRW_diagnostic **d, int *num, Z_S
         
         if (sr->username)
         {
-            Z_IdAuthentication *auth = odr_malloc(assoc->decode, sizeof(*auth));
+            Z_IdAuthentication *auth = (Z_IdAuthentication *)
+                odr_malloc(assoc->decode, sizeof(*auth));
             int len;
 
             len = strlen(sr->username) + 1;
             if (sr->password) 
                 len += strlen(sr->password) + 2;
             auth->which = Z_IdAuthentication_open;
-            auth->u.open = odr_malloc(assoc->decode, len);
+            auth->u.open = (char *) odr_malloc(assoc->decode, len);
             strcpy(auth->u.open, sr->username);
             if (sr->password && *sr->password)
             {
@@ -580,13 +583,13 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr)
 #if YAZ_HAVE_XML2
     yaz_record_conv_t rc = 0;
     const char *match_schema = 0;
-    int *match_syntax = 0;
+    Odr_oid *match_syntax = 0;
 
     if (assoc->server)
     {
         int r;
         const char *input_schema = yaz_get_esn(rr->comp);
-        Odr_oid *input_syntax_raw = rr->request_format_raw;
+        Odr_oid *input_syntax_raw = rr->request_format;
         
         const char *backend_schema = 0;
         Odr_oid *backend_syntax = 0;
@@ -624,26 +627,17 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr)
             if (input_syntax_raw)
             {
                 char oidbuf[OID_STR_MAX];
-                oid_to_dotstring(input_syntax_raw, oidbuf);
+                oid_oid_to_dotstring(input_syntax_raw, oidbuf);
                 rr->errstring = odr_strdup(rr->stream, oidbuf);
             }
             return -1;
         }
         if (backend_schema)
         {
-            yaz_set_esn(&rr->comp, backend_schema, rr->stream->mem);
+            yaz_set_esn(&rr->comp, backend_schema, odr_getmem(rr->stream));
         }
         if (backend_syntax)
-        {
-            oident *oident_syntax = oid_getentbyoid(backend_syntax);
-
-            rr->request_format_raw = backend_syntax;
-            
-            if (oident_syntax)
-                rr->request_format = oident_syntax->value;
-            else
-                rr->request_format = VAL_NONE;
-        }
+            rr->request_format = backend_syntax;
     }
     (*assoc->init->bend_fetch)(assoc->backend, rr);
     if (rc && rr->record && rr->errcode == 0 && rr->len > 0)
@@ -660,17 +654,13 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr)
         else
         {
             rr->len = wrbuf_len(output_record);
-            rr->record = odr_malloc(rr->stream, rr->len);
+            rr->record = (char *) odr_malloc(rr->stream, rr->len);
             memcpy(rr->record, wrbuf_buf(output_record), rr->len);
         }
-        wrbuf_free(output_record, 1);
+        wrbuf_destroy(output_record);
     }
     if (match_syntax)
-    {
-        struct oident *oi = oid_getentbyoid(match_syntax);
-        rr->output_format = oi ? oi->value : VAL_NONE;
-        rr->output_format_raw = match_syntax;
-    }
+        rr->output_format = match_syntax;
     if (match_schema)
         rr->schema = odr_strdup(rr->stream, match_schema);
     return 0;
@@ -691,10 +681,8 @@ static int srw_bend_fetch(association *assoc, int pos,
     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_RECSYN,
-                                                   VAL_TEXT_XML);
+    rr.request_format = odr_oiddup(assoc->decode, yaz_oid_recsyn_xml);
+
     rr.comp = (Z_RecordComposition *)
             odr_malloc(assoc->decode, sizeof(*rr.comp));
     rr.comp->which = Z_RecordComp_complex;
@@ -747,29 +735,7 @@ static int srw_bend_fetch(association *assoc, int pos,
     if (rr.errcode && rr.surrogate_flag)
     {
         int code = yaz_diag_bib1_to_srw(rr.errcode);
-        const char *message = yaz_diag_srw_str(code);
-        int len = 200;
-        if (message)
-            len += strlen(message);
-        if (rr.errstring)
-            len += strlen(rr.errstring);
-
-        record->recordData_buf = odr_malloc(o, len);
-        
-        sprintf(record->recordData_buf, "<diagnostic "
-                "xmlns=\"http://www.loc.gov/zing/srw/diagnostic/\">\n"
-                " <uri>info:srw/diagnostic/1/%d</uri>\n", code);
-        if (rr.errstring)
-            sprintf(record->recordData_buf + strlen(record->recordData_buf),
-                    " <details>%s</details>\n", rr.errstring);
-        if (message)
-            sprintf(record->recordData_buf + strlen(record->recordData_buf),
-                    " <message>%s</message>\n", message);
-        sprintf(record->recordData_buf + strlen(record->recordData_buf),
-                "</diagnostic>\n");
-        record->recordData_len = strlen(record->recordData_buf);
-        record->recordPosition = odr_intdup(o, pos);
-        record->recordSchema = "info:srw/schema/1/diagnostics-v1.1";
+        yaz_mk_sru_surrogate(o, record, pos, code, rr.errstring);
         return 0;
     }
     else if (rr.len >= 0)
@@ -777,10 +743,8 @@ static int srw_bend_fetch(association *assoc, int pos,
         record->recordData_buf = rr.record;
         record->recordData_len = rr.len;
         record->recordPosition = odr_intdup(o, pos);
-        if (rr.schema)
-            record->recordSchema = odr_strdup(o, rr.schema);
-        else
-            record->recordSchema = 0;
+        record->recordSchema = odr_strdup_null(
+            o, rr.schema ? rr.schema : srw_req->recordSchema);
     }
     if (rr.errcode)
     {
@@ -803,8 +767,7 @@ static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct,
     r = cql_parser_string(cp, cql);
     if (r)
     {
-        /* CQL syntax error */
-        srw_errcode = 10; 
+        srw_errcode = YAZ_SRW_QUERY_SYNTAX_ERROR;
     }
     if (!r)
     {
@@ -813,7 +776,7 @@ static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct,
                               cql_parser_result(cp),
                               rpn_buf, sizeof(rpn_buf)-1);
         if (r)
-            srw_errcode  = cql_transform_error(ct, &add);
+            srw_errcode = cql_transform_error(ct, &add);
     }
     if (!r)
     {
@@ -828,7 +791,7 @@ static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct,
             int code = yaz_pqf_error(pp, &pqf_msg, &off);
             yaz_log(YLOG_WARN, "PQF Parser Error %s (code %d)",
                     pqf_msg, code);
-            srw_errcode = 10;
+            srw_errcode = YAZ_SRW_QUERY_SYNTAX_ERROR;
         }
         else
         {
@@ -850,19 +813,38 @@ static int cql2pqf_scan(ODR odr, const char *cql, cql_transform_t ct,
     if (srw_error)
         return srw_error;
     if (query.which != Z_Query_type_1 && query.which != Z_Query_type_101)
-        return 10; /* bad query type */
+        return YAZ_SRW_QUERY_SYNTAX_ERROR; /* bad query type */
     rpn = query.u.type_1;
     if (!rpn->RPNStructure) 
-        return 10; /* must be structure */
+        return YAZ_SRW_QUERY_SYNTAX_ERROR; /* must be structure */
     if (rpn->RPNStructure->which != Z_RPNStructure_simple)
-        return 10; /* must be simple */
+        return YAZ_SRW_QUERY_SYNTAX_ERROR; /* must be simple */
     if (rpn->RPNStructure->u.simple->which != Z_Operand_APT)
-        return 10; /* must be attributes plus term node .. */
+        return YAZ_SRW_QUERY_SYNTAX_ERROR; /* must be be attributes + term */
     memcpy(result, rpn->RPNStructure->u.simple->u.attributesPlusTerm,
            sizeof(*result));
     return 0;
 }
                    
+
+static int ccl2pqf(ODR odr, const Odr_oct *ccl, CCL_bibset bibset,
+                   bend_search_rr *bsrr) {
+    char *ccl0;
+    struct ccl_rpn_node *node;
+    int errcode, pos;
+
+    ccl0 = odr_strdupn(odr, (char*) ccl->buf, ccl->len);
+    if ((node = ccl_find_str(bibset, ccl0, &errcode, &pos)) == 0) {
+        bsrr->errstring = (char*) ccl_err_msg(errcode);
+        return YAZ_SRW_QUERY_SYNTAX_ERROR;    /* Query syntax error */
+    }
+
+    bsrr->query->which = Z_Query_type_1;
+    bsrr->query->u.type_1 = ccl_rpn_query(odr, node);
+    return 0;
+}
+
+
 static void srw_bend_search(association *assoc, request *req,
                             Z_SRW_PDU *sr,
                             Z_SRW_searchRetrieveResponse *srw_res,
@@ -1001,12 +983,14 @@ static void srw_bend_search(association *assoc, request *req,
                         odr_intdup(assoc->encode, *rr.srw_setnameIdleTime );
                }
                 
-                if ((rr.hits > 0 && start > rr.hits) || start < 1)
+                if (start > rr.hits || start < 1)
                 {
-                    yaz_add_srw_diagnostic(
-                        assoc->encode, 
-                        &srw_res->diagnostics, &srw_res->num_diagnostics,
-                        YAZ_SRW_FIRST_RECORD_POSITION_OUT_OF_RANGE, 0);
+                    /* if hits<=0 and start=1 we don't return a diagnostic */
+                    if (start != 1)
+                        yaz_add_srw_diagnostic(
+                            assoc->encode, 
+                            &srw_res->diagnostics, &srw_res->num_diagnostics,
+                            YAZ_SRW_FIRST_RECORD_POSITION_OUT_OF_RANGE, 0);
                 }
                 else if (number > 0)
                 {
@@ -1023,7 +1007,6 @@ static void srw_bend_search(association *assoc, request *req,
                         bprr->setname = "default";
                         bprr->start = start;
                         bprr->number = number;
-                        bprr->format = VAL_TEXT_XML;
                         if (srw_req->recordSchema)
                         {
                             bprr->comp = (Z_RecordComposition *) odr_malloc(assoc->decode,
@@ -1156,15 +1139,15 @@ static void srw_bend_search(association *assoc, request *req,
                       srw_res->resultSetId : "-"),
                      (srw_req->startRecord ? *srw_req->startRecord : 1), 
                      srw_res->num_records);
-        yaz_log(log_request, "%s %s: %s", wrbuf_buf(wr), querytype, querystr);
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), querytype, querystr);
+        wrbuf_destroy(wr);
     }
 }
 
 static char *srw_bend_explain_default(void *handle, bend_explain_rr *rr)
 {
 #if YAZ_HAVE_XML2
-    xmlNodePtr ptr = rr->server_node_ptr;
+    xmlNodePtr ptr = (xmlNode *) rr->server_node_ptr;
     if (!ptr)
         return 0;
     for (ptr = ptr->children; ptr; ptr = ptr->next)
@@ -1276,12 +1259,14 @@ static void srw_bend_scan(association *assoc, request *req,
         bsrr->print = assoc->print;
         bsrr->step_size = odr_intdup(assoc->decode, 0);
         bsrr->entries = 0;
+        bsrr->setname = 0;
 
         if (bsrr->num_entries > 0) 
         {
             int i;
-            bsrr->entries = odr_malloc(assoc->decode, sizeof(*bsrr->entries) *
-                                       bsrr->num_entries);
+            bsrr->entries = (struct scan_entry *) 
+                odr_malloc(assoc->decode, sizeof(*bsrr->entries) *
+                           bsrr->num_entries);
             for (i = 0; i<bsrr->num_entries; i++)
             {
                 bsrr->entries[i].term = 0;
@@ -1296,20 +1281,11 @@ static void srw_bend_scan(association *assoc, request *req,
         if (srw_req->query_type == Z_SRW_query_type_pqf &&
             assoc->init->bend_scan)
         {
-            Odr_oid *scan_attributeSet = 0;
-            oident *attset;
             YAZ_PQF_Parser pqf_parser = yaz_pqf_create();
             
             bsrr->term = yaz_pqf_scan(pqf_parser, assoc->decode,
-                                      &scan_attributeSet, 
+                                      &bsrr->attributeset, 
                                       srw_req->scanClause.pqf); 
-            if (scan_attributeSet &&
-                (attset = oid_getentbyoid(scan_attributeSet)) &&
-                (attset->oclass == CLASS_ATTSET ||
-                 attset->oclass == CLASS_GENERAL))
-                bsrr->attributeset = attset->value;
-            else
-                bsrr->attributeset = VAL_NONE;
             yaz_pqf_destroy(pqf_parser);
             bsrr->scanClause = 0;
             ((int (*)(void *, bend_scan_rr *))
@@ -1321,8 +1297,9 @@ static void srw_bend_scan(association *assoc, request *req,
         {
             int srw_error;
             bsrr->scanClause = 0;
-            bsrr->attributeset = VAL_NONE;
-            bsrr->term = odr_malloc(assoc->decode, sizeof(*bsrr->term));
+            bsrr->attributeset = 0;
+            bsrr->term = (Z_AttributesPlusTerm *)
+                odr_malloc(assoc->decode, sizeof(*bsrr->term));
             srw_error = cql2pqf_scan(assoc->encode,
                                      srw_req->scanClause.cql,
                                      assoc->server->cql_transform,
@@ -1341,7 +1318,7 @@ static void srw_bend_scan(association *assoc, request *req,
                  && assoc->init->bend_srw_scan)
         {
             bsrr->term = 0;
-            bsrr->attributeset = VAL_NONE;
+            bsrr->attributeset = 0;
             bsrr->scanClause = srw_req->scanClause.cql;
             ((int (*)(void *, bend_scan_rr *))
              (*assoc->init->bend_srw_scan))(assoc->backend, bsrr);
@@ -1434,8 +1411,8 @@ static void srw_bend_scan(association *assoc, request *req,
                       *srw_req->maximumTerms : 1));
         /* there is no step size in SRU/W ??? */
         wrbuf_printf(wr, "%s: %s ", querytype, querystr);
-        yaz_log(log_request, "%s ", wrbuf_buf(wr) );
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s ", wrbuf_cstr(wr) );
+        wrbuf_destroy(wr);
     }
 
 }
@@ -1693,7 +1670,7 @@ static char *read_file(const char *fname, ODR o, int *sz)
     fseek(inf, 0L, SEEK_END);
     *sz = ftell(inf);
     rewind(inf);
-    buf = odr_malloc(o, *sz);
+    buf = (char *) odr_malloc(o, *sz);
     fread(buf, 1, *sz, inf);
     fclose(inf);
     return buf;     
@@ -1797,8 +1774,8 @@ static void process_http_request(association *assoc, request *req)
         if (sr->which == Z_SRW_searchRetrieve_request)
         {
             Z_SRW_PDU *res =
-                yaz_srw_get(assoc->encode, Z_SRW_searchRetrieve_response);
-
+                yaz_srw_get_pdu(assoc->encode, Z_SRW_searchRetrieve_response,
+                                sr->srw_version);
             stylesheet = sr->u.request->stylesheet;
             if (num_diagnostic)
             {
@@ -1815,7 +1792,8 @@ static void process_http_request(association *assoc, request *req)
         }
         else if (sr->which == Z_SRW_explain_request)
         {
-            Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_explain_response);
+            Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_explain_response,
+                                             sr->srw_version);
             stylesheet = sr->u.explain_request->stylesheet;
             if (num_diagnostic)
             {   
@@ -1829,7 +1807,8 @@ static void process_http_request(association *assoc, request *req)
         }
         else if (sr->which == Z_SRW_scan_request)
         {
-            Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_scan_response);
+            Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_scan_response,
+                                             sr->srw_version);
             stylesheet = sr->u.scan_request->stylesheet;
             if (num_diagnostic)
             {   
@@ -1843,7 +1822,8 @@ static void process_http_request(association *assoc, request *req)
         }
         else if (sr->which == Z_SRW_update_request)
         {
-            Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_update_response);
+            Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_update_response,
+                                             sr->srw_version);
             yaz_log(YLOG_DEBUG, "handling SRW UpdateRequest");
             if (num_diagnostic)
             {   
@@ -1874,7 +1854,7 @@ static void process_http_request(association *assoc, request *req)
 #endif
                 {0, 0, 0}
             };
-            char ctype[60];
+            char ctype[80];
             int ret;
             p = z_get_HTTP_Response(o, 200);
             hres = p->u.HTTP_Response;
@@ -1892,7 +1872,7 @@ static void process_http_request(association *assoc, request *req)
             hres->code = http_code;
 
             strcpy(ctype, "text/xml");
-            if (charset)
+            if (charset && strlen(charset) < sizeof(ctype)-30)
             {
                 strcat(ctype, "; charset=");
                 strcat(ctype, charset);
@@ -2170,7 +2150,7 @@ static int process_z_response(association *assoc, request *req, Z_APDU *res)
 
 static char *get_vhost(Z_OtherInformation *otherInfo)
 {
-    return yaz_oi_get_string_oidval(&otherInfo, VAL_PROXY, 1, 0);
+    return yaz_oi_get_string_oid(&otherInfo, yaz_oid_userinfo_proxy, 1, 0);
 }
 
 /*
@@ -2241,7 +2221,8 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     else
     {
         /* no backend. return error */
-        binitres = odr_malloc(assoc->encode, sizeof(*binitres));
+        binitres = (bend_initresult *)
+            odr_malloc(assoc->encode, sizeof(*binitres));
         binitres->errstring = 0;
         binitres->errcode = YAZ_BIB1_PERMANENT_SYSTEM_ERROR;
         iochan_settimeout(assoc->client_chan, 10);
@@ -2306,26 +2287,34 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
         ODR_MASK_SET(resp->options, Z_Options_sort);
         strcat(options, " sort");
     }
-
-    if (ODR_MASK_GET(req->options, Z_Options_negotiationModel)
-        && assoc->init->charneg_response)
+    
+    if (ODR_MASK_GET(req->options, Z_Options_negotiationModel))
     {
-        Z_OtherInformation **p;
         Z_OtherInformationUnit *p0;
-        
-        yaz_oi_APDU(apdu, &p);
-        
-        if ((p0=yaz_oi_update(p, assoc->encode, NULL, 0, 0))) {
-            ODR_MASK_SET(resp->options, Z_Options_negotiationModel);
-            
+
+        if (!assoc->init->charneg_response)
+        {
+            if (assoc->init->query_charset)
+            {
+                assoc->init->charneg_response = yaz_set_response_charneg(
+                    assoc->encode, assoc->init->query_charset, 0, 
+                    assoc->init->records_in_same_charset);
+            }
+            else
+            {
+                yaz_log(YLOG_WARN, "default query_charset not defined by backend");
+            }
+        }
+        if (assoc->init->charneg_response
+            && (p0=yaz_oi_update(&resp->otherInfo, assoc->encode, NULL, 0, 0)))
+        {
             p0->which = Z_OtherInfo_externallyDefinedInfo;
             p0->information.externallyDefinedInfo =
                 assoc->init->charneg_response;
+            ODR_MASK_SET(resp->options, Z_Options_negotiationModel);
+            strcat(options, " negotiation");
         }
-        ODR_MASK_SET(resp->options, Z_Options_negotiationModel);
-        strcat(options, " negotiation");
     }
-        
     if (ODR_MASK_GET(req->options, Z_Options_triggerResourceCtrl))
         ODR_MASK_SET(resp->options, Z_Options_triggerResourceCtrl);
 
@@ -2364,7 +2353,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
                 assoc->init->implementation_name,
                 odr_prepend(assoc->encode, "GFS", resp->implementationName));
 
-    version = odr_strdup(assoc->encode, "$Revision: 1.111 $");
+    version = odr_strdup(assoc->encode, "$Revision: 1.128 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     resp->implementationVersion = odr_prepend(assoc->encode,
@@ -2427,8 +2416,8 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
                      (req->implementationVersion ?
                       req->implementationVersion : "-")
             );
-        yaz_log(log_request, "%s", wrbuf_buf(wr));
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s", wrbuf_cstr(wr));
+        wrbuf_destroy(wr);
     }
     return apdu;
 }
@@ -2476,9 +2465,9 @@ static Z_NamePlusRecord *surrogatediagrec(association *assoc,
 
 static Z_Records *pack_records(association *a, char *setname, int start,
                                int *num, Z_RecordComposition *comp,
-                               int *next, int *pres, oid_value format,
+                               int *next, int *pres,
                                Z_ReferenceId *referenceId,
-                               int *oid, int *errcode)
+                               Odr_oid *oid, int *errcode)
 {
     int recno, total_length = 0, toget = *num, dumped_records = 0;
     Z_Records *records =
@@ -2520,10 +2509,8 @@ static Z_Records *pack_records(association *a, char *setname, int start,
         freq.surrogate_flag = 0;
         freq.number = recno;
         freq.comp = comp;
-        freq.request_format = format;
-        freq.request_format_raw = oid;
-        freq.output_format = format;
-        freq.output_format_raw = 0;
+        freq.request_format = oid;
+        freq.output_format = 0;
         freq.stream = a->encode;
         freq.print = a->print;
         freq.referenceId = referenceId;
@@ -2533,11 +2520,9 @@ static Z_Records *pack_records(association *a, char *setname, int start,
 
         *next = freq.last_in_set ? 0 : recno + 1;
 
-        /* backend should be able to signal whether error is system-wide
-           or only pertaining to current record */
         if (freq.errcode)
         {
-            if (!freq.surrogate_flag)
+            if (!freq.surrogate_flag) /* non-surrogate diagnostic i.e. global */
             {
                 char s[20];
                 *pres = Z_PresentStatus_failure;
@@ -2609,19 +2594,13 @@ static Z_Records *pack_records(association *a, char *setname, int start,
         if (!(thisrec = (Z_NamePlusRecord *)
               odr_malloc(a->encode, sizeof(*thisrec))))
             return 0;
-        if (freq.basename)
-            thisrec->databaseName = odr_strdup(a->encode, freq.basename);
-        else
-            thisrec->databaseName = 0;
+        thisrec->databaseName = odr_strdup_null(a->encode, freq.basename);
         thisrec->which = Z_NamePlusRecord_databaseRecord;
 
-        if (freq.output_format_raw)
-        {
-            struct oident *ident = oid_getentbyoid(freq.output_format_raw);
-            freq.output_format = ident->value;
-        }
-        thisrec->u.databaseRecord = z_ext_record(a->encode, freq.output_format,
-                                                 freq.record, freq.len);
+        if (!freq.output_format)
+            freq.output_format = freq.request_format;
+        thisrec->u.databaseRecord = z_ext_record_oid(
+            a->encode, freq.output_format, freq.record, freq.len);
         if (!thisrec->u.databaseRecord)
             return 0;
         reclist->records[reclist->num_records] = thisrec;
@@ -2668,7 +2647,7 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb,
         bsrr->basenames = req->databaseNames;
         bsrr->query = req->query;
         bsrr->stream = assoc->encode;
-        nmem_transfer(bsrr->stream->mem, reqb->request_mem);
+        nmem_transfer(odr_getmem(bsrr->stream), reqb->request_mem);
         bsrr->decode = assoc->decode;
         bsrr->print = assoc->print;
         bsrr->hits = 0;
@@ -2687,6 +2666,18 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb,
             if (srw_errcode)
                 bsrr->errcode = yaz_diag_srw_to_bib1(srw_errcode);
         }
+
+        if (assoc->server && assoc->server->ccl_transform 
+            && req->query->which == Z_Query_type_2) /*CCL*/
+        {
+            /* have a CCL query and a CCL to PQF transform .. */
+            int srw_errcode = 
+                ccl2pqf(bsrr->stream, req->query->u.type_2,
+                        assoc->server->ccl_transform, bsrr);
+            if (srw_errcode)
+                bsrr->errcode = yaz_diag_srw_to_bib1(srw_errcode);
+        }
+
         if (!bsrr->errcode)
             (assoc->init->bend_search)(assoc->backend, bsrr);
         if (!bsrr->request)  /* backend not ready with the search response */
@@ -2774,15 +2765,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
 
         if (*toget && !resp->records)
         {
-            oident *prefformat;
-            oid_value form;
             int *presst = odr_intdup(assoc->encode, 0);
-
-            if (!(prefformat = oid_getentbyoid(req->preferredRecordSyntax)))
-                form = VAL_NONE;
-            else
-                form = prefformat->value;
-
             /* Call bend_present if defined */
             if (assoc->init->bend_present)
             {
@@ -2791,7 +2774,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
                 bprr->setname = req->resultSetName;
                 bprr->start = 1;
                 bprr->number = *toget;
-                bprr->format = form;
+                bprr->format = req->preferredRecordSyntax;
                 bprr->comp = compp;
                 bprr->referenceId = req->referenceId;
                 bprr->stream = assoc->encode;
@@ -2812,9 +2795,10 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
             }
 
             if (!resp->records)
-                resp->records = pack_records(assoc, req->resultSetName, 1,
-                                             toget, compp, next, presst, form, req->referenceId,
-                                             req->preferredRecordSyntax, NULL);
+                resp->records = pack_records(
+                    assoc, req->resultSetName, 1,
+                    toget, compp, next, presst, req->referenceId,
+                    req->preferredRecordSyntax, NULL);
             if (!resp->records)
                 return 0;
             resp->numberOfRecordsReturned = toget;
@@ -2864,8 +2848,8 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
                      req->resultSetName, returnedrecs);
         yaz_query_to_wrbuf(wr, req->query);
         
-        yaz_log(log_request, "Search %s", wrbuf_buf(wr));
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "Search %s", wrbuf_cstr(wr));
+        wrbuf_destroy(wr);
     }
     return apdu;
 }
@@ -2889,8 +2873,6 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
                                       int *fd)
 {
     Z_PresentRequest *req = reqb->apdu_request->u.presentRequest;
-    oident *prefformat;
-    oid_value form;
     Z_APDU *apdu;
     Z_PresentResponse *resp;
     int *next;
@@ -2900,10 +2882,6 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
 
     yaz_log(log_requestdetail, "Got PresentRequest.");
 
-    if (!(prefformat = oid_getentbyoid(req->preferredRecordSyntax)))
-        form = VAL_NONE;
-    else
-        form = prefformat->value;
     resp = (Z_PresentResponse *)odr_malloc (assoc->encode, sizeof(*resp));
     resp->records = 0;
     resp->presentStatus = odr_intdup(assoc->encode, 0);
@@ -2914,7 +2892,7 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
         bprr->setname = req->resultSetId;
         bprr->start = *req->resultSetStartPoint;
         bprr->number = *req->numberOfRecordsRequested;
-        bprr->format = form;
+        bprr->format = req->preferredRecordSyntax;
         bprr->comp = req->recordComposition;
         bprr->referenceId = req->referenceId;
         bprr->stream = assoc->encode;
@@ -2951,7 +2929,7 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
             pack_records(assoc, req->resultSetId, *req->resultSetStartPoint,
                          num, req->recordComposition, next,
                          resp->presentStatus,
-                         form, req->referenceId, req->preferredRecordSyntax, 
+                         req->referenceId, req->preferredRecordSyntax, 
                          &errcode);
     }
     if (log_request)
@@ -2969,8 +2947,8 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
         wrbuf_printf(wr, " %s %d+%d ",
                 req->resultSetId, *req->resultSetStartPoint,
                 *req->numberOfRecordsRequested);
-        yaz_log(log_request, "%s", wrbuf_buf(wr) );
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s", wrbuf_cstr(wr) );
+        wrbuf_destroy(wr);
     }
     if (!resp->records)
         return 0;
@@ -2995,7 +2973,6 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
     Z_ListEntries *ents = (Z_ListEntries *)
         odr_malloc (assoc->encode, sizeof(*ents));
     Z_DiagRecs *diagrecs_p = NULL;
-    oident *attset;
     bend_scan_rr *bsrr = (bend_scan_rr *)
         odr_malloc (assoc->encode, sizeof(*bsrr));
     struct scan_entry *save_entries;
@@ -3039,6 +3016,8 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
     bsrr->stream = assoc->encode;
     bsrr->print = assoc->print;
     bsrr->step_size = res->stepSize;
+    bsrr->setname = yaz_oi_get_string_oid(&req->otherInfo, 
+                                          yaz_oid_userinfo_scan_set, 1, 0);
     bsrr->entries = 0;
     /* For YAZ 2.0 and earlier it was the backend handler that
        initialized entries (member display_term did not exist)
@@ -3050,8 +3029,9 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
     if (bsrr->num_entries > 0) 
     {
         int i;
-        bsrr->entries = odr_malloc(assoc->decode, sizeof(*bsrr->entries) *
-                                   bsrr->num_entries);
+        bsrr->entries = (struct scan_entry *)
+            odr_malloc(assoc->decode, sizeof(*bsrr->entries) *
+                       bsrr->num_entries);
         for (i = 0; i<bsrr->num_entries; i++)
         {
             bsrr->entries[i].term = 0;
@@ -3063,12 +3043,7 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
     }
     save_entries = bsrr->entries;  /* save it so we can compare later */
 
-    if (req->attributeSet &&
-        (attset = oid_getentbyoid(req->attributeSet)) &&
-        (attset->oclass == CLASS_ATTSET || attset->oclass == CLASS_GENERAL))
-        bsrr->attributeset = attset->value;
-    else
-        bsrr->attributeset = VAL_NONE;
+    bsrr->attributeset = req->attributeSet;
     log_scan_term_level (log_requestdetail, req->termListAndStartPoint, 
             bsrr->attributeset);
     bsrr->term_position = req->preferredPositionInResponse ?
@@ -3156,39 +3131,36 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
         int i;
         WRBUF wr = wrbuf_alloc();
         wrbuf_printf(wr, "Scan ");
-        for (i = 0 ; i < req->num_databaseNames; i++){
+        for (i = 0 ; i < req->num_databaseNames; i++)
+        {
             if (i)
                 wrbuf_printf(wr, "+");
             wrbuf_printf(wr, req->databaseNames[i]);
         }
+
         wrbuf_printf(wr, " ");
         
-        if (bsrr->errcode){
+        if (bsrr->errcode)
             wr_diag(wr, bsrr->errcode, bsrr->errstring);
-            wrbuf_printf(wr, " ");
-        }
         else
-            wrbuf_printf(wr, "OK "); 
-        /* else if (*res->scanStatus == Z_Scan_success) */
-        /*    wrbuf_printf(wr, "OK "); */
-        /* else */
-        /* wrbuf_printf(wr, "Partial "); */
-
-        if (*res->numberOfEntriesReturned)
-            wrbuf_printf(wr, "%d - ", *res->numberOfEntriesReturned);
-        else
-            wrbuf_printf(wr, "0 - ");
+            wrbuf_printf(wr, "OK"); 
 
-        wrbuf_printf(wr, "%d+%d+%d ",
+        wrbuf_printf(wr, " %d - %d+%d+%d",
+                     res->numberOfEntriesReturned ?
+                     *res->numberOfEntriesReturned : 0,
                      (req->preferredPositionInResponse ?
                       *req->preferredPositionInResponse : 1),
                      *req->numberOfTermsRequested,
                      (res->stepSize ? *res->stepSize : 1));
+        
+        if (bsrr->setname)
+            wrbuf_printf(wr, "+%s", bsrr->setname);
 
+        wrbuf_printf(wr, " ");
         yaz_scan_to_wrbuf(wr, req->termListAndStartPoint, 
                           bsrr->attributeset);
-        yaz_log(log_request, "%s", wrbuf_buf(wr) );
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s", wrbuf_cstr(wr) );
+        wrbuf_destroy(wr);
     }
     return apdu;
 }
@@ -3264,8 +3236,8 @@ static Z_APDU *process_sortRequest(association *assoc, request *reqb,
         }
         wrbuf_printf(wr, ")->%s ",req->sortedResultSetName);
 
-        yaz_log(log_request, "%s", wrbuf_buf(wr) );
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s", wrbuf_cstr(wr) );
+        wrbuf_destroy(wr);
     }
     return apdu;
 }
@@ -3348,8 +3320,8 @@ static Z_APDU *process_deleteRequest(association *assoc, request *reqb,
             wrbuf_printf(wr, "OK -");
         for (i = 0; i<req->num_resultSetList; i++)
             wrbuf_printf(wr, " %s ", req->resultSetList[i]);
-        yaz_log(log_request, "%s", wrbuf_buf(wr) );
-        wrbuf_free(wr, 1);
+        yaz_log(log_request, "%s", wrbuf_cstr(wr) );
+        wrbuf_destroy(wr);
     }
     return apdu;
 }
@@ -3535,16 +3507,19 @@ static Z_APDU *process_ESRequest(association *assoc, request *reqb, int *fd)
         {
             WRBUF wr = wrbuf_alloc();
             wrbuf_diags(wr, resp->num_diagnostics, resp->diagnostics);
-            yaz_log(log_request, "EsRequest %s", wrbuf_buf(wr) );
-            wrbuf_free(wr, 1);
+            yaz_log(log_request, "EsRequest %s", wrbuf_cstr(wr) );
+            wrbuf_destroy(wr);
         }
 
     }
     /* Do something with the members of bend_extendedservice */
     if (esrequest.taskPackage)
-        resp->taskPackage = z_ext_record (assoc->encode, VAL_EXTENDED,
-                                         (const char *)  esrequest.taskPackage,
-                                          -1);
+    {
+        resp->taskPackage = z_ext_record_oid(
+            assoc->encode, yaz_oid_recsyn_extended,
+            (const char *)  esrequest.taskPackage, -1
+            );
+    }
     yaz_log(YLOG_DEBUG,"Send the result apdu");
     return apdu;
 }