* Copyright (c) 2000-2004, Index Data
* See the file LICENSE for details.
*
- * $Id: zoom-c.c,v 1.20 2004-01-22 11:20:54 adam Exp $
+ * $Id: zoom-c.c,v 1.28 2004-04-30 12:43:32 adam Exp $
*
* ZOOM layer for C, connections, result sets, queries.
*/
const char *dset,
const char *addinfo, const char *addinfo2)
{
+ char *cp;
xfree (c->addinfo);
c->addinfo = 0;
c->error = error;
- c->diagset = dset;
+ if (!c->diagset || strcmp(dset, c->diagset))
+ {
+ xfree(c->diagset);
+ c->diagset = xstrdup(dset);
+ /* remove integer part from SRW diagset .. */
+ if ((cp = strrchr(c->diagset, '/')))
+ *cp = '\0';
+ }
if (addinfo && addinfo2)
{
c->addinfo = xmalloc(strlen(addinfo) + strlen(addinfo2) + 2);
switch (task->which)
{
case ZOOM_TASK_SEARCH:
-
ZOOM_resultset_destroy (task->u.search.resultset);
break;
case ZOOM_TASK_RETRIEVE:
case ZOOM_TASK_PACKAGE:
ZOOM_package_destroy (task->u.package);
break;
+ case ZOOM_TASK_SORT:
+ ZOOM_resultset_destroy (task->u.sort.resultset);
+ ZOOM_query_destroy(task->u.sort.q);
+ break;
default:
assert (0);
}
c->reconnect_ok = 0;
c->state = STATE_IDLE;
c->addinfo = 0;
+ c->diagset = 0;
set_ZOOM_error(c, ZOOM_ERROR_NONE, 0);
c->buf_in = 0;
c->len_in = 0;
s->z_query->which = Z_Query_type_1;
s->z_query->u.type_1 = p_query_rpn(s->odr, PROTO_Z3950, str);
if (!s->z_query->u.type_1)
+ {
+ s->z_query = 0;
return -1;
+ }
return 0;
}
xfree (c->buf_in);
xfree (c->addinfo);
+ xfree (c->diagset);
odr_destroy (c->odr_in);
odr_destroy (c->odr_out);
ZOOM_options_destroy (c->options);
r, r->refcount);
}
}
+
ZOOM_resultset ZOOM_resultset_create ()
{
ZOOM_resultset r = (ZOOM_resultset) xmalloc (sizeof(*r));
}
ZOOM_API(void)
+ ZOOM_resultset_sort(ZOOM_resultset r,
+ const char *sort_type, const char *sort_spec)
+{
+ ZOOM_connection c = r->connection;
+ ZOOM_task task;
+
+ if (!c)
+ return;
+
+ if (c->host_port && c->proto == PROTO_HTTP)
+ {
+ if (!c->cs)
+ {
+ yaz_log(LOG_DEBUG, "NO COMSTACK");
+ ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT);
+ }
+ else
+ {
+ yaz_log(LOG_DEBUG, "PREPARE FOR RECONNECT");
+ c->reconnect_ok = 1;
+ }
+ }
+
+ ZOOM_resultset_cache_reset(r);
+ task = ZOOM_connection_add_task (c, ZOOM_TASK_SORT);
+ task->u.sort.resultset = r;
+ task->u.sort.q = ZOOM_query_create();
+ ZOOM_query_sortby(task->u.sort.q, sort_spec);
+
+ ZOOM_resultset_addref (r);
+
+ if (!c->async)
+ {
+ while (ZOOM_event (1, &c))
+ ;
+ }
+}
+
+ZOOM_API(void)
+ ZOOM_resultset_cache_reset(ZOOM_resultset r)
+{
+ ZOOM_record_cache rc;
+
+ for (rc = r->record_cache; rc; rc = rc->next)
+ {
+ if (rc->rec.wrbuf_marc)
+ wrbuf_free (rc->rec.wrbuf_marc, 1);
+ if (rc->rec.wrbuf_iconv)
+ wrbuf_free (rc->rec.wrbuf_iconv, 1);
+ if (rc->rec.wrbuf_opac)
+ wrbuf_free (rc->rec.wrbuf_opac, 1);
+ }
+ r->record_cache = 0;
+}
+
+ZOOM_API(void)
ZOOM_resultset_destroy(ZOOM_resultset r)
{
if (!r)
r, r->refcount);
if (r->refcount == 0)
{
- ZOOM_record_cache rc;
+ ZOOM_resultset_cache_reset(r);
- for (rc = r->record_cache; rc; rc = rc->next)
- {
- if (rc->rec.wrbuf_marc)
- wrbuf_free (rc->rec.wrbuf_marc, 1);
- if (rc->rec.wrbuf_iconv)
- wrbuf_free (rc->rec.wrbuf_iconv, 1);
- if (rc->rec.wrbuf_opac)
- wrbuf_free (rc->rec.wrbuf_opac, 1);
- }
if (r->connection)
{
/* remove ourselves from the resultsets in connection */
}
}
+static void get_cert(ZOOM_connection c)
+{
+ char *cert_buf;
+ int cert_len;
+
+ if (cs_get_peer_certificate_x509(c->cs, &cert_buf, &cert_len))
+ {
+ ZOOM_connection_option_setl(c, "sslPeerCert",
+ cert_buf, cert_len);
+ xfree(cert_buf);
+ }
+}
+
static zoom_ret do_connect (ZOOM_connection c)
{
void *add;
yaz_log (LOG_DEBUG, "do_connect host=%s", effective_host);
- assert (!c->cs);
+ if (c->cs)
+ cs_close(c->cs);
c->cs = cs_create_host (effective_host, 0, &add);
if (c->cs && c->cs->protocol == PROTO_HTTP)
{
ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
ZOOM_connection_put_event(c, event);
+ get_cert(c);
if (c->proto == PROTO_Z3950)
ZOOM_connection_send_init(c);
else
ZOOM_options_get(c->options, "implementationName"),
odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName));
- version = odr_strdup(c->odr_out, "$Revision: 1.20 $");
+ version = odr_strdup(c->odr_out, "$Revision: 1.28 $");
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
ireq->implementationVersion = odr_prepend(c->odr_out,
/* prepare query for the search request */
search_req->query = r->query->z_query;
+ if (!search_req->query)
+ {
+ set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
+ return zoom_complete;
+ }
search_req->databaseNames =
set_DatabaseNames (c, r->options, &search_req->num_databaseNames);
i++;
if (!strncmp(type_spec+i, "charset=", 8))
{
- cp = type_spec+i+8;
- for (i = 0; cp[i] && i < sizeof(charset)-1; i++)
+ int j = 0;
+ i = i + 8; /* skip charset= */
+ for (j = 0; type_spec[i] && j < sizeof(charset)-1; i++, j++)
{
- if (cp[i] == ';' || cp[i] == ' ')
+ if (type_spec[i] == ';' || type_spec[i] == ' ')
break;
- charset[i] = cp[i];
+ charset[j] = cp[i];
}
- charset[i] = '\0';
+ charset[j] = '\0';
}
else if (!strncmp(type_spec+i, "xpath=", 6))
{
- cp = type_spec+i+6;
- for (i = 0; cp[i] && i < sizeof(xpath)-1; i++)
- xpath[i] = cp[i];
- xpath[i] = '\0';
+ int j = 0;
+ i = i + 6;
+ for (j = 0; type_spec[i] && j < sizeof(xpath)-1; i++, j++)
+ xpath[j] = cp[i];
+ xpath[j] = '\0';
}
while (type_spec[i] == ' ')
i++;
return 1;
}
-static zoom_ret send_sort (ZOOM_connection c)
+static zoom_ret send_sort (ZOOM_connection c,
+ ZOOM_resultset resultset)
{
- ZOOM_resultset resultset;
-
- if (!c->tasks || c->tasks->which != ZOOM_TASK_SEARCH)
- return zoom_complete;
-
- resultset = c->tasks->u.search.resultset;
-
if (c->error)
- {
resultset->r_sort_spec = 0;
- return zoom_complete;
- }
if (resultset->r_sort_spec)
{
Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_sortRequest);
break;
case ZOOM_TASK_PACKAGE:
ret = send_package(c);
+ break;
+ case ZOOM_TASK_SORT:
+ c->tasks->u.sort.resultset->r_sort_spec =
+ c->tasks->u.sort.q->sort_spec;
+ ret = send_sort(c, c->tasks->u.sort.resultset);
break;
}
}
static zoom_ret send_sort_present (ZOOM_connection c)
{
- zoom_ret r = send_sort (c);
+ zoom_ret r = zoom_complete;
+
+ if (c->tasks && c->tasks->which == ZOOM_TASK_SEARCH)
+ r = send_sort (c, c->tasks->u.search.resultset);
if (r == zoom_complete)
r = send_present (c);
return r;
}
if (res->num_diagnostics > 0)
{
- set_dset_error(c, *res->diagnostics[0].code, "SRW",
- res->diagnostics[0].details, 0);
+ const char *uri = res->diagnostics[0].uri;
+ if (uri)
+ {
+ int code = 0;
+ const char *cp;
+ if ((cp = strrchr(uri, '/')))
+ code = atoi(cp+1);
+ set_dset_error(c, code, uri,
+ res->diagnostics[0].details, 0);
+ }
}
nmem = odr_extract_mem(c->odr_in);
nmem_transfer(resultset->odr->mem, nmem);
ZOOM_API(void)
ZOOM_connection_option_set (ZOOM_connection c, const char *key,
- const char *val)
+ const char *val)
{
ZOOM_options_set (c->options, key, val);
}
+ZOOM_API(void)
+ZOOM_connection_option_setl (ZOOM_connection c, const char *key,
+ const char *val, int len)
+{
+ ZOOM_options_setl (c->options, key, val, len);
+}
+
ZOOM_API(const char *)
ZOOM_resultset_option_get (ZOOM_resultset r, const char *key)
{
return "Unsupported protocol";
case ZOOM_ERROR_UNSUPPORTED_QUERY:
return "Unsupported query type";
+ case ZOOM_ERROR_INVALID_QUERY:
+ return "Invalid query";
default:
return diagbib1_str (error);
}
*cp = z_HTTP_errmsg(c->error);
else if (!strcmp(c->diagset, "Bib-1"))
*cp = ZOOM_diag_str(error);
- else if (!strcmp(c->diagset, "SRW"))
+ else if (!strcmp(c->diagset, "info:srw/diagnostic/1"))
*cp = yaz_diag_srw_str(c->error);
else
*cp = "Unknown error and diagnostic set";
else if (ret == 0)
{
ZOOM_connection_put_event (c, event);
+ get_cert(c);
if (c->proto == PROTO_Z3950)
ZOOM_connection_send_init(c);
else