+
+ 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_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML)
+ sr->u.explain_request->recordPacking = "xml";
+ return send_srw(sr);
+}
+#endif
+
+static int send_searchRequest(const char *arg)
+{
+ Z_APDU *apdu = zget_APDU(out, Z_APDU_searchRequest);
+ Z_SearchRequest *req = apdu->u.searchRequest;
+ Z_Query query;
+ struct ccl_rpn_node *rpn = NULL;
+ int error, pos;
+ char setstring[100];
+ Z_RPNQuery *RPNquery;
+ Odr_oct ccl_query;
+ YAZ_PQF_Parser pqf_parser;
+ Z_External *ext;
+ QueryType myQueryType = queryType;
+ char pqfbuf[512];
+
+ if (myQueryType == QueryType_CCL2RPN)
+ {
+ rpn = ccl_find_str(bibset, arg, &error, &pos);
+ if (error)
+ {
+ printf("CCL ERROR: %s\n", ccl_err_msg(error));
+ return 0;
+ }
+ } else if (myQueryType == QueryType_CQL2RPN) {
+ /* ### All this code should be wrapped in a utility function */
+ CQL_parser parser;
+ struct cql_node *node;
+ const char *addinfo;
+ if (cqltrans == 0) {
+ printf("Can't use CQL: no translation file. Try set_cqlfile\n");
+ return 0;
+ }
+ parser = cql_parser_create();
+ if ((error = cql_parser_string(parser, arg)) != 0) {
+ printf("Can't parse CQL: must be a syntax error\n");
+ return 0;
+ }
+ node = cql_parser_result(parser);
+ if ((error = cql_transform_buf(cqltrans, node, pqfbuf,
+ sizeof pqfbuf)) != 0) {
+ error = cql_transform_error(cqltrans, &addinfo);
+ printf ("Can't convert CQL to PQF: %s (addinfo=%s)\n",
+ cql_strerror(error), addinfo);
+ return 0;
+ }
+ arg = pqfbuf;
+ myQueryType = QueryType_Prefix;
+ }
+
+ req->referenceId = set_refid (out);
+ if (!strcmp(arg, "@big")) /* strictly for troublemaking */