For OIDs use Odr_oid type everywhere, i.e. do not assume Odr_oid=int.
[yaz-moved-to-github.git] / src / zoom-c.c
index fb30049..f16b0d1 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.124 2007-04-13 09:55:41 adam Exp $
+ * $Id: zoom-c.c,v 1.130 2007-05-08 08:22:36 adam Exp $
  */
 /**
  * \file zoom-c.c
@@ -26,6 +26,8 @@
 #include <yaz/srw.h>
 #include <yaz/cql.h>
 #include <yaz/ccl.h>
+#include <yaz/query-charset.h>
+#include <yaz/copy_types.h>
 
 static int log_api = 0;
 static int log_details = 0;
@@ -45,9 +47,9 @@ static char *cql2pqf(ZOOM_connection c, const char *cql);
  * This wrapper is just for logging failed lookups.  It would be nicer
  * if it could cause failure when a lookup fails, but that's hard.
  */
-static int *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
+static Odr_oid *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
                                      int oid_class, const char *str) {
-    int *res = yaz_string_to_oid_odr(yaz_oid_std(), oid_class, str,
+    Odr_oid *res = yaz_string_to_oid_odr(yaz_oid_std(), oid_class, str,
                                      c->odr_out);
     if (res == 0)
         yaz_log(YLOG_WARN, "%p OID lookup (%d, '%s') failed",
@@ -362,6 +364,13 @@ ZOOM_API(ZOOM_connection)
     c->client_IP = 0;
     c->tasks = 0;
 
+    c->user = 0;
+    c->group = 0;
+    c->password = 0;
+
+    c->maximum_record_size = 0;
+    c->preferred_message_size = 0;
+
     c->odr_in = odr_createmem(ODR_DECODE);
     c->odr_out = odr_createmem(ODR_ENCODE);
 
@@ -443,24 +452,22 @@ ZOOM_API(void)
     }
     yaz_log(log_details, "%p ZOOM_connection_connect connect", c);
     xfree(c->proxy);
+    c->proxy = 0;
     val = ZOOM_options_get(c->options, "proxy");
     if (val && *val)
     {
         yaz_log(log_details, "%p ZOOM_connection_connect proxy=%s", c, val);
         c->proxy = xstrdup(val);
     }
-    else
-        c->proxy = 0;
 
     xfree(c->charset);
+    c->charset = 0;
     val = ZOOM_options_get(c->options, "charset");
     if (val && *val)
     {
         yaz_log(log_details, "%p ZOOM_connection_connect charset=%s", c, val);
         c->charset = xstrdup(val);
     }
-    else
-        c->charset = 0;
 
     xfree(c->lang);
     val = ZOOM_options_get(c->options, "lang");
@@ -521,6 +528,8 @@ ZOOM_API(void)
 
     ZOOM_options_set(c->options, "host", c->host_port);
 
+    xfree(c->cookie_out);
+    c->cookie_out = 0;
     val = ZOOM_options_get(c->options, "cookie");
     if (val && *val)
     { 
@@ -528,6 +537,8 @@ ZOOM_API(void)
         c->cookie_out = xstrdup(val);
     }
 
+    xfree(c->client_IP);
+    c->client_IP = 0;
     val = ZOOM_options_get(c->options, "clientIP");
     if (val && *val)
     {
@@ -536,6 +547,32 @@ ZOOM_API(void)
         c->client_IP = xstrdup(val);
     }
 
+    xfree(c->group);
+    c->group = 0;
+    val = ZOOM_options_get(c->options, "group");
+    if (val && *val)
+        c->group = xstrdup(val);
+
+    xfree(c->user);
+    c->user = 0;
+    val = ZOOM_options_get(c->options, "user");
+    if (val && *val)
+        c->user = xstrdup(val);
+
+    xfree(c->password);
+    c->password = 0;
+    val = ZOOM_options_get(c->options, "password");
+    if (!val)
+        val = ZOOM_options_get(c->options, "pass");
+
+    if (val && *val)
+        c->password = xstrdup(val);
+    
+    c->maximum_record_size =
+        ZOOM_options_get_int(c->options, "maximumRecordSize", 1024*1024);
+    c->preferred_message_size =
+        ZOOM_options_get_int(c->options, "preferredMessageSize", 1024*1024);
+
     c->async = ZOOM_options_get_bool(c->options, "async", 0);
     yaz_log(log_details, "%p ZOOM_connection_connect async=%d", c, c->async);
  
@@ -726,6 +763,9 @@ ZOOM_API(void)
     xfree(c->cookie_out);
     xfree(c->cookie_in);
     xfree(c->client_IP);
+    xfree(c->user);
+    xfree(c->group);
+    xfree(c->password);
     xfree(c);
 }
 
@@ -762,6 +802,7 @@ ZOOM_resultset ZOOM_resultset_create(void)
     r->next = 0;
     r->databaseNames = 0;
     r->num_databaseNames = 0;
+    r->rpn_iconv = 0;
     return r;
 }
 
@@ -792,6 +833,13 @@ ZOOM_API(ZOOM_resultset)
     r->query = q;
 
     r->options = ZOOM_options_create_with_parent(c->options);
+    
+    {
+        const char *cp = ZOOM_options_get(r->options, "rpnCharset");
+        if (cp)
+            r->rpn_iconv = yaz_iconv_open(cp, "UTF-8");
+    }
+
 
     start = ZOOM_options_get_int(r->options, "start", 0);
     count = ZOOM_options_get_int(r->options, "count", 0);
@@ -817,6 +865,8 @@ ZOOM_API(ZOOM_resultset)
     r->next = c->resultsets;
     c->resultsets = r;
 
+    
+
     if (c->host_port && c->proto == PROTO_HTTP)
     {
         if (!c->cs)
@@ -858,7 +908,7 @@ ZOOM_API(void)
     ZOOM_resultset_sort(ZOOM_resultset r,
                          const char *sort_type, const char *sort_spec)
 {
-    (void) ZOOM_resultset_sort(r, sort_type, sort_spec);
+    (void) ZOOM_resultset_sort1(r, sort_type, sort_spec);
 }
 
 ZOOM_API(int)
@@ -963,6 +1013,8 @@ static void resultset_destroy(ZOOM_resultset r)
         }
         ZOOM_query_destroy(r->query);
         ZOOM_options_destroy(r->options);
+        if (r->rpn_iconv)
+            yaz_iconv_close(r->rpn_iconv);
         odr_destroy(r->odr);
         xfree(r->setname);
         xfree(r->schema);
@@ -1173,7 +1225,7 @@ static void otherInfo_attach(ZOOM_connection c, Z_APDU *a, ODR out)
     for (i = 0; i<200; i++)
     {
         size_t len;
-        int *oid;
+        Odr_oid *oid;
         Z_OtherInformation **oi;
         char buf[80];
         const char *val;
@@ -1207,19 +1259,17 @@ static int encode_APDU(ZOOM_connection c, Z_APDU *a, ODR out)
     assert(a);
     if (c->cookie_out)
     {
-        const int *oid = yaz_string_to_oid(
-            yaz_oid_std(), CLASS_USERINFO, OID_STR_COOKIE);
         Z_OtherInformation **oi;
         yaz_oi_APDU(a, &oi);
-        yaz_oi_set_string_oid(oi, out, oid, 1, c->cookie_out);
+        yaz_oi_set_string_oid(oi, out, yaz_oid_userinfo_cookie, 
+                              1, c->cookie_out);
     }
     if (c->client_IP)
     {
-        const int *oid = yaz_string_to_oid(
-            yaz_oid_std(), CLASS_USERINFO, OID_STR_CLIENT_IP);
         Z_OtherInformation **oi;
         yaz_oi_APDU(a, &oi);
-        yaz_oi_set_string_oid(oi, out, oid, 1, c->client_IP);
+        yaz_oi_set_string_oid(oi, out, yaz_oid_userinfo_client_ip, 
+                              1, c->client_IP);
     }
     otherInfo_attach(c, a, out);
     if (!z_APDU(out, &a, 0, 0))
@@ -1266,15 +1316,8 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
     Z_InitRequest *ireq = apdu->u.initRequest;
     Z_IdAuthentication *auth = (Z_IdAuthentication *)
         odr_malloc(c->odr_out, sizeof(*auth));
-    const char *auth_groupId = ZOOM_options_get(c->options, "group");
-    const char *auth_userId = ZOOM_options_get(c->options, "user");
-    const char *auth_password = ZOOM_options_get(c->options, "password");
     char *version;
 
-    /* support the pass for backwards compatibility */
-    if (!auth_password)
-        auth_password = ZOOM_options_get(c->options, "pass");
-        
     ODR_MASK_SET(ireq->options, Z_Options_search);
     ODR_MASK_SET(ireq->options, Z_Options_present);
     ODR_MASK_SET(ireq->options, Z_Options_scan);
@@ -1298,7 +1341,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.124 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.130 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
@@ -1307,60 +1350,35 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
                     odr_prepend(c->odr_out, &version[11],
                                 ireq->implementationVersion));
     
-    *ireq->maximumRecordSize =
-        ZOOM_options_get_int(c->options, "maximumRecordSize", 1024*1024);
-    *ireq->preferredMessageSize =
-        ZOOM_options_get_int(c->options, "preferredMessageSize", 1024*1024);
+    *ireq->maximumRecordSize = c->maximum_record_size;
+    *ireq->preferredMessageSize = c->preferred_message_size;
     
-    if (auth_groupId || auth_password)
+    if (c->group || c->password)
     {
         Z_IdPass *pass = (Z_IdPass *) odr_malloc(c->odr_out, sizeof(*pass));
-        int i = 0;
         pass->groupId = 0;
-        if (auth_groupId && *auth_groupId)
-        {
-            pass->groupId = (char *)
-                odr_malloc(c->odr_out, strlen(auth_groupId)+1);
-            strcpy(pass->groupId, auth_groupId);
-            i++;
-        }
+        if (c->group)
+            pass->groupId = odr_strdup(c->odr_out, c->group);
         pass->userId = 0;
-        if (auth_userId && *auth_userId)
-        {
-            pass->userId = (char *)
-                odr_malloc(c->odr_out, strlen(auth_userId)+1);
-            strcpy(pass->userId, auth_userId);
-            i++;
-        }
+        if (c->user)
+            pass->userId = odr_strdup(c->odr_out, c->user);
         pass->password = 0;
-        if (auth_password && *auth_password)
-        {
-            pass->password = (char *)
-                odr_malloc(c->odr_out, strlen(auth_password)+1);
-            strcpy(pass->password, auth_password);
-            i++;
-        }
-        if (i)
-        {
-            auth->which = Z_IdAuthentication_idPass;
-            auth->u.idPass = pass;
-            ireq->idAuthentication = auth;
-        }
+        if (c->password)
+            pass->password = odr_strdup(c->odr_out, c->password);
+        auth->which = Z_IdAuthentication_idPass;
+        auth->u.idPass = pass;
+        ireq->idAuthentication = auth;
     }
-    else if (auth_userId)
+    else if (c->user)
     {
         auth->which = Z_IdAuthentication_open;
-        auth->u.open = (char *)
-            odr_malloc(c->odr_out, strlen(auth_userId)+1);
-        strcpy(auth->u.open, auth_userId);
+        auth->u.open = odr_strdup(c->odr_out, c->user);
         ireq->idAuthentication = auth;
     }
     if (c->proxy)
     {
-        const int *oid = yaz_string_to_oid(
-            yaz_oid_std(), CLASS_USERINFO, OID_STR_CLIENT_IP);
         yaz_oi_set_string_oid(&ireq->otherInfo, c->odr_out,
-                              oid, 1, c->host_port);
+                              yaz_oid_userinfo_proxy, 1, c->host_port);
     }
     if (c->charset || c->lang)
     {
@@ -1551,7 +1569,13 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c)
         set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
         return zoom_complete;
     }
-
+    if (r->query->z_query->which == Z_Query_type_1 && r->rpn_iconv)
+    {
+        search_req->query = yaz_copy_Z_Query(r->query->z_query, c->odr_out);
+        
+        yaz_query_charset_convert_rpnquery(search_req->query->u.type_1,
+                                           c->odr_out, r->rpn_iconv);
+    }
     search_req->databaseNames = r->databaseNames;
     search_req->num_databaseNames = r->num_databaseNames;
 
@@ -1642,7 +1666,7 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c)
 
 static void response_default_diag(ZOOM_connection c, Z_DefaultDiagFormat *r)
 {
-    int oclass;
+    oid_class oclass;
     char *addinfo = 0;
 
     switch (r->which)
@@ -1865,7 +1889,7 @@ ZOOM_API(int)
         if (diag_rec->which == Z_DiagRec_defaultFormat)
         {
             Z_DefaultDiagFormat *ddf = diag_rec->u.defaultFormat;
-            int oclass;
+            oid_class oclass;
     
             error = *ddf->condition;
             switch (ddf->which)
@@ -1979,7 +2003,7 @@ ZOOM_API(const char *)
     if (!strcmp(type, "render"))
     {
         Z_External *r = (Z_External *) npr->u.databaseRecord;
-        const int *oid = r->direct_reference;
+        const Odr_oid *oid = r->direct_reference;
 
         /* render bibliographic record .. */
         if (r->which == Z_External_OPAC)
@@ -2027,7 +2051,7 @@ ZOOM_API(const char *)
     else if (!strcmp(type, "xml"))
     {
         Z_External *r = (Z_External *) npr->u.databaseRecord;
-        const int *oid = r->direct_reference;
+        const Odr_oid *oid = r->direct_reference;
 
         /* render bibliographic record .. */
         if (r->which == Z_External_OPAC)
@@ -2688,6 +2712,20 @@ ZOOM_API(ZOOM_scanset)
         p_query_scan(scan->odr, PROTO_Z3950, &scan->attributeSet, start);
     xfree(freeme);
 
+    {
+        const char *cp = ZOOM_options_get(scan->options, "rpnCharset");
+        if (cp)
+        {
+            yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8");
+            if (cd)
+            {
+                yaz_query_charset_convert_apt(scan->termListAndStartPoint,
+                                              scan->odr, cd);
+            }
+        }
+    }
+        
+
     scan->databaseNames = set_DatabaseNames(c, c->options,
                                             &scan->num_databaseNames,
                                             scan->odr);
@@ -2849,7 +2887,7 @@ ZOOM_API(void)
     ZOOM_options_set(scan->options, key, val);
 }
 
-static Z_APDU *create_es_package(ZOOM_package p, const char *type)
+static Z_APDU *create_es_package(ZOOM_package p, const Odr_oid *oid)
 {
     const char *str;
     Z_APDU *apdu = zget_APDU(p->odr_out, Z_APDU_extendedServicesRequest);
@@ -2865,8 +2903,7 @@ static Z_APDU *create_es_package(ZOOM_package p, const char *type)
     if (str)
         req->userId = odr_strdup(p->odr_out, str);
     
-    req->packageType = yaz_string_to_oid_odr(yaz_oid_std(), CLASS_EXTSERV,
-                                             type, p->odr_out);
+    req->packageType = odr_oiddup(p->odr_out, oid);
 
     str = ZOOM_options_get(p->options, "function");
     if (str)
@@ -2914,10 +2951,7 @@ static Z_External *encode_ill_request(ZOOM_package p)
         char *illRequest_buf = odr_getbuf(out, &illRequest_size, 0);
                 
         r = (Z_External *) odr_malloc(out, sizeof(*r));
-        r->direct_reference = yaz_string_to_oid_odr(yaz_oid_std(),
-                                                    CLASS_GENERAL,
-                                                    OID_STR_ILL_1,
-                                                    out);
+        r->direct_reference = odr_oiddup(out, yaz_oid_general_isoill_1);
         r->indirect_reference = 0;
         r->descriptor = 0;
         r->which = Z_External_single;
@@ -3001,7 +3035,7 @@ Z_APDU *create_admin_package(ZOOM_package p, int type,
                              Z_ESAdminOriginPartToKeep **toKeepP,
                              Z_ESAdminOriginPartNotToKeep **notToKeepP)
 {
-    Z_APDU *apdu = create_es_package(p, OID_STR_ADMIN);
+    Z_APDU *apdu = create_es_package(p, yaz_oid_extserv_admin);
     if (apdu)
     {
         Z_ESAdminOriginPartToKeep  *toKeep;
@@ -3014,9 +3048,7 @@ Z_APDU *create_admin_package(ZOOM_package p, int type,
         if (num_db > 0)
             first_db = db[0];
             
-        r->direct_reference =
-            yaz_string_to_oid_odr(yaz_oid_std(),
-                                  CLASS_EXTSERV, OID_STR_ADMIN, p->odr_out);
+        r->direct_reference = odr_oiddup(p->odr_out, yaz_oid_extserv_admin);
         r->descriptor = 0;
         r->indirect_reference = 0;
         r->which = Z_External_ESAdmin;
@@ -3051,7 +3083,7 @@ Z_APDU *create_admin_package(ZOOM_package p, int type,
 
 static Z_APDU *create_xmlupdate_package(ZOOM_package p)
 {
-    Z_APDU *apdu = create_es_package(p, OID_STR_XMLES);
+    Z_APDU *apdu = create_es_package(p, yaz_oid_extserv_xml_es);
     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");
@@ -3083,7 +3115,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
     const char *record_buf = ZOOM_options_get(p->options, "record");
     const char *syntax_str = ZOOM_options_get(p->options, "syntax");
     int action_no = -1;
-    int *syntax_oid = 0;
+    Odr_oid *syntax_oid = 0;
 
     if (!syntax_str)
         syntax_str = "xml";
@@ -3121,7 +3153,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
     else
         return 0;
 
-    apdu = create_es_package(p, OID_STR_EXT_UPDATE);
+    apdu = create_es_package(p, yaz_oid_extserv_database_update);
     if (apdu)
     {
         Z_IUOriginPartToKeep *toKeep;
@@ -3132,9 +3164,8 @@ static Z_APDU *create_update_package(ZOOM_package p)
         apdu->u.extendedServicesRequest->taskSpecificParameters = r;
 
         
-        r->direct_reference =
-            yaz_string_to_oid_odr(yaz_oid_std(), CLASS_EXTSERV,
-                                  OID_STR_EXT_UPDATE, p->odr_out);
+        r->direct_reference = odr_oiddup(p->odr_out, 
+                                         yaz_oid_extserv_database_update);
         r->descriptor = 0;
         r->which = Z_External_update;
         r->indirect_reference = 0;
@@ -3208,14 +3239,13 @@ ZOOM_API(void)
     p->buf_out = 0;
     if (!strcmp(type, "itemorder"))
     {
-        apdu = create_es_package(p, OID_STR_ITEMORDER);
+        apdu = create_es_package(p, yaz_oid_extserv_item_order);
         if (apdu)
         {
             Z_External *r = (Z_External *) odr_malloc(p->odr_out, sizeof(*r));
             
-            r->direct_reference =
-                yaz_string_to_oid_odr(yaz_oid_std(), CLASS_EXTSERV,
-                                      OID_STR_ITEMORDER, p->odr_out);
+            r->direct_reference = 
+                odr_oiddup(p->odr_out, yaz_oid_extserv_item_order);
             r->descriptor = 0;
             r->which = Z_External_itemOrder;
             r->indirect_reference = 0;
@@ -3456,7 +3486,7 @@ static void interpret_otherinformation_field(ZOOM_connection c,
 
 
 static void set_init_option(const char *name, void *clientData) {
-    ZOOM_connection c = clientData;
+    ZOOM_connection c = (ZOOM_connection) clientData;
     char buf[80];
 
     sprintf(buf, "init_opt_%.70s", name);
@@ -3509,12 +3539,9 @@ static void recv_apdu(ZOOM_connection c, Z_APDU *apdu)
         }
         else
         {
-            const int *oid = yaz_string_to_oid(yaz_oid_std(),
-                                               CLASS_USERINFO,
-                                               OID_STR_COOKIE);
             char *cookie =
                 yaz_oi_get_string_oid(&apdu->u.initResponse->otherInfo,
-                                      oid, 1, 0);
+                                      yaz_oid_userinfo_cookie, 1, 0);
             xfree(c->cookie_in);
             c->cookie_in = 0;
             if (cookie)
@@ -3662,8 +3689,7 @@ static void handle_srw_response(ZOOM_connection c,
             odr_malloc(c->odr_in, sizeof(Z_External));
         npr->u.databaseRecord->descriptor = 0;
         npr->u.databaseRecord->direct_reference =
-            yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN, OID_STR_XML,
-                                  c->odr_in);
+            odr_oiddup(c->odr_in, yaz_oid_recsyn_xml);
         npr->u.databaseRecord->which = Z_External_octet;
 
         npr->u.databaseRecord->u.octet_aligned = (Odr_oct *)
@@ -4090,7 +4116,7 @@ ZOOM_API(int)
 
 static void cql2pqf_wrbuf_puts(const char *buf, void *client_data)
 {
-    WRBUF wrbuf = client_data;
+    WRBUF wrbuf = (WRBUF) client_data;
     wrbuf_puts(wrbuf, buf);
 }