X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=client%2Fclient.c;h=f0416fef1d71ca27164c5738634480019b7ae30b;hp=396be27b5a91663ab8331441b21bdf0a7e1061f4;hb=b7e0b586c47f8cc0c99f0195e0b554dc5f1af072;hpb=e8b504e6b88e1254fb1c329a74fd1afaf973570b diff --git a/client/client.c b/client/client.c index 396be27..f0416fe 100644 --- a/client/client.c +++ b/client/client.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2006, Index Data ApS + * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: client.c,v 1.318 2006-11-08 08:55:50 adam Exp $ + * $Id: client.c,v 1.327 2007-01-24 23:10:01 adam Exp $ */ /** \file client.c * \brief yaz-client program @@ -13,6 +13,9 @@ #include #include #include +#ifndef WIN32 +#include +#endif #if HAVE_SYS_TYPES_H #include #endif @@ -78,9 +81,12 @@ #include "admin.h" #include "tabcomplete.h" +#include "fhistory.h" #define C_PROMPT "Z> " +static file_history_t file_history = 0; + static char *sru_method = "soap"; static char *codeset = 0; /* character set for output */ static int hex_dump = 0; @@ -936,62 +942,41 @@ static void display_record(Z_External *r) int rlen; yaz_iconv_t cd = 0; yaz_marc_t mt = yaz_marc_create(); - - if (yaz_marc_decode_buf(mt, octet_buf,r->u.octet_aligned->len, - &result, &rlen)> 0) + const char *from = 0; + + if (marcCharset && !strcmp(marcCharset, "auto")) { - char *from = 0; - if (marcCharset && !strcmp(marcCharset, "auto")) + if (ent->value == VAL_USMARC) { - if (ent->value == VAL_USMARC) - { - if (octet_buf[9] == 'a') - from = "UTF-8"; - else - from = "MARC-8"; - } + if (octet_buf[9] == 'a') + from = "UTF-8"; else - from = "ISO-8859-1"; - } - else if (marcCharset) - from = marcCharset; - if (outputCharset && from) - { - cd = yaz_iconv_open(outputCharset, from); - printf ("convert from %s to %s", from, - outputCharset); - if (!cd) - printf (" unsupported\n"); - else - printf ("\n"); + from = "MARC-8"; } + else + from = "ISO-8859-1"; + } + else if (marcCharset) + from = marcCharset; + if (outputCharset && from) + { + cd = yaz_iconv_open(outputCharset, from); + printf ("convert from %s to %s", from, + outputCharset); if (!cd) - fwrite (result, 1, rlen, stdout); + printf (" unsupported\n"); else { - char outbuf[6]; - size_t inbytesleft = rlen; - const char *inp = result; - - while (inbytesleft) - { - size_t outbytesleft = sizeof(outbuf); - char *outp = outbuf; - size_t r; - - r = yaz_iconv (cd, (char**) &inp, - &inbytesleft, - &outp, &outbytesleft); - if (r == (size_t) (-1)) - { - int e = yaz_iconv_error(cd); - if (e != YAZ_ICONV_E2BIG) - break; - } - fwrite (outbuf, outp - outbuf, 1, stdout); - } + yaz_marc_iconv(mt, cd); + printf ("\n"); } } + + if (yaz_marc_decode_buf(mt, octet_buf,r->u.octet_aligned->len, + &result, &rlen)> 0) + { + fwrite (result, rlen, 1, stdout); + } else { printf ("bad MARC. Dumping as it is:\n"); @@ -1633,7 +1618,25 @@ static int process_searchResponse(Z_SearchResponse *res) last_hit_count = *res->resultCount; if (setnumber >= 0) printf (", setno %d", setnumber); - printf ("\n"); + putchar('\n'); + if (res->resultSetStatus) + { + printf("Result Set Status: "); + switch(*res->resultSetStatus) + { + case Z_SearchResponse_subset: + printf("subset"); break; + case Z_SearchResponse_interim: + printf("interim"); break; + case Z_SearchResponse_none: + printf("none"); break; + case Z_SearchResponse_estimate: + printf("estimate"); break; + default: + printf("%d", *res->resultSetStatus); + } + putchar('\n'); + } display_searchResult (res->additionalSearchInfo); printf("records returned: %d\n", *res->numberOfRecordsReturned); @@ -2123,20 +2126,20 @@ static int cmd_update0(const char *arg) return cmd_update_common(arg, 0); } +static int cmd_update_Z3950(int version, int action_no, const char *recid, + char *rec_buf, int rec_len); + +static int cmd_update_SRW(int action_no, const char *recid, + char *rec_buf, int rec_len); + static int cmd_update_common(const char *arg, int version) { - Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest ); - Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; - Z_External *r; char action[20], recid[20]; char *rec_buf; int rec_len; int action_no; int noread = 0; - Z_External *record_this = 0; - if (only_z3950()) - return 1; *action = 0; *recid = 0; sscanf (arg, "%19s %19s%n", action, recid, &noread); @@ -2167,6 +2170,60 @@ static int cmd_update_common(const char *arg, int version) if (parse_cmd_doc(&arg, out, &rec_buf, &rec_len, 1) == 0) return 0; +#if YAZ_HAVE_XML2 + if (protocol == PROTO_HTTP) + return cmd_update_SRW(action_no, recid, rec_buf, rec_len); +#endif + return cmd_update_Z3950(version, action_no, recid, rec_buf, rec_len); +} + +#if YAZ_HAVE_XML2 +static int cmd_update_SRW(int action_no, const char *recid, + char *rec_buf, int rec_len) +{ + if (!conn) + cmd_open(0); + if (!conn) + return 0; + else + { + Z_SRW_PDU *srw = yaz_srw_get(out, Z_SRW_update_request); + Z_SRW_updateRequest *sr = srw->u.update_request; + + switch(action_no) + { + case Z_IUOriginPartToKeep_recordInsert: + sr->operation = "info:srw/action/1/create"; + break; + case Z_IUOriginPartToKeep_recordReplace: + sr->operation = "info:srw/action/1/replace"; + break; + case Z_IUOriginPartToKeep_recordDelete: + sr->operation = "info:srw/action/1/delete"; + break; + } + if (rec_buf) + { + sr->record = yaz_srw_get_record(out); + sr->record->recordData_buf = rec_buf; + sr->record->recordData_len = rec_len; + sr->record->recordSchema = record_schema; + } + if (recid) + sr->recordId = odr_strdup(out, recid); + return send_srw(srw); + } +} +#endif + +static int cmd_update_Z3950(int version, int action_no, const char *recid, + char *rec_buf, int rec_len) +{ + Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest ); + Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; + Z_External *r; + Z_External *record_this = 0; + if (rec_buf) record_this = z_ext_record (out, VAL_TEXT_XML, rec_buf, rec_len); else @@ -2220,7 +2277,7 @@ static int cmd_update_common(const char *arg, int version) notToKeep->elements[0] = (Z_IU0SuppliedRecords_elem *) odr_malloc(out, sizeof(**notToKeep->elements)); notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; - if (*recid) + if (*recid && strcmp(recid, "none")) { notToKeep->elements[0]->u.opaque = (Odr_oct *) odr_malloc (out, sizeof(Odr_oct)); @@ -2752,11 +2809,18 @@ static int cmd_show(const char *arg) return 2; } +void exit_client(int code) +{ + file_history_save(file_history); + file_history_destroy(&file_history); + exit(code); +} + int cmd_quit(const char *arg) { printf("See you later, alligator.\n"); xmalloc_trav (""); - exit(0); + exit_client(0); return 0; } @@ -3640,24 +3704,24 @@ void source_rcfile(void) { /* Look for a $HOME/.yazclientrc and source it if it exists */ struct stat statbuf; - char buffer[1000]; - char* homedir=getenv("HOME"); + char fname[1000]; + char* homedir = getenv("HOME"); - if( homedir ) { - - sprintf(buffer,"%s/.yazclientrc",homedir); + sprintf(fname, "%.500s%s%s", homedir ? homedir : "", + homedir ? "/" : "", + ".yazclientrc"); - if(stat(buffer,&statbuf)==0) { - cmd_source(buffer, 0 ); - } - - }; - - if(stat(".yazclientrc",&statbuf)==0) { - cmd_source(".yazclientrc", 0 ); - } + if (stat(fname,&statbuf)==0) + cmd_source(fname, 0 ); } +void add_to_readline_history(void *client_data, const char *line) +{ +#if HAVE_READLINE_HISTORY_H + if (strlen(line)) + add_history(line); +#endif +} static void initialize(void) { @@ -3696,6 +3760,10 @@ static void initialize(void) } source_rcfile(); + + file_history = file_history_new(); + file_history_load(file_history); + file_history_trav(file_history, 0, add_to_readline_history); } @@ -3807,16 +3875,15 @@ static void http_response(Z_HTTP_Response *hres) { Z_SOAP *soap_package = 0; ODR o = odr_createmem(ODR_DECODE); - Z_SOAP_Handler soap_handlers[2] = { - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, + Z_SOAP_Handler soap_handlers[3] = { + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, {0, 0, 0} }; ret = z_soap_codec(o, &soap_package, &hres->content_buf, &hres->content_len, soap_handlers); - if (!ret && soap_package->which == Z_SOAP_generic && - soap_package->u.generic->no == 0) + if (!ret && soap_package->which == Z_SOAP_generic) { Z_SRW_PDU *sr = soap_package->u.generic->p; if (sr->which == Z_SRW_searchRetrieve_response) @@ -3825,11 +3892,14 @@ static void http_response(Z_HTTP_Response *hres) handle_srw_explain_response(sr->u.explain_response); else if (sr->which == Z_SRW_scan_response) handle_srw_scan_response(sr->u.scan_response); + else if (sr->which == Z_SRW_update_response) + printf("Got update response. Status: %s\n", + sr->u.update_response->operationStatus); else ret = -1; } else if (soap_package && (soap_package->which == Z_SOAP_fault - || soap_package->which == Z_SOAP_error)) + || soap_package->which == Z_SOAP_error)) { printf ("HTTP Error Status=%d\n", hres->code); printf ("SOAP Fault code %s\n", @@ -3841,7 +3911,10 @@ static void http_response(Z_HTTP_Response *hres) soap_package->u.fault->details); } else + { + printf("z_soap_codec failed. (no SOAP error)\n"); ret = -1; + } odr_destroy(o); } if (ret) @@ -4321,6 +4394,7 @@ static struct { {"displaycharset", cmd_displaycharset, "",NULL,0,NULL}, {"marccharset", cmd_marccharset, "",NULL,0,NULL}, {"lang", cmd_lang, "",NULL,0,NULL}, + {"source", cmd_source_echo, "",NULL,1,NULL}, {".", cmd_source_echo, "",NULL,1,NULL}, {"!", cmd_subshell, "Subshell command",NULL,1,NULL}, {"set_apdufile", cmd_set_apdufile, "",NULL,1,NULL}, @@ -4608,12 +4682,23 @@ char **readline_completer(char *text, int start, int end) } #endif +#ifndef WIN32 +void ctrl_c_handler(int x) +{ + exit_client(0); +} +#endif + static void client(void) { char line[10240]; line[10239] = '\0'; +#ifndef WIN32 + signal(SIGINT, ctrl_c_handler); +#endif + #if HAVE_GETTIMEOFDAY gettimeofday (&tv_start, 0); #endif @@ -4631,7 +4716,7 @@ static void client(void) if (*line_in) add_history(line_in); #endif - strncpy(line, line_in, 10239); + strncpy(line, line_in, sizeof(line)-1); free(line_in); } #endif @@ -4640,11 +4725,13 @@ static void client(void) char *end_p; printf (C_PROMPT); fflush(stdout); - if (!fgets(line, 10239, stdin)) + if (!fgets(line, sizeof(line)-1, stdin)) break; if ((end_p = strchr (line, '\n'))) *end_p = '\0'; } + if (isatty(0)) + file_history_add_line(file_history, line); process_cmd_line(line); } } @@ -4803,8 +4890,9 @@ int main(int argc, char **argv) #endif xfree(open_command); } - client (); - exit (0); + client(); + exit_client(0); + return 0; } /* * Local variables: