X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=client%2Fclient.c;h=a02c99c0c54ec2eddb2ab61db876f5edb779fad3;hp=94292d046ecfa21ca37bc26b3f69fb8879a77f1e;hb=9b9e5015dba09e7480f09351cfccdfafd99b2d30;hpb=4acb9088c874e971fbe37f3d65ea4f47764e6219 diff --git a/client/client.c b/client/client.c index 94292d0..a02c99c 100644 --- a/client/client.c +++ b/client/client.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: client.c,v 1.208 2003-09-04 18:51:49 adam Exp $ + * $Id: client.c,v 1.215 2003-12-18 17:02:24 mike Exp $ */ #include @@ -60,6 +60,7 @@ static char *codeset = 0; /* character set for output */ static int hex_dump = 0; +static char *dump_file_prefix = 0; static ODR out, in, print; /* encoding and decoding streams */ #if HAVE_XML2 static ODR srw_sr_odr_out = 0; @@ -103,6 +104,8 @@ static char *refid = NULL; static char *last_open_command = NULL; static int auto_reconnect = 0; +static char cur_host[200]; + typedef enum { QueryType_Prefix, QueryType_CCL, @@ -114,7 +117,7 @@ typedef enum { static QueryType queryType = QueryType_Prefix; static CCL_bibset bibset; /* CCL bibset handle */ -static cql_transform_t cqltrans; /* CQL qualifier-set handle */ +static cql_transform_t cqltrans; /* CQL context-set handle */ #if HAVE_READLINE_COMPLETION_OVER @@ -174,6 +177,21 @@ static void do_hex_dump(const char* buf, int len) printf("\n"); } } + if (dump_file_prefix) + { + static int no = 0; + if (++no < 1000 && strlen(dump_file_prefix) < 500) + { + char fname[1024]; + FILE *of; + sprintf (fname, "%s.%03d.raw", dump_file_prefix, no); + of = fopen(fname, "wb"); + + fwrite (buf, 1, len, of); + + fclose(of); + } + } } void add_otherInfos(Z_APDU *a) @@ -212,13 +230,13 @@ int send_apdu(Z_APDU *a) if (ber_file) odr_dumpBER(ber_file, buf, len); /* printf ("sending APDU of size %d\n", len); */ + do_hex_dump(buf, len); if (cs_put(conn, buf, len) < 0) { fprintf(stderr, "cs_put: %s", cs_errmsg(cs_errno(conn))); close_session(); return 0; } - do_hex_dump(buf,len); odr_reset(out); /* release the APDU structure */ return 1; } @@ -309,6 +327,11 @@ static void send_initRequest(const char* type_and_host) printf("Sent initrequest.\n"); } + +/* These two are used only from process_initResponse() */ +static void render_initUserInfo(Z_OtherInformation *ui1); +static void render_diag(Z_DiagnosticFormat *diag); + static int process_initResponse(Z_InitResponse *res) { int ver = 0; @@ -333,22 +356,24 @@ static int process_initResponse(Z_InitResponse *res) if (res->userInformationField) { Z_External *uif = res->userInformationField; - printf("UserInformationfield:\n"); - if (!z_External(print, (Z_External**)&uif, 0, 0)) - { - odr_perror(print, "Printing userinfo\n"); - odr_reset(print); - } - if (uif->which == Z_External_octet) - { - printf("Guessing visiblestring:\n"); - printf("'%s'\n", uif->u. octet_aligned->buf); - } else if (uif->which == Z_External_single) { - /* Peek at any private Init-diagnostic APDUs */ - Odr_any *sat = uif->u.single_ASN1_type; - printf("### NAUGHTY: External is '%s'\n", sat->buf); + if (uif->which == Z_External_userInfo1) { + render_initUserInfo(uif->u.userInfo1); + } else { + printf("UserInformationfield:\n"); + if (!z_External(print, (Z_External**)&uif, 0, 0)) { + odr_perror(print, "Printing userinfo\n"); + odr_reset(print); + } + if (uif->which == Z_External_octet) { + printf("Guessing visiblestring:\n"); + printf("'%s'\n", uif->u. octet_aligned->buf); + } else if (uif->which == Z_External_single) { + /* Peek at any private Init-diagnostic APDUs */ + Odr_any *sat = uif->u.single_ASN1_type; + printf("### NAUGHTY: External is '%s'\n", sat->buf); + } + odr_reset (print); } - odr_reset (print); } printf ("Options:"); if (ODR_MASK_GET(res->options, Z_Options_search)) @@ -423,6 +448,60 @@ static int process_initResponse(Z_InitResponse *res) return 0; } + +static void render_initUserInfo(Z_OtherInformation *ui1) { + int i; + printf("Init response contains %d otherInfo unit%s:\n", + ui1->num_elements, ui1->num_elements == 1 ? "" : "s"); + + for (i = 0; i < ui1->num_elements; i++) { + Z_OtherInformationUnit *unit = ui1->list[i]; + printf(" %d: otherInfo unit contains ", i+1); + if (unit->which == Z_OtherInfo_externallyDefinedInfo && + unit->information.externallyDefinedInfo->which == + Z_External_diag1) { + render_diag(unit->information.externallyDefinedInfo->u.diag1); + } else { + printf("unsupported otherInfo unit type %d\n", unit->which); + } + } +} + + +/* ### should this share code with display_diagrecs()? */ +static void render_diag(Z_DiagnosticFormat *diag) { + int i; + + printf("%d diagnostic%s:\n", diag->num, diag->num == 1 ? "" : "s"); + for (i = 0; i < diag->num; i++) { + Z_DiagnosticFormat_s *ds = diag->elements[i]; + printf(" %d: ", i+1); + switch (ds->which) { + case Z_DiagnosticFormat_s_defaultDiagRec: { + Z_DefaultDiagFormat *dd = ds->u.defaultDiagRec; + /* ### should check `dd->diagnosticSetId' */ + printf("code=%d (%s)", *dd->condition, + diagbib1_str(*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); + break; + } + case Z_DiagnosticFormat_s_explicitDiagnostic: + printf("Explicit diagnostic (not supported)"); + break; + default: + printf("Unrecognised diagnostic type %d", ds->which); + break; + } + + if (ds->message != 0) + printf(", message='%s'", ds->message); + printf("\n"); + } +} + + static int set_base(const char *arg) { int i; @@ -552,7 +631,6 @@ int session_connect(const char *arg) int cmd_open(const char *arg) { - static char cur_host[200]; if (arg) { strncpy (cur_host, arg, sizeof(cur_host)-1); @@ -1049,7 +1127,7 @@ static int send_deleteResultSetRequest(const char *arg) static int send_srw(Z_SRW_PDU *sr) { const char *charset = negotiationCharset; - const char *host_port = 0; + const char *host_port = cur_host; char *path = 0; char ctype[50]; Z_SOAP_Handler h[2] = { @@ -1087,7 +1165,7 @@ static int send_srw(Z_SRW_PDU *sr) memcpy (h, cp0, cp1 - cp0); h[cp1-cp0] = '\0'; z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, - "host", h); + "Host", h); } } @@ -1119,10 +1197,14 @@ static int send_srw(Z_SRW_PDU *sr) char *buf_out; int len_out; int r; + if (apdu_file && !z_GDU(print, &gdu, 0, 0)) + printf ("Failed to print outgoing APDU\n"); 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); @@ -2492,7 +2574,9 @@ int send_sortrequest(const char *arg, int newset) void display_term(Z_TermInfo *t) { - if (t->term->which == Z_Term_general) + if (t->displayTerm) + printf("%s", t->displayTerm); + else if (t->term->which == Z_Term_general) { printf("%.*s", t->term->u.general->len, t->term->u.general->buf); sprintf(last_scan_line, "%.*s", t->term->u.general->len, @@ -3254,17 +3338,20 @@ static void http_response(Z_HTTP_Response *hres) } close_session(); } - if (!strcmp(hres->version, "1.0")) - { - /* HTTP 1.0: only if Keep-Alive we stay alive.. */ - if (!connection_head || strcmp(connection_head, "Keep-Alive")) - close_session(); - } - else + else { - /* HTTP 1.1: only if no close we stay alive .. */ - if (connection_head && !strcmp(connection_head, "close")) - close_session(); + if (!strcmp(hres->version, "1.0")) + { + /* HTTP 1.0: only if Keep-Alive we stay alive.. */ + if (!connection_head || strcmp(connection_head, "Keep-Alive")) + close_session(); + } + else + { + /* HTTP 1.1: only if no close we stay alive .. */ + if (connection_head && !strcmp(connection_head, "close")) + close_session(); + } } } #endif @@ -3293,6 +3380,8 @@ void wait_and_handle_response() buf_out = odr_getbuf(out, &len_out, 0); + do_hex_dump(buf_out, len_out); + cs_put(conn, buf_out, len_out); odr_reset(out); @@ -3979,7 +4068,7 @@ int main(int argc, char **argv) if (codeset) outputCharset = xstrdup(codeset); - while ((ret = options("k:c:q:a:b:m:v:p:u:t:Vx", argv, argc, &arg)) != -2) + while ((ret = options("k:c:q:a:b:m:v:p:u:t:Vxd:", argv, argc, &arg)) != -2) { switch (ret) { @@ -3991,6 +4080,9 @@ int main(int argc, char **argv) strcat (open_command, arg); } break; + case 'd': + dump_file_prefix = arg; + break; case 'k': kilobytes = atoi(arg); break; @@ -4048,7 +4140,7 @@ int main(int argc, char **argv) fprintf (stderr, "Usage: %s [-m ] [ -a ] " "[-b berdump] [-c cclfields] \n" "[-q cqlfields] [-p ] [-u ] " - "[-k size] [-V] []\n", + "[-k size] [-d dump] [-V] []\n", prog); exit (1); }