Option logapdu renamed apdulog as it harmonizes more with pazpar2
[yaz-moved-to-github.git] / src / zoom-c.c
index b59c14a..bea723f 100644 (file)
@@ -596,6 +596,13 @@ ZOOM_API(void)
         ZOOM_options_get_int(c->options, "preferredMessageSize", 1024*1024);
 
     c->async = ZOOM_options_get_bool(c->options, "async", 0);
+    if (ZOOM_options_get_bool(c->options, "apdulog", 0))
+    {
+        c->odr_print = odr_createmem(ODR_PRINT);
+        odr_setprint(c->odr_print, yaz_log_file());
+    }
+    else
+        c->odr_print = 0;
     yaz_log(log_details, "%p ZOOM_connection_connect async=%d", c, c->async);
  
     task = ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT);
@@ -774,6 +781,11 @@ ZOOM_API(void)
     xfree(c->diagset);
     odr_destroy(c->odr_in);
     odr_destroy(c->odr_out);
+    if (c->odr_print)
+    {
+        odr_setprint(c->odr_print, 0); /* prevent destroy from fclose'ing */
+        odr_destroy(c->odr_print);
+    }
     ZOOM_options_destroy(c->options);
     ZOOM_connection_remove_tasks(c);
     ZOOM_connection_remove_events(c);
@@ -1301,6 +1313,8 @@ static int encode_APDU(ZOOM_connection c, Z_APDU *a, ODR out)
         odr_reset(out);
         return -1;
     }
+    if (c->odr_print)
+        z_APDU(c->odr_print, &a, 0, 0);
     yaz_log(log_details, "%p encoding_APDU encoding OK", c);
     return 0;
 }
@@ -1429,6 +1443,8 @@ static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr)
     }
     if (!z_GDU(c->odr_out, &gdu, 0, 0))
         return zoom_complete;
+    if (c->odr_print)
+        z_GDU(c->odr_print, &gdu, 0, 0);
     c->buf_out = odr_getbuf(c->odr_out, &c->len_out, 0);
         
     event = ZOOM_Event_create(ZOOM_EVENT_SEND_APDU);
@@ -2636,8 +2652,12 @@ static zoom_ret send_present(ZOOM_connection c)
         yaz_log(log_details, "%p send_present skip=%d", c, i);
 
     *req->resultSetStartPoint = *start + 1;
-    *req->numberOfRecordsRequested = resultset->step>0 ?
-        resultset->step : *count;
+
+    if (resultset->step > 0 && resultset->step < *count)
+        *req->numberOfRecordsRequested = resultset->step;
+    else
+        *req->numberOfRecordsRequested = *count;
+    
     if (*req->numberOfRecordsRequested + *start > resultset->size)
         *req->numberOfRecordsRequested = resultset->size - *start;
     assert(*req->numberOfRecordsRequested > 0);
@@ -3269,6 +3289,9 @@ static Z_APDU *create_update_package(ZOOM_package p)
     int record_len;
     const char *record_buf = ZOOM_options_getl(p->options, "record",
         &record_len);
+    int recordOpaque_len;
+    const char *recordOpaque_buf = ZOOM_options_getl(p->options, "recordOpaque",
+        &recordOpaque_len);
     const char *syntax_str = ZOOM_options_get(p->options, "syntax");
     const char *version = ZOOM_options_get(p->options, "updateVersion");
 
@@ -3284,7 +3307,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
         version = "3";
     if (!syntax_str)
         syntax_str = "xml";
-    if (!record_buf)
+    if (!record_buf && !recordOpaque_buf)
     {
         record_buf = "void";
         record_len = 4;
@@ -3409,9 +3432,18 @@ static Z_APDU *create_update_package(ZOOM_package p)
         }
         else
             notToKeep->elements[0]->correlationInfo = 0;
-        notToKeep->elements[0]->record =
-            z_ext_record_oid(p->odr_out, syntax_oid,
-                             record_buf, record_len);
+        if (recordOpaque_buf)
+        {
+            notToKeep->elements[0]->record =
+                z_ext_record_oid_any(p->odr_out, syntax_oid,
+                                 recordOpaque_buf, recordOpaque_len);
+        }
+        else
+        {
+            notToKeep->elements[0]->record =
+                z_ext_record_oid(p->odr_out, syntax_oid,
+                                 record_buf, record_len);
+        }
     }
     if (0 && apdu)
     {
@@ -3640,22 +3672,90 @@ static zoom_ret send_sort_present(ZOOM_connection c)
     return r;
 }
 
+static int es_response_taskpackage_update(ZOOM_connection c,
+               Z_IUUpdateTaskPackage *utp)
+{
+       if (utp && utp->targetPart)
+       {
+               Z_IUTargetPart *targetPart = utp->targetPart;
+               switch ( *targetPart->updateStatus ) {
+                       case Z_IUTargetPart_success:
+                               ZOOM_options_set(c->tasks->u.package->options,"updateStatus", "success");
+                               break;
+                       case Z_IUTargetPart_partial:
+                               ZOOM_options_set(c->tasks->u.package->options,"updateStatus", "partial");
+                               break;
+                       case Z_IUTargetPart_failure:
+                               ZOOM_options_set(c->tasks->u.package->options,"updateStatus", "failure");
+                               if (targetPart->globalDiagnostics && targetPart->num_globalDiagnostics > 0)
+                                       response_diag(c, targetPart->globalDiagnostics[0]);
+                               break;
+               }
+               // NOTE: Individual record status, surrogate diagnostics, and supplemental diagnostics ARE NOT REPORTED.
+       }
+    return 1;
+}
+
+static int es_response_taskpackage(ZOOM_connection c,
+                                   Z_TaskPackage *taskPackage)
+{
+       // targetReference
+       Odr_oct *id = taskPackage->targetReference;
+       if (id)
+               ZOOM_options_setl(c->tasks->u.package->options,
+                                                       "targetReference", (char*) id->buf, id->len);
+       
+       // taskStatus
+       switch ( *taskPackage->taskStatus ) {
+               case Z_TaskPackage_pending:
+                       ZOOM_options_set(c->tasks->u.package->options,"taskStatus", "pending");
+                       break;
+               case Z_TaskPackage_active:
+                       ZOOM_options_set(c->tasks->u.package->options,"taskStatus", "active");
+                       break;
+               case Z_TaskPackage_complete:
+                       ZOOM_options_set(c->tasks->u.package->options,"taskStatus", "complete");
+                       break;
+               case Z_TaskPackage_aborted:
+                       ZOOM_options_set(c->tasks->u.package->options,"taskStatus", "aborted");
+                       if ( taskPackage->num_packageDiagnostics && taskPackage->packageDiagnostics )
+                               response_diag(c, taskPackage->packageDiagnostics[0]);
+                       break;
+       }
+       
+       // taskSpecificParameters
+       // NOTE: Only Update implemented, no others.
+       if ( taskPackage->taskSpecificParameters->which == Z_External_update ) {
+                       Z_IUUpdateTaskPackage *utp = taskPackage->taskSpecificParameters->u.update->u.taskPackage;
+                       es_response_taskpackage_update(c, utp);
+       }
+       return 1;
+}
+
+
 static int es_response(ZOOM_connection c,
                        Z_ExtendedServicesResponse *res)
 {
     if (!c->tasks || c->tasks->which != ZOOM_TASK_PACKAGE)
         return 0;
-    if (res->diagnostics && res->num_diagnostics > 0)
-        response_diag(c, res->diagnostics[0]);
+    switch (*res->operationStatus) {
+        case Z_ExtendedServicesResponse_done:
+            ZOOM_options_set(c->tasks->u.package->options,"operationStatus", "done");
+            break;
+        case Z_ExtendedServicesResponse_accepted:
+            ZOOM_options_set(c->tasks->u.package->options,"operationStatus", "accepted");
+            break;
+        case Z_ExtendedServicesResponse_failure:
+            ZOOM_options_set(c->tasks->u.package->options,"operationStatus", "failure");
+            if (res->diagnostics && res->num_diagnostics > 0)
+                response_diag(c, res->diagnostics[0]);
+            break;
+    }
     if (res->taskPackage &&
         res->taskPackage->which == Z_External_extendedService)
     {
         Z_TaskPackage *taskPackage = res->taskPackage->u.extendedService;
-        Odr_oct *id = taskPackage->targetReference;
-        
-        if (id)
-            ZOOM_options_setl(c->tasks->u.package->options,
-                              "targetReference", (char*) id->buf, id->len);
+        es_response_taskpackage(c, taskPackage);
     }
     if (res->taskPackage && 
         res->taskPackage->which == Z_External_octet)
@@ -4083,16 +4183,21 @@ static int do_read(ZOOM_connection c)
             }
             do_close(c);
         }
-        else if (gdu->which == Z_GDU_Z3950)
-            recv_apdu(c, gdu->u.z3950);
-        else if (gdu->which == Z_GDU_HTTP_Response)
+        else
         {
+            if (c->odr_print)
+                z_GDU(c->odr_print, &gdu, 0, 0);
+            if (gdu->which == Z_GDU_Z3950)
+                recv_apdu(c, gdu->u.z3950);
+            else if (gdu->which == Z_GDU_HTTP_Response)
+            {
 #if YAZ_HAVE_XML2
-            handle_http(c, gdu->u.HTTP_Response);
+                handle_http(c, gdu->u.HTTP_Response);
 #else
-            set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0);
-            do_close(c);
+                set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0);
+                do_close(c);
 #endif
+            }
         }
         c->reconnect_ok = 0;
     }