X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fzoom-c.c;h=9496fb5f2f2556a09cfc75b63c1fe035b0f20f14;hb=719e0dcf2d15c08086a06457701e21c6aff3d791;hp=e161888d164b0111897ab80efe10ed554ffb2886;hpb=163abf332e441c2d39cf6ee4e83bad169fa1c59c;p=yaz-moved-to-github.git diff --git a/src/zoom-c.c b/src/zoom-c.c index e161888..9496fb5 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004, Index Data * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.21 2004-01-27 12:15:12 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. */ @@ -90,10 +90,18 @@ static void set_dset_error (ZOOM_connection c, int error, 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); @@ -177,7 +185,6 @@ void ZOOM_connection_remove_task (ZOOM_connection c) switch (task->which) { case ZOOM_TASK_SEARCH: - ZOOM_resultset_destroy (task->u.search.resultset); break; case ZOOM_TASK_RETRIEVE: @@ -191,6 +198,10 @@ void ZOOM_connection_remove_task (ZOOM_connection c) 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); } @@ -219,6 +230,7 @@ ZOOM_connection_create (ZOOM_options options) 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; @@ -422,7 +434,10 @@ ZOOM_query_prefix(ZOOM_query s, const char *str) 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; } @@ -471,6 +486,7 @@ ZOOM_connection_destroy(ZOOM_connection c) 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); @@ -495,6 +511,7 @@ void ZOOM_resultset_addref (ZOOM_resultset r) r, r->refcount); } } + ZOOM_resultset ZOOM_resultset_create () { ZOOM_resultset r = (ZOOM_resultset) xmalloc (sizeof(*r)); @@ -592,6 +609,62 @@ ZOOM_connection_search(ZOOM_connection c, ZOOM_query q) } 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) @@ -601,17 +674,8 @@ ZOOM_resultset_destroy(ZOOM_resultset 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 */ @@ -718,6 +782,19 @@ ZOOM_resultset_records (ZOOM_resultset r, ZOOM_record *recs, } } +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; @@ -730,7 +807,8 @@ static zoom_ret do_connect (ZOOM_connection c) 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) @@ -757,6 +835,7 @@ static zoom_ret do_connect (ZOOM_connection c) { 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 @@ -922,7 +1001,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.21 $"); + 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, @@ -1192,6 +1271,11 @@ static zoom_ret ZOOM_connection_send_search (ZOOM_connection c) /* 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); @@ -1519,21 +1603,23 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) 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++; @@ -1931,20 +2017,11 @@ static int scan_response (ZOOM_connection c, Z_ScanResponse *res) 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); @@ -2722,6 +2799,11 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) 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; } } @@ -2742,7 +2824,10 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) 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; @@ -2949,20 +3034,16 @@ static void handle_srw_response(ZOOM_connection c, } if (res->num_diagnostics > 0) { - const char *std_diag = "info:srw/diagnostic/1/1/"; - const char *code = res->diagnostics[0].code; - const char *cp; - const char *category = code; - int code_int = 0; - - if (code && (cp = strrchr(code, '/'))) - code_int = atoi(cp+1); - if (code && !strncmp(code, std_diag, strlen(std_diag))) - category = "SRW"; - - if (category) - set_dset_error(c, code_int, category, + 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); @@ -3160,11 +3241,18 @@ ZOOM_connection_option_get (ZOOM_connection c, const char *key) 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) { @@ -3228,6 +3316,8 @@ ZOOM_diag_str (int error) 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); } @@ -3246,7 +3336,7 @@ ZOOM_connection_error_x (ZOOM_connection c, const char **cp, *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"; @@ -3298,6 +3388,7 @@ static int ZOOM_connection_do_io(ZOOM_connection c, int mask) else if (ret == 0) { ZOOM_connection_put_event (c, event); + get_cert(c); if (c->proto == PROTO_Z3950) ZOOM_connection_send_init(c); else