Character set negotiation updates
[yaz-moved-to-github.git] / server / seshigh.c
index 4af6e86..a9e17fa 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2002, Index Data
  * See the file LICENSE for details.
  *
- * $Id: seshigh.c,v 1.127 2002-03-05 12:45:49 mike Exp $
+ * $Id: seshigh.c,v 1.131 2002-07-25 12:52:54 adam Exp $
  */
 
 /*
@@ -46,6 +46,8 @@
 #include <yaz/logrpn.h>
 #include <yaz/statserv.h>
 #include <yaz/diagbib1.h>
+#include <yaz/charneg.h>
+#include <yaz/otherinfo.h>
 
 #include <yaz/backend.h>
 
@@ -167,6 +169,7 @@ void destroy_association(association *h)
     request_delq(&h->incoming);
     request_delq(&h->outgoing);
     xfree(h);
+    xmalloc_trav("session closed");
     if (control_block && control_block->one_shot)
        exit (0);
 }
@@ -357,6 +360,8 @@ void ir_session(IOCHAN h, int event)
                iochan_clearflag(h, EVENT_OUTPUT|EVENT_INPUT);
                iochan_setflag(h, assoc->cs_get_mask);
            }
+            else
+                assoc->cs_put_mask = EVENT_OUTPUT;
            break;
        default:
            if (conn->io_pending & CS_WANT_WRITE)
@@ -573,7 +578,8 @@ 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 options[100];
+
+    char options[140];
 
     xfree (assoc->init);
     assoc->init = (bend_initrequest *) xmalloc (sizeof(*assoc->init));
@@ -601,6 +607,17 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     assoc->init->bend_scan = NULL;
     assoc->init->bend_segment = NULL;
     assoc->init->bend_fetch = NULL;
+    assoc->init->charneg_request = NULL;
+    assoc->init->charneg_response = NULL;
+    assoc->init->decode = assoc->decode;
+
+    if (ODR_MASK_GET(req->options, Z_Options_negotiationModel))
+    {
+        Z_CharSetandLanguageNegotiation *negotiation =
+            yaz_get_charneg_record (req->otherInfo);
+        if (negotiation->which == Z_CharSetandLanguageNegotiation_proposal)
+            assoc->init->charneg_request = negotiation;
+    }
     
     assoc->init->peer_name =
        odr_strdup (assoc->encode, cs_addrstr(assoc->client_link));
@@ -664,13 +681,33 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     if (ODR_MASK_GET(req->options, Z_Options_concurrentOperations))
     {
        ODR_MASK_SET(resp->options, Z_Options_concurrentOperations);
-       strcat(options, " concurop");
+       strcat(options, " concurrop");
     }
     if (ODR_MASK_GET(req->options, Z_Options_sort) && assoc->init->bend_sort)
     {
        ODR_MASK_SET(resp->options, Z_Options_sort);
        strcat(options, " sort");
     }
+
+    if (ODR_MASK_GET(req->options, Z_Options_negotiationModel)
+        && assoc->init->charneg_response)
+    {
+       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);
+            
+            p0->which = Z_OtherInfo_externallyDefinedInfo;
+            p0->information.externallyDefinedInfo =
+                assoc->init->charneg_response;
+        }
+       ODR_MASK_SET(resp->options, Z_Options_negotiationModel);
+       strcat(options, " negotiation");
+    }
+
     if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
     {
        ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
@@ -686,6 +723,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
        ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3);
        assoc->version = 3;
     }
+
     yaz_log(LOG_LOG, "Negotiated to v%d: %s", assoc->version, options);
     assoc->maximumRecordSize = *req->maximumRecordSize;
     if (assoc->maximumRecordSize > control_block->maxrecordsize)
@@ -1023,6 +1061,7 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb,
        bsrr->errcode = 0;
        bsrr->hits = 0;
        bsrr->errstring = NULL;
+        bsrr->search_info = NULL;
        (assoc->init->bend_search)(assoc->backend, bsrr);
        if (!bsrr->request)
            return 0;
@@ -1133,6 +1172,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
            resp->presentStatus = 0;
        }
     }
+    resp->additionalSearchInfo = bsrt->search_info;
     return apdu;
 }
 
@@ -1565,15 +1605,15 @@ void *bend_request_getdata(bend_request r)
 
 static Z_APDU *process_segmentRequest (association *assoc, request *reqb)
 {
-    bend_segment_rr request;
+    bend_segment_rr req;
 
-    request.segment = reqb->apdu_request->u.segmentRequest;
-    request.stream = assoc->encode;
-    request.decode = assoc->decode;
-    request.print = assoc->print;
-    request.association = assoc;
+    req.segment = reqb->apdu_request->u.segmentRequest;
+    req.stream = assoc->encode;
+    req.decode = assoc->decode;
+    req.print = assoc->print;
+    req.association = assoc;
     
-    (*assoc->init->bend_segment)(assoc->backend, &request);
+    (*assoc->init->bend_segment)(assoc->backend, &req);
 
     return 0;
 }