X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-c.c;h=05371beab4b6b7c0075757f3da80c1d8ce7931a6;hp=c01ccb83fd3c4f69749ba1c0af7d0a76e37ec620;hb=29c6ebfc19c403aa99c7f462d2b36f056ffd4dbc;hpb=7e318eefe6a4dd4906261feb766cae881352ba07 diff --git a/src/zoom-c.c b/src/zoom-c.c index c01ccb8..05371be 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.72 2006-05-10 07:34:38 adam Exp $ + * $Id: zoom-c.c,v 1.76 2006-06-13 16:27:23 mike Exp $ */ /** * \file zoom-c.c @@ -25,6 +25,7 @@ #include #include #include +#include #if HAVE_SYS_TYPES_H #include @@ -53,6 +54,7 @@ typedef enum { static zoom_ret ZOOM_connection_send_init (ZOOM_connection c); static zoom_ret do_write_ex (ZOOM_connection c, char *buf_out, int len_out); static char *cql2pqf(ZOOM_connection c, const char *cql); +static char *ccl2pqf(ZOOM_connection c, const char *ccl); static void initlog() { @@ -576,6 +578,29 @@ ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn) return ret; } +/* + * Analogous in every way to ZOOM_query_cql2rpn(), except that there + * is no analogous ZOOM_query_ccl() that just sends uninterpreted CCL + * to the server, as the YAZ GFS doesn't know how to handle this. + */ +ZOOM_API(int) +ZOOM_query_ccl2rpn(ZOOM_query s, const char *str, ZOOM_connection conn) +{ + char *rpn; + int ret; + + yaz_log(log_details, "%p ZOOM_query_ccl2rpn str=%s conn=%p", s, str, conn); + if (conn == 0) + conn = ZOOM_connection_create(0); + + if ((rpn = ccl2pqf(conn, str)) == 0) + return -1; + + ret = ZOOM_query_prefix(s, rpn); + xfree(rpn); + return ret; +} + ZOOM_API(int) ZOOM_query_sortby(ZOOM_query s, const char *criteria) { @@ -1155,7 +1180,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.72 $"); + version = odr_strdup(c->odr_out, "$Revision: 1.76 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; ireq->implementationVersion = odr_prepend(c->odr_out, @@ -1236,41 +1261,10 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c) #if HAVE_XML2 static zoom_ret send_srw (ZOOM_connection c, Z_SRW_PDU *sr) { - Z_SOAP_Handler h[2] = { - {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, - {0, 0, 0} - }; - ODR o = odr_createmem(ODR_ENCODE); - int ret; - Z_SOAP *p = (Z_SOAP*) odr_malloc(o, sizeof(*p)); Z_GDU *gdu; ZOOM_Event event; - gdu = z_get_HTTP_Request(c->odr_out); - gdu->u.HTTP_Request->path = c->path; - - if (c->host_port) - { - const char *cp0 = strstr(c->host_port, "://"); - const char *cp1 = 0; - if (cp0) - cp0 = cp0+3; - else - cp0 = c->host_port; - - cp1 = strchr(cp0, '/'); - if (!cp1) - cp1 = cp0+strlen(cp0); - - if (cp0 && cp1) - { - char *h = (char*) odr_malloc(c->odr_out, cp1 - cp0 + 1); - memcpy (h, cp0, cp1 - cp0); - h[cp1-cp0] = '\0'; - z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, - "Host", h); - } - } + gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port, c->path); if (c->sru_mode == zoom_sru_get) { @@ -1282,29 +1276,11 @@ static zoom_ret send_srw (ZOOM_connection c, Z_SRW_PDU *sr) } else if (c->sru_mode == zoom_sru_soap) { - z_HTTP_header_add_content_type(c->odr_out, - &gdu->u.HTTP_Request->headers, - "text/xml", c->charset); - - z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, - "SOAPAction", "\"\""); - p->which = Z_SOAP_generic; - p->u.generic = (Z_SOAP_Generic *) odr_malloc(o, sizeof(*p->u.generic)); - p->u.generic->no = 0; - p->u.generic->ns = 0; - p->u.generic->p = sr; - p->ns = "http://schemas.xmlsoap.org/soap/envelope/"; - - ret = z_soap_codec_enc(o, &p, - &gdu->u.HTTP_Request->content_buf, - &gdu->u.HTTP_Request->content_len, h, - c->charset); - + yaz_sru_post_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset); } if (!z_GDU(c->odr_out, &gdu, 0, 0)) return zoom_complete; c->buf_out = odr_getbuf(c->odr_out, &c->len_out, 0); - odr_destroy(o); event = ZOOM_Event_create (ZOOM_EVENT_SEND_APDU); ZOOM_connection_put_event (c, event); @@ -2489,12 +2465,11 @@ ZOOM_connection_scan1 (ZOOM_connection c, ZOOM_query q) /* * We need to check the query-type, so we can recognise CQL and - * compile it into a form that we can use here. The ZOOM_query - * structure has no explicit `type' member, but inspection of the - * ZOOM_query_prefix() and ZOOM_query_cql() functions shows how - * the structure is set up in each case. + * CCL and compile them into a form that we can use here. The + * ZOOM_query structure has no explicit `type' member, but + * inspection of the ZOOM_query_prefix() and ZOOM_query_cql() + * functions shows how the structure is set up in each case. */ - if (q->z_query->which == Z_Query_type_1) { yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p PQF '%s'", c, q, q->query_string); @@ -2505,6 +2480,12 @@ ZOOM_connection_scan1 (ZOOM_connection c, ZOOM_query q) start = freeme = cql2pqf(c, q->query_string); if (start == 0) return 0; + } else if (q->z_query->which == Z_Query_type_2) { + yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p CCL '%s'", + c, q, q->query_string); + start = freeme = ccl2pqf(c, q->query_string); + if (start == 0) + return 0; } else { yaz_log(YLOG_FATAL, "%p ZOOM_connection_scan1 q=%p unknown type '%s'", c, q, q->query_string); @@ -2556,8 +2537,10 @@ static zoom_ret send_package (ZOOM_connection c) event = ZOOM_Event_create (ZOOM_EVENT_SEND_APDU); ZOOM_connection_put_event (c, event); - return do_write_ex (c, c->tasks->u.package->buf_out, - c->tasks->u.package->len_out); + c->buf_out = c->tasks->u.package->buf_out; + c->len_out = c->tasks->u.package->len_out; + + return do_write(c); } static zoom_ret send_scan (ZOOM_connection c) @@ -3764,6 +3747,10 @@ ZOOM_diag_str (int error) return "CQL parsing error"; case ZOOM_ERROR_CQL_TRANSFORM: return "CQL transformation error"; + case ZOOM_ERROR_CCL_CONFIG: + return "CCL configuration error"; + case ZOOM_ERROR_CCL_PARSE: + return "CCL parsing error"; default: return diagbib1_str (error); } @@ -4120,6 +4107,50 @@ static char *cql2pqf(ZOOM_connection c, const char *cql) } +/* ### Could cache `bibset' */ +static char *ccl2pqf(ZOOM_connection c, const char *ccl) +{ + const char *cclfile; + CCL_bibset bibset; + struct ccl_rpn_node *node; + int errorcode; + int errorpos; + WRBUF w; + char *pqf; + + if ((cclfile = ZOOM_connection_option_get(c, "cclfile")) == 0) { + set_ZOOM_error(c, ZOOM_ERROR_CCL_CONFIG, "no CCL qualifier file"); + return 0; + } + + bibset = ccl_qual_mk(); + if (ccl_qual_fname(bibset, cclfile) < 0) { + char buf[512]; + ccl_qual_rm(&bibset); + sprintf(buf, "can't open CCL qualifier file '%.200s': %.200s", + cclfile, strerror(errno)); + set_ZOOM_error(c, ZOOM_ERROR_CCL_CONFIG, buf); + return 0; + } + + node = ccl_find_str (bibset, ccl, &errorcode, &errorpos); + ccl_qual_rm(&bibset); + if (node == 0) { + /* code is one of the CCL_ERR_* constants; pos is unused here */ + set_ZOOM_error(c, ZOOM_ERROR_CCL_PARSE, ccl_err_msg(errorcode)); + return 0; + } + + w = wrbuf_alloc(); + ccl_pquery(w, node); + ccl_rpn_delete(node); + pqf = xstrdup(wrbuf_buf(w)); + wrbuf_free(w, 1); + + return pqf; +} + + /* * Local variables: * c-basic-offset: 4