Add Zthes tag-set -- where was it?!
[yaz-moved-to-github.git] / server / seshigh.c
index d7e34a0..90b1a70 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2002, Index Data
  * See the file LICENSE for details.
  *
- * $Id: seshigh.c,v 1.125 2002-01-23 21:13:30 adam Exp $
+ * $Id: seshigh.c,v 1.132 2002-09-25 12:37:07 adam Exp $
  */
 
 /*
@@ -45,6 +45,9 @@
 #include <yaz/log.h>
 #include <yaz/logrpn.h>
 #include <yaz/statserv.h>
+#include <yaz/diagbib1.h>
+#include <yaz/charneg.h>
+#include <yaz/otherinfo.h>
 
 #include <yaz/backend.h>
 
@@ -104,7 +107,11 @@ association *create_association(IOCHAN channel, COMSTACK link)
        strcpy(filename, control_block->apdufile);
        if (!(anew->print = odr_createmem(ODR_PRINT)))
            return 0;
-       if (*control_block->apdufile != '-')
+       if (*control_block->apdufile == '@')
+        {
+           odr_setprint(anew->print, yaz_log_file());
+       }       
+       else if (*control_block->apdufile != '-')
        {
            strcpy(filename, control_block->apdufile);
            if (!control_block->dynamic)
@@ -166,6 +173,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);
 }
@@ -356,6 +364,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)
@@ -572,7 +582,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));
@@ -590,6 +601,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     assoc->init->auth = req->idAuthentication;
     assoc->init->referenceId = req->referenceId;
     assoc->init->implementation_version = 0;
+    assoc->init->implementation_id = 0;
     assoc->init->implementation_name = 0;
     assoc->init->bend_sort = NULL;
     assoc->init->bend_search = NULL;
@@ -599,6 +611,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));
@@ -662,13 +685,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);
@@ -684,6 +727,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)
@@ -702,6 +746,16 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
 
     resp->implementationName = "GFS/YAZ";
 
+    if (assoc->init->implementation_id)
+    {
+       char *nv = (char *)
+           odr_malloc (assoc->encode,
+                       strlen(assoc->init->implementation_id) + 10 + 
+                              strlen(resp->implementationId));
+       sprintf (nv, "%s / %s",
+                resp->implementationId, assoc->init->implementation_id);
+        resp->implementationId = nv;
+    }
     if (assoc->init->implementation_name)
     {
        char *nv = (char *)
@@ -759,7 +813,7 @@ static Z_Records *diagrec(association *assoc, int error, char *addinfo)
        odr_malloc (assoc->encode, sizeof(*dr));
 
     yaz_log(LOG_LOG, "[%d] %s %s%s", error, diagbib1_str(error),
-        addinfo ? " -- " : "", addinfo ? addinfo : "", error);
+        addinfo ? " -- " : "", addinfo ? addinfo : "");
     rec->which = Z_Records_NSD;
     rec->u.nonSurrogateDiagnostic = dr;
     dr->diagnosticSetId =
@@ -936,7 +990,7 @@ static Z_Records *pack_records(association *a, char *setname, int start,
            }
            else /* too big entirely */
            {
-               yaz_log(LOG_DEBUG, "Record > maxrcdsz");
+               yaz_log(LOG_LOG, "Record > maxrcdsz this=%d max=%d", this_length, a->maximumRecordSize);
                reclist->records[reclist->num_records] =
                    surrogatediagrec(a, freq.basename, 17, 0);
                reclist->num_records++;
@@ -1011,6 +1065,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;
@@ -1121,6 +1176,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb,
            resp->presentStatus = 0;
        }
     }
+    resp->additionalSearchInfo = bsrt->search_info;
     return apdu;
 }
 
@@ -1225,7 +1281,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 *attent;
     oident *attset;
     bend_scan_rr *bsrr = (bend_scan_rr *)
         odr_malloc (assoc->encode, sizeof(*bsrr));
@@ -1554,15 +1609,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;
 }