Better support for extra data for SRU codecs and GFS
[yaz-moved-to-github.git] / src / seshigh.c
index 9c791d1..b0349e7 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2008 Index Data
+ * Copyright (C) 1995-2009 Index Data
  * See the file LICENSE for details.
  */
 /**
@@ -377,7 +377,7 @@ void ir_session(IOCHAN h, int event)
     {
         if (assoc->state != ASSOC_UP)
         {
-            yaz_log(YLOG_DEBUG, "Final timeout - closing connection.");
+            yaz_log(log_session, "Timeout. Closing connection");
             /* do we need to lod this at all */
             cs_close(conn);
             destroy_association(assoc);
@@ -385,8 +385,7 @@ void ir_session(IOCHAN h, int event)
         }
         else
         {
-            yaz_log(log_sessiondetail, 
-                    "Session idle too long. Sending close.");
+            yaz_log(log_sessiondetail, "Timeout. Sending Z39.50 Close");
             do_close(assoc, Z_Close_lackOfActivity, 0);
         }
         return;
@@ -509,6 +508,7 @@ static void assoc_init_reset(association *assoc)
     assoc->init->bend_explain = NULL;
     assoc->init->bend_srw_scan = NULL;
     assoc->init->bend_srw_update = NULL;
+    assoc->init->named_result_sets = 0;
 
     assoc->init->charneg_request = NULL;
     assoc->init->charneg_response = NULL;
@@ -664,7 +664,6 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr)
         rr->output_format = match_syntax;
     if (match_schema)
         rr->schema = odr_strdup(rr->stream, match_schema);
-    return 0;
 #else
     (*assoc->init->bend_fetch)(assoc->backend, rr);
 #endif
@@ -848,9 +847,10 @@ static int ccl2pqf(ODR odr, const Odr_oct *ccl, CCL_bibset bibset,
 
 static void srw_bend_search(association *assoc, request *req,
                             Z_SRW_PDU *sr,
-                            Z_SRW_searchRetrieveResponse *srw_res,
+                            Z_SRW_PDU *res,
                             int *http_code)
 {
+    Z_SRW_searchRetrieveResponse *srw_res = res->u.response;
     int srw_error = 0;
     Z_External *ext;
     Z_SRW_searchRetrieveRequest *srw_req = sr->u.request;
@@ -873,6 +873,8 @@ static void srw_bend_search(association *assoc, request *req,
         rr.partial_resultset = 0;
         rr.query = (Z_Query *) odr_malloc(assoc->decode, sizeof(*rr.query));
         rr.query->u.type_1 = 0;
+        rr.extra_args = sr->extra_args;
+        rr.extra_response_data = 0;
         
         if (srw_req->query_type == Z_SRW_query_type_cql)
         {
@@ -972,7 +974,8 @@ static void srw_bend_search(association *assoc, request *req,
                 int number = srw_req->maximumRecords ? *srw_req->maximumRecords : 0;
                 int start = srw_req->startRecord ? *srw_req->startRecord : 1;
                 
-                yaz_log(log_requestdetail, "Request to pack %d+%d out of %d",
+                yaz_log(log_requestdetail, "Request to pack %d+%d out of "
+                        ODR_INT_PRINTF,
                         start, number, rr.hits);
                 
                 srw_res->numberOfRecords = odr_intdup(assoc->encode, rr.hits);
@@ -1093,6 +1096,11 @@ static void srw_bend_search(association *assoc, request *req,
                             srw_res->records = 0;
                     }
                 }
+                if (rr.extra_response_data)
+                {
+                    res->extraResponseData_buf = rr.extra_response_data;
+                    res->extraResponseData_len = strlen(rr.extra_response_data);
+                }
                 if (rr.estimated_hit_count || rr.partial_resultset)
                 {
                     yaz_add_srw_diagnostic(
@@ -1129,11 +1137,11 @@ static void srw_bend_search(association *assoc, request *req,
             wrbuf_printf(wr, "ERROR info:http/%d", *http_code);
         else if (srw_res->numberOfRecords)
         {
-            wrbuf_printf(wr, "OK %d",
+            wrbuf_printf(wr, "OK " ODR_INT_PRINTF,
                          (srw_res->numberOfRecords ?
                           *srw_res->numberOfRecords : 0));
         }
-        wrbuf_printf(wr, " %s %d+%d", 
+        wrbuf_printf(wr, " %s " ODR_INT_PRINTF " +%d", 
                      (srw_res->resultSetId ?
                       srw_res->resultSetId : "-"),
                      (srw_req->startRecord ? *srw_req->startRecord : 1), 
@@ -1401,7 +1409,7 @@ static void srw_bend_scan(association *assoc, request *req,
         else
             wrbuf_printf(wr, "OK - - ");
 
-        wrbuf_printf(wr, "%d+%d+0 ",
+        wrbuf_printf(wr, ODR_INT_PRINTF "+" ODR_INT_PRINTF " ",
                      (srw_req->responsePosition ? 
                       *srw_req->responsePosition : 1),
                      (srw_req->maximumTerms ?
@@ -1657,7 +1665,7 @@ static int check_path(const char *path)
     return 1;
 }
 
-static char *read_file(const char *fname, ODR o, int *sz)
+static char *read_file(const char *fname, ODR o, size_t *sz)
 {
     char *buf;
     FILE *inf = fopen(fname, "rb");
@@ -1690,6 +1698,7 @@ static void process_http_request(association *assoc, request *req)
     int num_diagnostic = 0;
     const char *host = z_HTTP_header_lookup(hreq->headers, "Host");
 
+    yaz_log(log_request, "%s %s HTTP/%s", hreq->method, hreq->path, hreq->version);
     if (!control_association(assoc, host, 0))
     {
         p = z_get_HTTP_Response(o, 404);
@@ -1710,7 +1719,7 @@ static void process_http_request(association *assoc, request *req)
         }
         else
         {
-            int content_size = 0;
+            size_t content_size = 0;
             char *content_buf = read_file(hreq->path+1, o, &content_size);
             if (!content_buf)
             {
@@ -1782,8 +1791,7 @@ static void process_http_request(association *assoc, request *req)
             }
             else
             {
-                srw_bend_search(assoc, req, sr, res->u.response, 
-                                &http_code);
+                srw_bend_search(assoc, req, sr, res, &http_code);
             }
             if (http_code == 200)
                 soap_package->u.generic->p = res;
@@ -2164,7 +2172,6 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     Z_APDU *apdu = zget_APDU(assoc->encode, Z_APDU_initResponse);
     Z_InitResponse *resp = apdu->u.initResponse;
     bend_initresult *binitres;
-    char *version;
     char options[140];
     statserv_options_block *cb = 0;  /* by default no control for backend */
 
@@ -2199,6 +2206,10 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
             assoc->init->charneg_request = negotiation;
     }
 
+    /* by default named_result_sets is 0 .. Enable it if client asks for it. */
+    if (ODR_MASK_GET(req->options, Z_Options_namedResultSets))
+        assoc->init->named_result_sets = 1;
+
     assoc->backend = 0;
     if (cb)
     {
@@ -2265,7 +2276,8 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
         ODR_MASK_SET(resp->options, Z_Options_extendedServices);
         strcat(options, " extendedServices");
     }
-    if (ODR_MASK_GET(req->options, Z_Options_namedResultSets))
+    if (ODR_MASK_GET(req->options, Z_Options_namedResultSets)
+        && assoc->init->named_result_sets)
     {
         ODR_MASK_SET(resp->options, Z_Options_namedResultSets);
         strcat(options, " namedresults");
@@ -2351,14 +2363,6 @@ 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.128 $");
-    if (strlen(version) > 10)   /* check for unexpanded CVS strings */
-        version[strlen(version)-2] = '\0';
-    resp->implementationVersion = odr_prepend(assoc->encode,
-                assoc->init->implementation_version,
-                odr_prepend(assoc->encode, &version[11],
-                            resp->implementationVersion));
-
     if (binitres->errcode)
     {
         assoc->state = ASSOC_DEAD;
@@ -2367,6 +2371,9 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
                              binitres->errstring);
         *resp->result = 0;
     }
+    else
+        assoc->state = ASSOC_UP;
+    
     if (log_request)
     {
         if (!req->idAuthentication)
@@ -2461,9 +2468,9 @@ static Z_NamePlusRecord *surrogatediagrec(association *assoc,
     return zget_surrogateDiagRec(assoc->encode, dbname, error, addinfo);
 }
 
-static Z_Records *pack_records(association *a, char *setname, int start,
-                               int *num, Z_RecordComposition *comp,
-                               int *next, int *pres,
+static Z_Records *pack_records(association *a, char *setname, Odr_int start,
+                               Odr_int *num, Z_RecordComposition *comp,
+                               Odr_int *next, Odr_int *pres,
                                Z_ReferenceId *referenceId,
                                Odr_oid *oid, int *errcode)
 {
@@ -2483,8 +2490,9 @@ static Z_Records *pack_records(association *a, char *setname, int start,
     *num = 0;
     *next = 0;
 
-    yaz_log(log_requestdetail, "Request to pack %d+%d %s", start, toget, setname);
-    yaz_log(log_requestdetail, "pms=%d, mrs=%d", a->preferredMessageSize,
+    yaz_log(log_requestdetail, "Request to pack " ODR_INT_PRINTF "+%d %s", start, toget, setname);
+    yaz_log(log_requestdetail, "pms=" ODR_INT_PRINTF
+            ", mrs=" ODR_INT_PRINTF, a->preferredMessageSize,
         a->maximumRecordSize);
     for (recno = start; reclist->num_records < toget; recno++)
     {
@@ -2579,7 +2587,8 @@ static Z_Records *pack_records(association *a, char *setname, int start,
             }
             else /* too big entirely */
             {
-                yaz_log(log_requestdetail, "Record > maxrcdsz this=%d max=%d",
+                yaz_log(log_requestdetail, "Record > maxrcdsz "
+                        "this=%d max=" ODR_INT_PRINTF,
                         this_length, a->maximumRecordSize);
                 reclist->records[reclist->num_records] =
                     surrogatediagrec(a, freq.basename, 17, 0);
@@ -2626,6 +2635,8 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb,
     bsrr->srw_setnameIdleTime = 0;
     bsrr->estimated_hit_count = 0;
     bsrr->partial_resultset = 0;
+    bsrr->extra_args = 0;
+    bsrr->extra_response_data = 0;
 
     yaz_log (log_requestdetail, "ResultSet '%s'", req->resultSetName);
     if (req->databaseNames)
@@ -2705,9 +2716,9 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
     Z_APDU *apdu = (Z_APDU *)odr_malloc(assoc->encode, sizeof(*apdu));
     Z_SearchResponse *resp = (Z_SearchResponse *)
         odr_malloc(assoc->encode, sizeof(*resp));
-    int *nulint = odr_intdup(assoc->encode, 0);
-    int *next = odr_intdup(assoc->encode, 0);
-    int *none = odr_intdup(assoc->encode, Z_SearchResponse_none);
+    Odr_int *nulint = odr_intdup(assoc->encode, 0);
+    Odr_int *next = odr_intdup(assoc->encode, 0);
+    Odr_int *none = odr_intdup(assoc->encode, Z_SearchResponse_none);
     int returnedrecs = 0;
 
     apdu->which = Z_APDU_searchResponse;
@@ -2727,17 +2738,17 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
         resp->resultCount = nulint;
         resp->numberOfRecordsReturned = nulint;
         resp->nextResultSetPosition = nulint;
-        resp->searchStatus = nulint;
+        resp->searchStatus = odr_booldup(assoc->encode, 0);
         resp->resultSetStatus = none;
         resp->presentStatus = 0;
     }
     else
     {
-        bool_t *sr = odr_intdup(assoc->encode, 1);
-        int *toget = odr_intdup(assoc->encode, 0);
+        bool_t *sr = odr_booldup(assoc->encode, 1);
+        Odr_int *toget = odr_intdup(assoc->encode, 0);
         Z_RecordComposition comp, *compp = 0;
 
-        yaz_log(log_requestdetail, "resultCount: %d", bsrt->hits);
+        yaz_log(log_requestdetail, "resultCount: " ODR_INT_PRINTF, bsrt->hits);
 
         resp->records = 0;
         resp->resultCount = &bsrt->hits;
@@ -2763,7 +2774,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
 
         if (*toget && !resp->records)
         {
-            int *presst = odr_intdup(assoc->encode, 0);
+            Odr_int *presst = odr_intdup(assoc->encode, 0);
             /* Call bend_present if defined */
             if (assoc->init->bend_present)
             {
@@ -2841,7 +2852,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
         if (bsrt->errcode)
             wrbuf_printf(wr, "ERROR %d", bsrt->errcode);
         else
-            wrbuf_printf(wr, "OK %d", bsrt->hits);
+            wrbuf_printf(wr, "OK " ODR_INT_PRINTF, bsrt->hits);
         wrbuf_printf(wr, " %s 1+%d ",
                      req->resultSetName, returnedrecs);
         yaz_query_to_wrbuf(wr, req->query);
@@ -2873,8 +2884,8 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
     Z_PresentRequest *req = reqb->apdu_request->u.presentRequest;
     Z_APDU *apdu;
     Z_PresentResponse *resp;
-    int *next;
-    int *num;
+    Odr_int *next;
+    Odr_int *num;
     int errcode = 0;
     const char *errstring = 0;
 
@@ -2940,9 +2951,10 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb,
         else if (*resp->presentStatus == Z_PresentStatus_success)
             wrbuf_printf(wr, "OK -  ");
         else
-            wrbuf_printf(wr, "Partial %d - ", *resp->presentStatus);
+            wrbuf_printf(wr, "Partial " ODR_INT_PRINTF " - ",
+                         *resp->presentStatus);
 
-        wrbuf_printf(wr, " %s %d+%d ",
+        wrbuf_printf(wr, " %s " ODR_INT_PRINTF "+" ODR_INT_PRINTF " ",
                 req->resultSetId, *req->resultSetStartPoint,
                 *req->numberOfRecordsRequested);
         yaz_log(log_request, "%s", wrbuf_cstr(wr) );
@@ -2966,8 +2978,8 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
     Z_APDU *apdu = (Z_APDU *)odr_malloc(assoc->encode, sizeof(*apdu));
     Z_ScanResponse *res = (Z_ScanResponse *)
         odr_malloc(assoc->encode, sizeof(*res));
-    int *scanStatus = odr_intdup(assoc->encode, Z_Scan_failure);
-    int *numberOfEntriesReturned = odr_intdup(assoc->encode, 0);
+    Odr_int *scanStatus = odr_intdup(assoc->encode, Z_Scan_failure);
+    Odr_int *numberOfEntriesReturned = odr_intdup(assoc->encode, 0);
     Z_ListEntries *ents = (Z_ListEntries *)
         odr_malloc(assoc->encode, sizeof(*ents));
     Z_DiagRecs *diagrecs_p = NULL;
@@ -3065,7 +3077,8 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
             *scanStatus = Z_Scan_success;
         ents->entries = tab;
         ents->num_entries = bsrr->num_entries;
-        res->numberOfEntriesReturned = &ents->num_entries;          
+        res->numberOfEntriesReturned = odr_intdup(assoc->encode, 
+                                                   ents->num_entries);
         res->positionOfTerm = &bsrr->term_position;
         for (i = 0; i < bsrr->num_entries; i++)
         {
@@ -3104,7 +3117,7 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
                     odr_malloc(assoc->encode, o->len = o->size =
                                strlen(bsrr->entries[i].term));
                 memcpy(o->buf, bsrr->entries[i].term, o->len);
-                yaz_log(YLOG_DEBUG, "  term #%d: '%s' (%d)", i,
+                yaz_log(YLOG_DEBUG, "  term #%d: '%s' (" ODR_INT_PRINTF ")", i,
                          bsrr->entries[i].term, bsrr->entries[i].occurrences);
             }
             else
@@ -3143,7 +3156,8 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb, int *fd)
         else
             wrbuf_printf(wr, "OK"); 
 
-        wrbuf_printf(wr, " %d - %d+%d+%d",
+        wrbuf_printf(wr, " " ODR_INT_PRINTF " - " ODR_INT_PRINTF "+" 
+                     ODR_INT_PRINTF "+" ODR_INT_PRINTF,
                      res->numberOfEntriesReturned ?
                      *res->numberOfEntriesReturned : 0,
                      (req->preferredPositionInResponse ?
@@ -3266,7 +3280,7 @@ static Z_APDU *process_deleteRequest(association *assoc, request *reqb,
     bdrr->statuses = 0;
     if (bdrr->num_setnames > 0)
     {
-        bdrr->statuses = (int*) 
+        bdrr->statuses = (Odr_int*) 
             odr_malloc(assoc->encode, sizeof(*bdrr->statuses) *
                        bdrr->num_setnames);
         for (i = 0; i < bdrr->num_setnames; i++)
@@ -3533,6 +3547,7 @@ int bend_assoc_is_alive(bend_association assoc)
 /*
  * Local variables:
  * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab