COmment.
[yaz-moved-to-github.git] / src / zoom-c.c
index 57ff141..3ada8d1 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.132 2007-05-31 07:38:14 adam Exp $
+ * $Id: zoom-c.c,v 1.140 2007-08-15 17:53:11 mike Exp $
  */
 /**
  * \file zoom-c.c
@@ -28,6 +28,7 @@
 #include <yaz/ccl.h>
 #include <yaz/query-charset.h>
 #include <yaz/copy_types.h>
+#include <yaz/snprintf.h>
 
 static int log_api = 0;
 static int log_details = 0;
@@ -1341,7 +1342,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
                     odr_prepend(c->odr_out, "ZOOM-C",
                                 ireq->implementationName));
     
-    version = odr_strdup(c->odr_out, "$Revision: 1.132 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.140 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
@@ -1666,9 +1667,11 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c)
 
 static void response_default_diag(ZOOM_connection c, Z_DefaultDiagFormat *r)
 {
-    oid_class oclass;
+    char oid_name_buf[OID_STR_MAX];
+    const char *oid_name;
     char *addinfo = 0;
 
+    oid_name = yaz_oid_to_string_buf(r->diagnosticSetId, 0, oid_name_buf);
     switch (r->which)
     {
     case Z_DefaultDiagFormat_v2Addinfo:
@@ -1680,10 +1683,7 @@ static void response_default_diag(ZOOM_connection c, Z_DefaultDiagFormat *r)
     }
     xfree(c->addinfo);
     c->addinfo = 0;
-    set_dset_error(c, *r->condition,
-                   yaz_oid_to_string(yaz_oid_std(), 
-                                     r->diagnosticSetId, &oclass),
-                   addinfo, 0);
+    set_dset_error(c, *r->condition, oid_name, addinfo, 0);
 }
 
 static void response_diag(ZOOM_connection c, Z_DiagRec *p)
@@ -2691,6 +2691,19 @@ ZOOM_API(ZOOM_scanset)
     {
         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;
@@ -2893,8 +2906,6 @@ static Z_APDU *create_es_package(ZOOM_package p, const Odr_oid *oid)
     Z_APDU *apdu = zget_APDU(p->odr_out, Z_APDU_extendedServicesRequest);
     Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
     
-    *req->function = Z_ExtendedServicesRequest_create;
-    
     str = ZOOM_options_get(p->options, "package-name");
     if (str && *str)
         req->packageName = odr_strdup(p->odr_out, str);
@@ -2909,11 +2920,24 @@ static Z_APDU *create_es_package(ZOOM_package p, const Odr_oid *oid)
     if (str)
     {
         if (!strcmp (str, "create"))
-            *req->function = 1;
+            *req->function = Z_ExtendedServicesRequest_create;
         if (!strcmp (str, "delete"))
-            *req->function = 2;
+            *req->function = Z_ExtendedServicesRequest_delete;
         if (!strcmp (str, "modify"))
-            *req->function = 3;
+            *req->function = Z_ExtendedServicesRequest_modify;
+    }
+
+    str = ZOOM_options_get(p->options, "waitAction");
+    if (str)
+    {
+        if (!strcmp (str, "wait"))
+            *req->waitAction = Z_ExtendedServicesRequest_wait;
+        if (!strcmp (str, "waitIfPossible"))
+            *req->waitAction = Z_ExtendedServicesRequest_waitIfPossible;
+        if (!strcmp (str, "dontWait"))
+            *req->waitAction = Z_ExtendedServicesRequest_dontWait;
+        if (!strcmp (str, "dontReturnPackage"))
+            *req->waitAction = Z_ExtendedServicesRequest_dontReturnPackage;
     }
     return apdu;
 }
@@ -3114,6 +3138,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
     const char *recordIdNumber = ZOOM_options_get(p->options, "recordIdNumber");
     const char *record_buf = ZOOM_options_get(p->options, "record");
     const char *syntax_str = ZOOM_options_get(p->options, "syntax");
+    const char *version = ZOOM_options_get(p->options, "updateVersion");
 
     const char *correlationInfo_note =
         ZOOM_options_get(p->options, "correlationInfo.note");
@@ -3121,7 +3146,10 @@ static Z_APDU *create_update_package(ZOOM_package p)
         ZOOM_options_get(p->options, "correlationInfo.id");
     int action_no = -1;
     Odr_oid *syntax_oid = 0;
+    const Odr_oid *package_oid = yaz_oid_extserv_database_update;
 
+    if (!version)
+        version = "3";
     if (!syntax_str)
         syntax_str = "xml";
     if (!record_buf)
@@ -3142,8 +3170,27 @@ static Z_APDU *create_update_package(ZOOM_package p)
     if (num_db > 0)
         first_db = db[0];
     
-    if (!action)
-        action = "specialUpdate";
+    switch(*version)
+    {
+    case '1':
+        package_oid = yaz_oid_extserv_database_update_first_version;
+        /* old update does not support specialUpdate */
+        if (!action)
+            action = "recordInsert";
+        break;
+    case '2':
+        if (!action)
+            action = "specialUpdate";
+        package_oid = yaz_oid_extserv_database_update_second_version;
+        break;
+    case '3':
+        if (!action)
+            action = "specialUpdate";
+        package_oid = yaz_oid_extserv_database_update;
+        break;
+    default:
+        return 0;
+    }
     
     if (!strcmp(action, "recordInsert"))
         action_no = Z_IUOriginPartToKeep_recordInsert;
@@ -3158,19 +3205,19 @@ static Z_APDU *create_update_package(ZOOM_package p)
     else
         return 0;
 
-    apdu = create_es_package(p, yaz_oid_extserv_database_update);
+    apdu = create_es_package(p, package_oid);
     if (apdu)
     {
         Z_IUOriginPartToKeep *toKeep;
         Z_IUSuppliedRecords *notToKeep;
         Z_External *r = (Z_External *)
             odr_malloc(p->odr_out, sizeof(*r));
+        const char *elementSetName =
+            ZOOM_options_get(p->options, "elementSetName");
         
         apdu->u.extendedServicesRequest->taskSpecificParameters = r;
-
         
-        r->direct_reference = odr_oiddup(p->odr_out, 
-                                         yaz_oid_extserv_database_update);
+        r->direct_reference = odr_oiddup(p->odr_out, package_oid);
         r->descriptor = 0;
         r->which = Z_External_update;
         r->indirect_reference = 0;
@@ -3186,7 +3233,11 @@ static Z_APDU *create_update_package(ZOOM_package p)
         
         toKeep->databaseName = odr_strdup(p->odr_out, first_db);
         toKeep->schema = 0;
+        
         toKeep->elementSetName = 0;
+        if (elementSetName)
+            toKeep->elementSetName = odr_strdup(p->odr_out, elementSetName);
+            
         toKeep->actionQualifier = 0;
         toKeep->action = odr_intdup(p->odr_out, action_no);
         
@@ -3519,7 +3570,7 @@ static void recv_apdu(ZOOM_connection c, Z_APDU *apdu)
     switch(apdu->which)
     {
     case Z_APDU_initResponse:
-        yaz_log(log_api, "%p recv_apd: Received Init response", c);
+        yaz_log(log_api, "%p recv_apdu: Received Init response", c);
         initrs = apdu->u.initResponse;
         ZOOM_connection_option_set(c, "serverImplementationId",
                                    initrs->implementationId ?
@@ -3837,11 +3888,19 @@ static int do_read(ZOOM_connection c)
         {
             int x;
             int err = odr_geterrorx(c->odr_in, &x);
-            char msg[60];
+            char msg[100];
             const char *element = odr_getelement(c->odr_in);
-            sprintf(msg, "ODR code %d:%d element=%-20s",
-                    err, x, element ? element : "<unknown>");
+            yaz_snprintf(msg, sizeof(msg),
+                    "ODR code %d:%d element=%s offset=%d",
+                    err, x, element ? element : "<unknown>",
+                    odr_offset(c->odr_in));
             set_ZOOM_error(c, ZOOM_ERROR_DECODE, msg);
+            if (log_api)
+            {
+                FILE *ber_file = yaz_log_file();
+                if (ber_file)
+                    odr_dumpBER(ber_file, c->buf_in, r);
+            }
             do_close(c);
         }
         else if (gdu->which == Z_GDU_Z3950)
@@ -4080,6 +4139,8 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask)
             if (c->cs->io_pending & CS_WANT_READ)
                 mask += ZOOM_SELECT_READ;
             ZOOM_connection_set_mask(c, mask);
+            event = ZOOM_Event_create(ZOOM_EVENT_NONE);
+            ZOOM_connection_put_event(c, event);
         }
         else if (ret == 0)
         {