Fix ZOOM_connection_connect SEGVs if host==NULL YAZ-746
[yaz-moved-to-github.git] / src / zoom-c.c
index f2363b6..1bbac7e 100644 (file)
@@ -96,8 +96,6 @@ int ZOOM_uri_to_code(const char *uri)
     return code;
 }
 
-
-
 void ZOOM_set_error(ZOOM_connection c, int error, const char *addinfo)
 {
     ZOOM_set_dset_error(c, error, "ZOOM", addinfo, 0);
@@ -136,9 +134,6 @@ void ZOOM_connection_show_task(ZOOM_task task)
     case ZOOM_TASK_SEARCH:
         yaz_log(YLOG_LOG, "search p=%p", task);
         break;
-    case ZOOM_TASK_RETRIEVE:
-        yaz_log(YLOG_LOG, "retrieve p=%p", task);
-        break;
     case ZOOM_TASK_CONNECT:
         yaz_log(YLOG_LOG, "connect p=%p", task);
         break;
@@ -201,12 +196,6 @@ void ZOOM_connection_remove_task(ZOOM_connection c)
             xfree(task->u.search.elementSetName);
             xfree(task->u.search.schema);
             break;
-        case ZOOM_TASK_RETRIEVE:
-            resultset_destroy(task->u.retrieve.resultset);
-            xfree(task->u.retrieve.syntax);
-            xfree(task->u.retrieve.elementSetName);
-            xfree(task->u.retrieve.schema);
-            break;
         case ZOOM_TASK_CONNECT:
             break;
         case ZOOM_TASK_SCAN:
@@ -309,9 +298,7 @@ ZOOM_API(ZOOM_connection)
     c->cookies = 0;
     c->saveAPDU_wrbuf = 0;
 
-#if HAVE_LIBMEMCACHED_MEMCACHED_H
-    c->mc_st = 0;
-#endif
+    ZOOM_memcached_init(c);
     return c;
 }
 
@@ -442,15 +429,25 @@ ZOOM_API(void)
 
     if (host)
     {
+        char hostn[128];
+        const char *http_lead;
+
+        val = ZOOM_options_get(c->options, "sru");
+        if (val && *val && !strstr(host, "://"))
+            http_lead = "http://";
+        else
+            http_lead = "";
+        c->sru_mode = get_sru_mode_from_string(val);
+
         xfree(c->host_port);
         if (portnum)
         {
-            char hostn[128];
             sprintf(hostn, "%.80s:%d", host, portnum);
-            c->host_port = xstrdup(hostn);
+            host = hostn;
         }
-        else
-            c->host_port = xstrdup(host);
+        c->host_port = xmalloc(strlen(host) + strlen(http_lead) + 1);
+        strcpy(c->host_port, http_lead);
+        strcat(c->host_port, host);
     }
 
     {
@@ -486,9 +483,6 @@ ZOOM_API(void)
         }
     }
 
-    val = ZOOM_options_get(c->options, "sru");
-    c->sru_mode = get_sru_mode_from_string(val);
-
     xfree(c->sru_version);
     val = ZOOM_options_get(c->options, "sru_version");
     c->sru_version = xstrdup(val ? val : "1.2");
@@ -550,29 +544,11 @@ ZOOM_API(void)
     yaz_cookies_destroy(c->cookies);
     c->cookies = yaz_cookies_create();
 
-#if HAVE_LIBMEMCACHED_MEMCACHED_H
-    if (c->mc_st)
-    {
-        memcached_free(c->mc_st);
-        c->mc_st = 0;
-    }
-#endif
-    val = ZOOM_options_get(c->options, "memcached");
-    if (val && *val)
+    if (ZOOM_memcached_configure(c))
     {
-#if HAVE_LIBMEMCACHED_MEMCACHED_H
-        c->mc_st = memcached(val, strlen(val));
-        if (!c->mc_st)
-        {
-            ZOOM_set_error(c, ZOOM_ERROR_MEMCACHED, val);
-            return;
-        }
-#else
-        ZOOM_set_error(c, ZOOM_ERROR_MEMCACHED, "not enabled");
+        ZOOM_connection_remove_tasks(c);
         return;
-#endif
     }
-
     if (c->sru_mode == zoom_sru_error)
     {
         ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, val);
@@ -618,10 +594,7 @@ ZOOM_API(void)
         return;
     yaz_log(c->log_api, "%p ZOOM_connection_destroy", c);
 
-#if HAVE_LIBMEMCACHED_MEMCACHED_H
-    if (c->mc_st)
-        memcached_free(c->mc_st);
-#endif
+    ZOOM_memcached_destroy(c);
     if (c->cs)
         cs_close(c->cs);
 
@@ -703,7 +676,7 @@ ZOOM_resultset ZOOM_resultset_create(void)
     yaz_log(log_details0, "%p ZOOM_resultset_create", r);
     r->refcount = 1;
     r->size = 0;
-    r->odr = odr_createmem(ODR_ENCODE);
+    r->odr = odr_createmem(ODR_DECODE);
     r->piggyback = 1;
     r->setname = 0;
     r->step = 0;
@@ -714,8 +687,9 @@ ZOOM_resultset ZOOM_resultset_create(void)
     r->connection = 0;
     r->databaseNames = 0;
     r->num_databaseNames = 0;
-    r->facets = 0;
-    r->num_facets = 0;
+    r->req_facets = 0;
+    r->res_facets = 0;
+    r->num_res_facets = 0;
     r->facets_names = 0;
     r->mutex = 0;
     yaz_mutex_create(&r->mutex);
@@ -727,6 +701,7 @@ ZOOM_resultset ZOOM_resultset_create(void)
 #endif
     resultset_use(1);
     r->mc_key = 0;
+    r->live_set = 0;
     return r;
 }
 
@@ -747,16 +722,18 @@ ZOOM_API(ZOOM_resultset)
     ZOOM_connection_search(ZOOM_connection c, ZOOM_query q)
 {
     ZOOM_resultset r = ZOOM_resultset_create();
-    const char *cp;
     ZOOM_task task;
     int start, count;
     const char *syntax, *elementSetName, *schema;
     yaz_log(c->log_api, "%p ZOOM_connection_search set %p query %p", c, r, q);
     r->r_sort_spec = ZOOM_query_get_sortspec(q);
     r->query = q;
+    ZOOM_query_addref(q);
 
     r->options = ZOOM_options_create_with_parent(c->options);
 
+    r->req_facets = odr_strdup_null(r->odr,
+                                    ZOOM_options_get(r->options, "facets"));
     start = ZOOM_options_get_int(r->options, "start", 0);
     count = ZOOM_options_get_int(r->options, "count", 0);
     {
@@ -766,40 +743,16 @@ ZOOM_API(ZOOM_resultset)
                                        (cp != 0 ? "presentChunk": "step"), 0);
     }
     r->piggyback = ZOOM_options_get_bool(r->options, "piggyback", 1);
-    cp = ZOOM_options_get(r->options, "setname");
-    if (cp)
-        r->setname = xstrdup(cp);
-
-    r->databaseNames = ZOOM_connection_get_databases(c, c->options, &r->num_databaseNames,
-                                         r->odr);
-
+    r->setname = odr_strdup_null(r->odr,
+                                 ZOOM_options_get(r->options, "setname"));
+    r->databaseNames = ZOOM_connection_get_databases(c, c->options,
+                                                     &r->num_databaseNames,
+                                                     r->odr);
     r->connection = c;
     r->next = c->resultsets;
     c->resultsets = r;
 
-#if HAVE_LIBMEMCACHED_MEMCACHED_H
-    r->mc_key = wrbuf_alloc();
-    wrbuf_puts(r->mc_key, c->host_port);
-    wrbuf_puts(r->mc_key, ";");
-    wrbuf_puts(r->mc_key, ZOOM_query_get_query_string(q));
-    if (c->mc_st)
-    {
-        size_t v_len;
-        uint32_t flags;
-        memcached_return_t rc;
-        char *v = memcached_get(c->mc_st, wrbuf_buf(r->mc_key),
-                                wrbuf_len(r->mc_key), &v_len, &flags, &rc);
-        if (v)
-        {
-            yaz_log(YLOG_LOG, "For key %s got value %.*s",
-                    wrbuf_cstr(r->mc_key), (int) v_len, v);
-        }
-        else
-        {
-            yaz_log(YLOG_LOG, "For key %s got NO value", wrbuf_cstr(r->mc_key));
-        }
-    }
-#endif
+    ZOOM_memcached_resultset(r, q);
 
     if (c->host_port && c->proto == PROTO_HTTP)
     {
@@ -819,7 +772,6 @@ ZOOM_API(ZOOM_resultset)
     task->u.search.resultset = r;
     task->u.search.start = start;
     task->u.search.count = count;
-    task->u.search.recv_search_fired = 0;
 
     syntax = ZOOM_options_get(r->options, "preferredRecordSyntax");
     task->u.search.syntax = syntax ? xstrdup(syntax) : 0;
@@ -831,8 +783,6 @@ ZOOM_API(ZOOM_resultset)
 
     ZOOM_resultset_addref(r);
 
-    ZOOM_query_addref(q);
-
     if (!c->async)
     {
         while (ZOOM_event(1, &c))
@@ -920,7 +870,6 @@ static void resultset_destroy(ZOOM_resultset r)
         ZOOM_query_destroy(r->query);
         ZOOM_options_destroy(r->options);
         odr_destroy(r->odr);
-        xfree(r->setname);
         yaz_mutex_destroy(&r->mutex);
 #if SHPTR
         YAZ_SHPTR_DEC(r->record_wrbuf, wrbuf_destroy);
@@ -986,19 +935,19 @@ static void ZOOM_resultset_retrieve(ZOOM_resultset r,
             c->reconnect_ok = 1;
         }
     }
-    task = ZOOM_connection_add_task(c, ZOOM_TASK_RETRIEVE);
-    task->u.retrieve.resultset = r;
-    task->u.retrieve.start = start;
-    task->u.retrieve.count = count;
+    task = ZOOM_connection_add_task(c, ZOOM_TASK_SEARCH);
+    task->u.search.resultset = r;
+    task->u.search.start = start;
+    task->u.search.count = count;
 
     syntax = ZOOM_options_get(r->options, "preferredRecordSyntax");
-    task->u.retrieve.syntax = syntax ? xstrdup(syntax) : 0;
+    task->u.search.syntax = syntax ? xstrdup(syntax) : 0;
     elementSetName = ZOOM_options_get(r->options, "elementSetName");
-    task->u.retrieve.elementSetName = elementSetName
+    task->u.search.elementSetName = elementSetName
         ? xstrdup(elementSetName) : 0;
 
     cp = ZOOM_options_get(r->options, "schema");
-    task->u.retrieve.schema = cp ? xstrdup(cp) : 0;
+    task->u.search.schema = cp ? xstrdup(cp) : 0;
 
     ZOOM_resultset_addref(r);
 
@@ -1029,37 +978,37 @@ ZOOM_API(void)
 }
 
 ZOOM_API(size_t)
-    ZOOM_resultset_facets_size(ZOOM_resultset r) {
-    return r->num_facets;
+    ZOOM_resultset_facets_size(ZOOM_resultset r)
+{
+    return r->num_res_facets;
 }
 
 ZOOM_API(ZOOM_facet_field)
-    ZOOM_resultset_get_facet_field(ZOOM_resultset r, const char *name) {
-    int num = r->num_facets;
-    ZOOM_facet_field *facets = r->facets;
-    int index;
-    for (index = 0; index < num; index++) {
-        if (!strcmp(facets[index]->facet_name, name)) {
-            return facets[index];
-        }
-    }
+    ZOOM_resultset_get_facet_field(ZOOM_resultset r, const char *name)
+{
+    int num = r->num_res_facets;
+    ZOOM_facet_field *facets = r->res_facets;
+    int i;
+    for (i = 0; i < num; i++)
+        if (!strcmp(facets[i]->facet_name, name))
+            return facets[i];
     return 0;
 }
 
 ZOOM_API(ZOOM_facet_field)
-    ZOOM_resultset_get_facet_field_by_index(ZOOM_resultset r, int index) {
-    int num = r->num_facets;
-    ZOOM_facet_field *facets = r->facets;
-    if (index >= 0 && index < num) {
-        return facets[index];
-    }
+    ZOOM_resultset_get_facet_field_by_index(ZOOM_resultset r, int idx)
+{
+    int num = r->num_res_facets;
+    ZOOM_facet_field *facets = r->res_facets;
+    if (idx >= 0 && idx < num)
+        return facets[idx];
     return 0;
 }
 
 ZOOM_API(ZOOM_facet_field *)
     ZOOM_resultset_facets(ZOOM_resultset r)
 {
-    return r->facets;
+    return r->res_facets;
 }
 
 ZOOM_API(const char**)
@@ -1081,7 +1030,8 @@ ZOOM_API(size_t)
 }
 
 ZOOM_API(const char*)
-    ZOOM_facet_field_get_term(ZOOM_facet_field field, size_t idx, int *freq) {
+    ZOOM_facet_field_get_term(ZOOM_facet_field field, size_t idx, int *freq)
+{
     *freq = field->facet_terms[idx].frequency;
     return field->facet_terms[idx].term;
 }
@@ -1179,7 +1129,7 @@ ZOOM_API(ZOOM_record)
     const char *schema =
         ZOOM_options_get(s->options, "schema");
 
-    return ZOOM_record_cache_lookup(s, pos, syntax, elementSetName, schema);
+    return ZOOM_record_cache_lookup_i(s, pos, syntax, elementSetName, schema);
 }
 
 ZOOM_API(ZOOM_record)
@@ -1494,13 +1444,7 @@ ZOOM_API(int)
             if (c->proto == PROTO_HTTP)
                 ret = ZOOM_connection_srw_send_search(c);
             else
-                ret = ZOOM_connection_Z3950_send_search(c);
-            break;
-        case ZOOM_TASK_RETRIEVE:
-            if (c->proto == PROTO_HTTP)
-                ret = ZOOM_connection_srw_send_search(c);
-            else
-                ret = send_Z3950_present(c);
+                ret = ZOOM_connection_Z3950_search(c);
             break;
         case ZOOM_TASK_CONNECT:
             ret = do_connect(c);