Add support for privately defined extended service, xml update, with
[yaz-moved-to-github.git] / src / zoom-c.c
index 5f0834a..d63ebe3 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.39 2005-05-02 19:33:00 adam Exp $
+ * $Id: zoom-c.c,v 1.42 2005-06-06 10:29:33 adam Exp $
  */
 /**
  * \file zoom-c.c
@@ -355,10 +355,7 @@ ZOOM_connection_connect(ZOOM_connection c,
     xfree (c->charset);
     val = ZOOM_options_get (c->options, "charset");
     if (val && *val)
-    {
        c->charset = xstrdup (val);
-       yaz_log(YLOG_LOG, "connect charset=%s", c->charset);
-    }
     else
        c->charset = 0;
 
@@ -1018,7 +1015,7 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c)
        ZOOM_options_get(c->options, "implementationName"),
        odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName));
 
-    version = odr_strdup(c->odr_out, "$Revision: 1.39 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.42 $");
     if (strlen(version) > 10)  /* check for unexpanded CVS strings */
        version[strlen(version)-2] = '\0';
     ireq->implementationVersion = odr_prepend(c->odr_out,
@@ -1389,20 +1386,11 @@ static zoom_ret ZOOM_connection_send_search (ZOOM_connection c)
     return send_APDU (c, apdu);
 }
 
-static void response_diag (ZOOM_connection c, Z_DiagRec *p)
+static void response_default_diag(ZOOM_connection c, Z_DefaultDiagFormat *r)
 {
     int oclass;
-    Z_DefaultDiagFormat *r;
     char *addinfo = 0;
-    
-    xfree (c->addinfo);
-    c->addinfo = 0;
-    if (p->which != Z_DiagRec_defaultFormat)
-    {
-        set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0);
-       return;
-    }
-    r = p->u.defaultFormat;
+
     switch (r->which)
     {
     case Z_DefaultDiagFormat_v2Addinfo:
@@ -1412,11 +1400,21 @@ static void response_diag (ZOOM_connection c, Z_DiagRec *p)
        addinfo = r->u.v3Addinfo;
        break;
     }
+    xfree (c->addinfo);
+    c->addinfo = 0;
     set_dset_error(c, *r->condition,
                    yaz_z3950oid_to_str(r->diagnosticSetId, &oclass),
                    addinfo, 0);
 }
 
+static void response_diag(ZOOM_connection c, Z_DiagRec *p)
+{
+    if (p->which != Z_DiagRec_defaultFormat)
+        set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0);
+    else
+       response_default_diag(c, p->u.defaultFormat);
+}
+
 ZOOM_API(ZOOM_record)
 ZOOM_record_clone (ZOOM_record srec)
 {
@@ -1943,13 +1941,7 @@ static void handle_records (ZOOM_connection c, Z_Records *sr,
         return;
     }
     if (sr && sr->which == Z_Records_NSD)
-    {
-       Z_DiagRec dr, *dr_p = &dr;
-       dr.which = Z_DiagRec_defaultFormat;
-       dr.u.defaultFormat = sr->u.nonSurrogateDiagnostic;
-       
-       response_diag (c, dr_p);
-    }
+       response_default_diag(c, sr->u.nonSurrogateDiagnostic);
     else if (sr && sr->which == Z_Records_multipleNSD)
     {
        if (sr->u.multipleNonSurDiagnostics->num_diagRecs >= 1)
@@ -1983,8 +1975,6 @@ static void handle_records (ZOOM_connection c, Z_Records *sr,
                Z_NamePlusRecord *myrec = 
                    zget_surrogateDiagRec(resultset->odr, 0, 14, 0);
                record_cache_add(resultset, myrec, resultset->start);
-               yaz_log(YLOG_LOG, "pseudo record 1, at pos %d",
-                       resultset->start);
            }
        }
        else if (present_phase)
@@ -1993,8 +1983,6 @@ static void handle_records (ZOOM_connection c, Z_Records *sr,
            Z_NamePlusRecord *myrec = 
                zget_surrogateDiagRec(resultset->odr, 0, 14, 0);
            record_cache_add(resultset, myrec, resultset->start);
-           yaz_log(YLOG_LOG, "pseudo record 1, at pos %d",
-                   resultset->start);
        }
     }
 }
@@ -2561,6 +2549,30 @@ Z_APDU *create_admin_package(ZOOM_package p, int type,
     return apdu;
 }
 
+static Z_APDU *create_xmlupdate_package(ZOOM_package p)
+{
+    Z_APDU *apdu = create_es_package(p, VAL_XMLUPDATE);
+    Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
+    Z_External *ext = (Z_External *) odr_malloc(p->odr_out, sizeof(*ext));
+    const char *doc = ZOOM_options_get(p->options, "doc");
+
+    req->taskSpecificParameters = ext;
+    ext->direct_reference = req->packageType;
+    ext->descriptor = 0;
+    ext->indirect_reference = 0;
+    
+    ext->which = Z_External_octet;
+    ext->u.single_ASN1_type = (Odr_oct *)
+       odr_malloc (p->odr_out, sizeof(Odr_oct));
+
+    if (!doc)
+       doc = "";
+    ext->u.single_ASN1_type->buf = (unsigned char*)
+       odr_strdup(p->odr_out, doc);
+    ext->u.single_ASN1_type->size = ext->u.single_ASN1_type->len = strlen(doc);
+    return apdu;
+}
+
 static Z_APDU *create_update_package(ZOOM_package p)
 {
     Z_APDU *apdu = 0;
@@ -2727,6 +2739,10 @@ ZOOM_API(void)
     {
        apdu = create_update_package(p);
     }
+    else if (!strcmp(type, "xmlupdate"))
+    {
+       apdu = create_xmlupdate_package(p);
+    }
     if (apdu)
     {
         if (encode_APDU(p->connection, apdu, p->odr_out) == 0)
@@ -2893,9 +2909,44 @@ static int es_response (ZOOM_connection c,
             ZOOM_options_setl (c->tasks->u.package->options,
                                "targetReference", (char*) id->buf, id->len);
     }
+    if (res->taskPackage && 
+       res->taskPackage->which == Z_External_octet)
+    {
+       Odr_oct *doc = res->taskPackage->u.octet_aligned;
+       ZOOM_options_setl (c->tasks->u.package->options,
+                          "xmlUpdateDoc", (char*) doc->buf, doc->len);
+    }
     return 1;
 }
 
+static void interpret_init_diag(ZOOM_connection c,
+                               Z_DiagnosticFormat *diag)
+{
+    if (diag->num > 0)
+    {
+       Z_DiagnosticFormat_s *ds = diag->elements[0];
+       if (ds->which == Z_DiagnosticFormat_s_defaultDiagRec)
+           response_default_diag(c, ds->u.defaultDiagRec);
+    }
+}
+
+
+static void interpret_otherinformation_field(ZOOM_connection c,
+                                            Z_OtherInformation *ui)
+{
+    int i;
+    for (i = 0; i < ui->num_elements; i++)
+    {
+       Z_OtherInformationUnit *unit = ui->list[i];
+       if (unit->which == Z_OtherInfo_externallyDefinedInfo &&
+           unit->information.externallyDefinedInfo &&
+           unit->information.externallyDefinedInfo->which ==
+           Z_External_diag1) 
+       {
+           interpret_init_diag(c, unit->information.externallyDefinedInfo->u.diag1);
+       } 
+    }
+}
 
 static void handle_apdu (ZOOM_connection c, Z_APDU *apdu)
 {
@@ -2928,7 +2979,12 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu)
                                    initrs->implementationVersion : "");
        if (!*initrs->result)
        {
-            set_ZOOM_error(c, ZOOM_ERROR_INIT, 0);
+           Z_External *uif = initrs->userInformationField;
+
+           set_ZOOM_error(c, ZOOM_ERROR_INIT, 0); /* default error */
+
+           if (uif && uif->which == Z_External_userInfo1)
+               interpret_otherinformation_field(c, uif->u.userInfo1);
        }
        else
        {