+#if HAVE_XML2
+static int send_srw(Z_SRW_PDU *sr)
+{
+ const char *charset = negotiationCharset;
+ const char *host_port = cur_host;
+ char *path = 0;
+ char ctype[50];
+ 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 = odr_malloc(o, sizeof(*p));
+ Z_GDU *gdu;
+
+ path = odr_malloc(out, strlen(databaseNames[0])+2);
+ *path = '/';
+ strcpy(path+1, databaseNames[0]);
+
+ gdu = z_get_HTTP_Request(out);
+ gdu->u.HTTP_Request->version = http_version;
+ gdu->u.HTTP_Request->path = odr_strdup(out, path);
+
+ if (host_port)
+ {
+ const char *cp0 = strstr(host_port, "://");
+ const char *cp1 = 0;
+ if (cp0)
+ cp0 = cp0+3;
+ else
+ cp0 = host_port;
+
+ cp1 = strchr(cp0, '/');
+ if (!cp1)
+ cp1 = cp0+strlen(cp0);
+
+ if (cp0 && cp1)
+ {
+ char *h = odr_malloc(out, cp1 - cp0 + 1);
+ memcpy (h, cp0, cp1 - cp0);
+ h[cp1-cp0] = '\0';
+ z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers,
+ "Host", h);
+ }
+ }
+
+ strcpy(ctype, "text/xml");
+ if (charset && strlen(charset) < 20)
+ {
+ strcat(ctype, "; charset=");
+ strcat(ctype, charset);
+ }
+ z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers,
+ "Content-Type", ctype);
+ z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers,
+ "SOAPAction", "\"\"");
+ p->which = Z_SOAP_generic;
+ p->u.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,
+ charset);
+
+ if (z_GDU(out, &gdu, 0, 0))
+ {
+ /* encode OK */
+ char *buf_out;
+ int len_out;
+ int r;
+ if (apdu_file)
+ {
+ if (!z_GDU(print, &gdu, 0, 0))
+ printf ("Failed to print outgoing APDU\n");
+ odr_reset(print);
+ }
+ buf_out = odr_getbuf(out, &len_out, 0);
+
+ /* we don't odr_reset(out), since we may need the buffer again */
+
+ do_hex_dump(buf_out, len_out);
+
+ r = cs_put(conn, buf_out, len_out);
+
+ odr_destroy(o);
+
+ if (r >= 0)
+ return 2;
+ }
+ return 0;
+}
+#endif
+
+#if HAVE_XML2
+static char *encode_SRW_term(ODR o, const char *q)
+{
+ const char *in_charset = "ISO-8859-1";
+ WRBUF w = wrbuf_alloc();
+ yaz_iconv_t cd;
+ char *res;
+ if (outputCharset)
+ in_charset = outputCharset;
+ cd = yaz_iconv_open("UTF-8", in_charset);
+ if (!cd)
+ {
+ wrbuf_free(w, 1);
+ return odr_strdup(o, q);
+ }
+ wrbuf_iconv_write(w, cd, q, strlen(q));
+ if (wrbuf_len(w))
+ {
+ int len = wrbuf_len(w);
+ res = odr_strdupn(o, wrbuf_buf(w), len);
+ }
+ else
+ res = odr_strdup(o, q);
+ yaz_iconv_close(cd);
+ wrbuf_free(w, 1);
+ return res;
+}
+
+
+static int send_SRW_scanRequest(const char *arg, int pos, int num)
+{
+ Z_SRW_PDU *sr = 0;
+
+ /* regular requestse .. */
+ sr = yaz_srw_get(out, Z_SRW_scan_request);
+
+ switch(queryType)
+ {
+ case QueryType_CQL:
+ sr->u.scan_request->query_type = Z_SRW_query_type_cql;
+ sr->u.scan_request->scanClause.cql = encode_SRW_term(out, arg);
+ break;
+ case QueryType_Prefix:
+ sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
+ sr->u.scan_request->scanClause.pqf = encode_SRW_term(out, arg);
+ break;
+ default:
+ printf ("Only CQL and PQF supported in SRW\n");
+ return 0;
+ }
+ sr->u.scan_request->responsePosition = odr_intdup(out, pos);
+ sr->u.scan_request->maximumTerms = odr_intdup(out, num);
+ return send_srw(sr);
+}
+
+static int send_SRW_searchRequest(const char *arg)
+{
+ Z_SRW_PDU *sr = 0;
+
+ if (!srw_sr)
+ {
+ assert(srw_sr_odr_out == 0);
+ srw_sr_odr_out = odr_createmem(ODR_ENCODE);
+ }
+ odr_reset(srw_sr_odr_out);
+
+ setno = 1;
+
+ /* save this for later .. when fetching individual records */
+ srw_sr = yaz_srw_get(srw_sr_odr_out, Z_SRW_searchRetrieve_request);
+
+ /* regular request .. */
+ sr = yaz_srw_get(out, Z_SRW_searchRetrieve_request);
+
+ switch(queryType)
+ {
+ case QueryType_CQL:
+ srw_sr->u.request->query_type = Z_SRW_query_type_cql;
+ srw_sr->u.request->query.cql = encode_SRW_term(srw_sr_odr_out, arg);
+
+ sr->u.request->query_type = Z_SRW_query_type_cql;
+ sr->u.request->query.cql = encode_SRW_term(srw_sr_odr_out, arg);
+ break;
+ case QueryType_Prefix:
+ srw_sr->u.request->query_type = Z_SRW_query_type_pqf;
+ srw_sr->u.request->query.pqf = encode_SRW_term(srw_sr_odr_out, arg);
+
+ sr->u.request->query_type = Z_SRW_query_type_pqf;
+ sr->u.request->query.pqf = encode_SRW_term(srw_sr_odr_out, arg);
+ break;
+ default:
+ printf ("Only CQL and PQF supported in SRW\n");
+ return 0;
+ }
+ sr->u.request->maximumRecords = odr_intdup(out, 0);
+
+ if (record_schema)
+ sr->u.request->recordSchema = record_schema;
+ if (recordsyntax == VAL_TEXT_XML)
+ sr->u.explain_request->recordPacking = "xml";
+ return send_srw(sr);
+}
+#endif
+
+static int send_searchRequest(const char *arg)