X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fzoom-c.c;h=6078c932dd2bf7bc7b7895e31106af344d7c1a7b;hb=317ee76a1bbe9de384aea464c829b8ad627518a2;hp=9acc7c7492a28fb88c12bf8a7b93364742fbecd3;hpb=b0940b7daa836cd50ed2be23d539fec9de602c89;p=yaz-moved-to-github.git diff --git a/src/zoom-c.c b/src/zoom-c.c index 9acc7c7..6078c93 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 2000-2003, Index Data + * Copyright (c) 2000-2004, Index Data * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.10 2003-12-04 12:57:30 adam Exp $ + * $Id: zoom-c.c,v 1.24 2004-02-14 15:58:42 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); @@ -219,6 +227,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 +431,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 +483,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); @@ -895,9 +908,13 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c) 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, "pass"); + 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); @@ -918,7 +935,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.10 $"); + version = odr_strdup(c->odr_out, "$Revision: 1.24 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; ireq->implementationVersion = odr_prepend(c->odr_out, @@ -1004,7 +1021,7 @@ static zoom_ret send_srw (ZOOM_connection c, Z_SRW_PDU *sr) { char ctype[50]; Z_SOAP_Handler h[2] = { - {"http://www.loc.gov/zing/srw/v1.0/", 0, (Z_SOAP_fun) yaz_srw_codec}, + {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; ODR o = odr_createmem(ODR_ENCODE); @@ -1188,6 +1205,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); @@ -1359,6 +1381,62 @@ ZOOM_record_destroy (ZOOM_record rec) xfree (rec); } +static const char *marc_iconv_return(ZOOM_record rec, int marc_type, + int *len, + const char *buf, int sz, + const char *record_charset) +{ + char to[40]; + char from[40]; + yaz_iconv_t cd = 0; + yaz_marc_t mt = yaz_marc_create(); + + *from = '\0'; + strcpy(to, "UTF-8"); + if (record_charset && *record_charset) + { + /* Use "from,to" or just "from" */ + const char *cp =strchr(record_charset, ','); + int clen = strlen(record_charset); + if (cp && cp[1]) + { + strncpy( to, cp+1, sizeof(to)-1); + to[sizeof(to)-1] = '\0'; + clen = cp - record_charset; + } + if (clen > sizeof(from)-1) + clen = sizeof(from)-1; + + if (clen) + strncpy(from, record_charset, clen); + from[clen] = '\0'; + } + + if (*from && *to) + { + cd = yaz_iconv_open(to, from); + yaz_marc_iconv(mt, cd); + } + + yaz_marc_xml(mt, marc_type); + if (!rec->wrbuf_marc) + rec->wrbuf_marc = wrbuf_alloc(); + wrbuf_rewind (rec->wrbuf_marc); + if (yaz_marc_decode_wrbuf (mt, buf, sz, rec->wrbuf_marc) > 0) + { + yaz_marc_destroy(mt); + if (cd) + yaz_iconv_close(cd); + if (len) + *len = wrbuf_len(rec->wrbuf_marc); + return wrbuf_buf(rec->wrbuf_marc); + } + yaz_marc_destroy(mt); + if (cd) + yaz_iconv_close(cd); + return 0; +} + static const char *record_iconv_return(ZOOM_record rec, int *len, const char *buf, int sz, const char *record_charset) @@ -1429,6 +1507,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) { char type[40]; char charset[40]; + char xpath[512]; const char *cp; int i; Z_NamePlusRecord *npr; @@ -1451,7 +1530,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) } type[i] = '\0'; charset[0] = '\0'; - if (type_spec[i] == ';') + while (type_spec[i] == ';') { i++; while (type_spec[i] == ' ') @@ -1467,8 +1546,16 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) } charset[i] = '\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'; + } + while (type_spec[i] == ' ') + i++; + } if (!strcmp (type, "database")) { if (len) @@ -1514,7 +1601,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) charset); else if (r->which == Z_External_octet) { - yaz_marc_t mt; + const char *ret_buf; switch (ent->value) { case VAL_SOIF: @@ -1525,23 +1612,13 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) case VAL_APPLICATION_XML: break; default: - if (!rec->wrbuf_marc) - rec->wrbuf_marc = wrbuf_alloc(); - - mt = yaz_marc_create(); - wrbuf_rewind (rec->wrbuf_marc); - if (yaz_marc_decode_wrbuf ( - mt, (const char *) r->u.octet_aligned->buf, - r->u.octet_aligned->len, - rec->wrbuf_marc) > 0) - { - yaz_marc_destroy(mt); - return record_iconv_return(rec, len, - wrbuf_buf(rec->wrbuf_marc), - wrbuf_len(rec->wrbuf_marc), - charset); - } - yaz_marc_destroy(mt); + ret_buf = marc_iconv_return( + rec, YAZ_MARC_LINE, len, + (const char *) r->u.octet_aligned->buf, + r->u.octet_aligned->len, + charset); + if (ret_buf) + return ret_buf; } return record_iconv_return(rec, len, (const char *) r->u.octet_aligned->buf, @@ -1582,7 +1659,7 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) charset); else if (r->which == Z_External_octet) { - yaz_marc_t mt; + const char *ret_buf; int marc_decode_type = YAZ_MARC_MARCXML; if (!strcmp(type, "oai")) @@ -1597,24 +1674,13 @@ ZOOM_record_get (ZOOM_record rec, const char *type_spec, int *len) case VAL_APPLICATION_XML: break; default: - if (!rec->wrbuf_marc) - rec->wrbuf_marc = wrbuf_alloc(); - wrbuf_rewind (rec->wrbuf_marc); - mt = yaz_marc_create(); - - yaz_marc_xml(mt, YAZ_MARC_MARCXML); - if (yaz_marc_decode_wrbuf ( - mt, (const char *) r->u.octet_aligned->buf, - r->u.octet_aligned->len, - rec->wrbuf_marc) > 0) - { - yaz_marc_destroy(mt); - return record_iconv_return(rec, len, - wrbuf_buf(rec->wrbuf_marc), - wrbuf_len(rec->wrbuf_marc), - charset); - } - yaz_marc_destroy(mt); + ret_buf = marc_iconv_return( + rec, marc_decode_type, len, + (const char *) r->u.octet_aligned->buf, + r->u.octet_aligned->len, + charset); + if (ret_buf) + return ret_buf; } return record_iconv_return(rec, len, (const char *) r->u.octet_aligned->buf, @@ -2176,7 +2242,7 @@ ZOOM_scanset_display_term (ZOOM_scanset scan, size_t pos, if (t->displayTerm) { - term = (const char *) t->term->u.general->buf; + term = t->displayTerm; *len = strlen(term); } else if (t->term->which == Z_Term_general) @@ -2405,7 +2471,8 @@ static Z_APDU *create_update_package(ZOOM_package p) int num_db; char **db = set_DatabaseNames(p->connection, p->options, &num_db); const char *action = ZOOM_options_get(p->options, "action"); - const char *recordId = ZOOM_options_get(p->options, "recordId"); + const char *recordIdOpaque = ZOOM_options_get(p->options, "recordIdOpaque"); + const char *recordIdNumber = ZOOM_options_get(p->options, "recordIdNumber"); const char *record_buf = ZOOM_options_get(p->options, "record"); const char *syntax_str = ZOOM_options_get(p->options, "syntax"); int syntax_oid = VAL_NONE; @@ -2481,14 +2548,21 @@ static Z_APDU *create_update_package(ZOOM_package p) notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *) odr_malloc(p->odr_out, sizeof(**notToKeep->elements)); notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; - if (recordId) + if (recordIdOpaque) { notToKeep->elements[0]->u.opaque = (Odr_oct *) odr_malloc (p->odr_out, sizeof(Odr_oct)); - notToKeep->elements[0]->u.opaque->size = strlen(recordId); - notToKeep->elements[0]->u.opaque->len = strlen(recordId); + notToKeep->elements[0]->u.opaque->size = + notToKeep->elements[0]->u.opaque->len = strlen(recordIdOpaque); notToKeep->elements[0]->u.opaque->buf = - odr_strdup(p->odr_out, recordId); + odr_strdup(p->odr_out, recordIdOpaque); + } + else if (recordIdNumber) + { + notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_number; + + notToKeep->elements[0]->u.number = + odr_intdup(p->odr_out, atoi(recordIdNumber)); } else notToKeep->elements[0]->u.opaque = 0; @@ -2893,8 +2967,16 @@ static void handle_srw_response(ZOOM_connection c, } 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); @@ -2916,9 +2998,9 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) if (content_type && !yaz_strcmp_del("text/xml", content_type, "; ")) { Z_SOAP *soap_package = 0; - ODR o = odr_createmem(ODR_DECODE); + ODR o = c->odr_in; Z_SOAP_Handler soap_handlers[2] = { - {"http://www.loc.gov/zing/srw/v1.0/", 0, + {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; @@ -2943,7 +3025,6 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) } else ret = -1; - odr_destroy(o); } if (ret) { @@ -3161,6 +3242,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); } @@ -3179,7 +3262,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";