X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=client%2Fclient.c;h=7a782d0a2fe3095aeba7cfb8592e82354b2479ca;hp=8385a5bea7637f2b2152cce992e79cf80773538f;hb=1349cb3d913df6ec4fad5d5f185de8fec01b835e;hpb=9a83c08e1f5eca156f911f71189590b2d436a723 diff --git a/client/client.c b/client/client.c index 8385a5b..7a782d0 100644 --- a/client/client.c +++ b/client/client.c @@ -1,5 +1,5 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2013 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ /** \file client.c @@ -44,7 +44,7 @@ #endif #include - +#include #include #include @@ -64,6 +64,7 @@ #include #include #include +#include #if HAVE_READLINE_READLINE_H #include @@ -145,10 +146,11 @@ static int z3950_version = 3; static int scan_stepSize = 0; static char scan_position[64]; static int scan_size = 20; -static char cur_host[200]; +static WRBUF cur_host = 0; static Odr_int last_hit_count = 0; static int pretty_xml = 0; static Odr_int sru_maximumRecords = 0; +static yaz_cookies_t yaz_cookies = 0; typedef enum { QueryType_Prefix, @@ -543,7 +545,7 @@ static void render_diag(Z_DiagnosticFormat *diag) Z_DefaultDiagFormat *dd = ds->u.defaultDiagRec; /* ### should check `dd->diagnosticSetId' */ printf("code=" ODR_INT_PRINTF " (%s)", *dd->condition, - diagbib1_str(*dd->condition)); + diagbib1_str((int) *dd->condition)); /* Both types of addinfo are the same, so use type-pun */ if (dd->u.v2Addinfo != 0) printf(",\n\taddinfo='%s'", dd->u.v2Addinfo); @@ -737,12 +739,15 @@ static int session_connect_base(const char *arg, const char **basep) return 0; } -static int session_connect(const char *arg) +static int session_connect(void) { int r; const char *basep = 0; - r = session_connect_base(arg, &basep); + yaz_cookies_destroy(yaz_cookies); + yaz_cookies = yaz_cookies_create(); + + r = session_connect_base(wrbuf_cstr(cur_host), &basep); if (basep && *basep) set_base(basep); else if (protocol == PROTO_Z3950) @@ -755,15 +760,16 @@ static int cmd_open(const char *arg) int r; if (arg) { - strncpy(cur_host, arg, sizeof(cur_host)-1); - cur_host[sizeof(cur_host)-1] = 0; + wrbuf_rewind(cur_host); + if (!strstr(arg, "://") && strcmp(sru_method, "soap")) + wrbuf_puts(cur_host, "http://"); + wrbuf_puts(cur_host, arg); } set_base(""); - r = session_connect(cur_host); + r = session_connect(); if (conn && conn->protocol == PROTO_HTTP) queryType = QueryType_CQL; - return r; } @@ -1197,7 +1203,7 @@ static void display_diagrecs(Z_DiagRec **pp, int num) printf("Unknown diagset: %s\n", diag_name); } printf(" [" ODR_INT_PRINTF "] %s", - *r->condition, diagbib1_str(*r->condition)); + *r->condition, diagbib1_str((int) *r->condition)); switch (r->which) { case Z_DefaultDiagFormat_v2Addinfo: @@ -1314,7 +1320,7 @@ static int send_srw_host_path(Z_SRW_PDU *sr, const char *host_port, const char *charset = negotiationCharset; Z_GDU *gdu; - gdu = z_get_HTTP_Request_host_path(out, host_port, path); + gdu = z_get_HTTP_Request_uri(out, host_port, path, yazProxy ? 1 : 0); if (auth) { @@ -1358,46 +1364,20 @@ static int send_srw_host_path(Z_SRW_PDU *sr, const char *host_port, static int send_srw(Z_SRW_PDU *sr) { char *path = yaz_encode_sru_dbpath_odr(out, databaseNames[0]); - return send_srw_host_path(sr, cur_host, path); + return send_srw_host_path(sr, wrbuf_cstr(cur_host), path); } -static int send_SRW_redirect(const char *uri, Z_HTTP_Response *cookie_hres) +static int send_SRW_redirect(const char *uri) { const char *username = 0; const char *password = 0; - struct Z_HTTP_Header *h; - char *combined_cookies = 0; - int combined_cookies_len = 0; Z_GDU *gdu = get_HTTP_Request_url(out, uri); gdu->u.HTTP_Request->method = odr_strdup(out, "GET"); z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, "Accept", "text/xml"); - for (h = cookie_hres->headers; h; h = h->next) - { - if (!strcmp(h->name, "Set-Cookie")) - { - char *cp; - - if (!(cp = strchr(h->value, ';'))) - cp = h->value + strlen(h->value); - if (cp - h->value >= 1) - { - combined_cookies = xrealloc(combined_cookies, combined_cookies_len + cp - h->value + 3); - memcpy(combined_cookies+combined_cookies_len, h->value, cp - h->value); - combined_cookies[combined_cookies_len + cp - h->value] = '\0'; - strcat(combined_cookies,"; "); - combined_cookies_len = strlen(combined_cookies); - } - } - } - if (combined_cookies_len) - { - z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, "Cookie", combined_cookies); - xfree(combined_cookies); - } - + yaz_cookies_request(yaz_cookies, out, gdu->u.HTTP_Request); if (auth) { if (auth->which == Z_IdAuthentication_open) @@ -2408,7 +2388,7 @@ static int send_SRW_update(int action_no, const char *recid, char *rec_buf, int rec_len) { if (!conn) - session_connect(cur_host); + session_connect(); if (!conn) return 0; else @@ -2670,7 +2650,7 @@ static int cmd_explain(const char *arg) return 0; #if YAZ_HAVE_XML2 if (!conn) - session_connect(cur_host); + session_connect(); if (conn) { Z_SRW_PDU *sr = 0; @@ -2693,12 +2673,14 @@ static int cmd_init(const char *arg) { if (*arg) { - strncpy(cur_host, arg, sizeof(cur_host)-1); - cur_host[sizeof(cur_host)-1] = 0; + wrbuf_rewind(cur_host); + if (!strstr(arg, "://") && strcmp(sru_method, "soap")) + wrbuf_puts(cur_host, "http://"); + wrbuf_puts(cur_host, arg); } if (only_z3950()) return 1; - send_Z3950_initRequest(cur_host); + send_Z3950_initRequest(wrbuf_cstr(cur_host)); return 2; } @@ -2869,7 +2851,7 @@ static int cmd_find(const char *arg) { #if YAZ_HAVE_XML2 if (!conn) - session_connect(cur_host); + session_connect(); if (!conn) return 0; if (!send_SRW_searchRequest(arg)) @@ -2880,7 +2862,7 @@ static int cmd_find(const char *arg) } else { - if (*cur_host && auto_reconnect) + if (wrbuf_len(cur_host) && auto_reconnect) { int i = 0; for (;;) @@ -2898,7 +2880,7 @@ static int cmd_find(const char *arg) printf("Unable to reconnect\n"); break; } - session_connect(cur_host); + session_connect(); wait_and_handle_response(0); } return 0; @@ -3241,7 +3223,7 @@ static int cmd_show(const char *arg) { #if YAZ_HAVE_XML2 if (!conn) - session_connect(cur_host); + session_connect(); if (!conn) return 0; if (!send_SRW_presentRequest(arg)) @@ -3265,9 +3247,15 @@ static int cmd_show(const char *arg) static void exit_client(int code) { + odr_destroy(in); + odr_destroy(out); + odr_destroy(print); + ccl_qual_rm(&bibset); + yaz_cookies_destroy(yaz_cookies); file_history_save(file_history); file_history_destroy(&file_history); nmem_destroy(nmem_auth); + wrbuf_destroy(cur_host); exit(code); } @@ -3490,7 +3478,7 @@ static void process_Z3950_scanResponse(Z_ScanResponse *res) num_entries = res->entries->num_entries; for (i = 0; i < num_entries; i++) { - int pos_term = res->positionOfTerm ? *res->positionOfTerm : -1; + Odr_int pos_term = res->positionOfTerm ? *res->positionOfTerm : -1; if (entries[i]->which == Z_Entry_termInfo) { printf("%c ", i + 1 == pos_term ? '*' : ' '); @@ -3629,7 +3617,7 @@ static int cmd_scan_common(const char *set, const char *arg) { #if YAZ_HAVE_XML2 if (!conn) - session_connect(cur_host); + session_connect(); if (!conn) return 0; if (send_SRW_scanRequest(scan_query, pos_p, scan_size) < 0) @@ -3641,9 +3629,9 @@ static int cmd_scan_common(const char *set, const char *arg) } else { - if (*cur_host && !conn && auto_reconnect) + if (wrbuf_len(cur_host) && !conn && auto_reconnect) { - session_connect(cur_host); + session_connect(); wait_and_handle_response(0); } if (!conn) @@ -4274,6 +4262,8 @@ static void initialize(const char *rc_file) FILE *inf; int i; + cur_host = wrbuf_alloc(); + if (!(out = odr_createmem(ODR_ENCODE)) || !(in = odr_createmem(ODR_DECODE)) || !(print = odr_createmem(ODR_PRINT))) @@ -4328,10 +4318,7 @@ struct timeval tv_start; static void handle_srw_record(Z_SRW_record *rec) { if (rec->recordPosition) - { printf("pos=" ODR_INT_PRINTF, *rec->recordPosition); - setno = *rec->recordPosition + 1; - } if (rec->recordSchema) printf(" schema=%s", rec->recordSchema); printf("\n"); @@ -4385,6 +4372,7 @@ static void handle_srw_response(Z_SRW_searchRetrieveResponse *res) } handle_srw_record(res->records + i); } + setno += res->num_records; } static void handle_srw_scan_term(Z_SRW_scanTerm *term) @@ -4468,6 +4456,7 @@ static void http_response(Z_HTTP_Response *hres) {YAZ_XMLNS_SRU_v2_mask, 0, (Z_SOAP_fun) yaz_srw_codec}, {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, {YAZ_XMLNS_SRU_v1_response, 0, (Z_SOAP_fun) yaz_srw_codec}, + {"searchRetrieveResponse", 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; ret = z_soap_codec(o, &soap_package, @@ -4530,7 +4519,7 @@ static void http_response(Z_HTTP_Response *hres) } #endif -#define max_HTTP_redirects 2 +#define max_HTTP_redirects 3 static void wait_and_handle_response(int one_response_only) { @@ -4552,7 +4541,7 @@ static void wait_and_handle_response(int one_response_only) { cs_close(conn); conn = 0; - session_connect(cur_host); + session_connect(); reconnect_ok = 0; if (conn) { @@ -4667,17 +4656,23 @@ static void wait_and_handle_response(int one_response_only) Z_HTTP_Response *hres = gdu->u.HTTP_Response; int code = hres->code; const char *location = 0; + + yaz_cookies_response(yaz_cookies, hres); if ((code == 301 || code == 302) && no_redirects < max_HTTP_redirects && !yaz_matchstr(sru_method, "get") && (location = z_HTTP_header_lookup(hres->headers, "Location"))) { const char *base_tmp; - session_connect_base(location, &base_tmp); + int host_change = 0; + location = yaz_check_location(in, wrbuf_cstr(cur_host), + location, &host_change); + if (host_change) + session_connect_base(location, &base_tmp); no_redirects++; if (conn) { - if (send_SRW_redirect(location, hres) == 2) + if (send_SRW_redirect(location) == 2) continue; } printf("Redirect failed\n"); @@ -4851,9 +4846,9 @@ static int cmd_list_all(const char* args) /* connection options */ if (conn) - printf("Connected to : %s\n", cur_host); - else if (*cur_host) - printf("Not connected to : %s\n", cur_host); + printf("Connected to : %s\n", wrbuf_cstr(cur_host)); + else if (cur_host && wrbuf_len(cur_host)) + printf("Not connected to : %s\n", wrbuf_cstr(cur_host)); else printf("Not connected : \n"); if (yazProxy) printf("using proxy : %s\n",yazProxy); @@ -5406,6 +5401,8 @@ int main(int argc, char **argv) if (codeset) outputCharset = xstrdup(codeset); + yaz_enable_panic_backtrace(prog); + ODR_MASK_SET(&z3950_options, Z_Options_search); ODR_MASK_SET(&z3950_options, Z_Options_present); ODR_MASK_SET(&z3950_options, Z_Options_namedResultSets);