X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=client%2Fclient.c;h=a02c99c0c54ec2eddb2ab61db876f5edb779fad3;hp=a57f354d99afdfe7ace32dbb77cde893de03a0db;hb=9b9e5015dba09e7480f09351cfccdfafd99b2d30;hpb=b258a14997c70bf78310b2e094eb6bcf14b26a55 diff --git a/client/client.c b/client/client.c index a57f354..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.205 2003-07-23 12:57:22 mike 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)) @@ -404,6 +429,15 @@ static int process_initResponse(Z_InitResponse *res) yaz_get_response_charneg(session_mem, p, &charset, &lang, &selected); + + if (outputCharset && negotiationCharset) { + odr_set_charset (out, charset, outputCharset); + odr_set_charset (in, outputCharset, charset); + } + else { + odr_set_charset (out, 0, 0); + odr_set_charset (in, 0, 0); + } printf("Accepted character set : %s\n", charset); printf("Accepted code language : %s\n", lang ? lang : "none"); @@ -414,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; @@ -543,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); @@ -1040,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] = { @@ -1078,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); } } @@ -1110,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); @@ -1840,14 +1931,24 @@ static int only_z3950() return 0; } +static int cmd_update_common(const char *arg, int version); + static int cmd_update(const char *arg) { + return cmd_update_common(arg, 1); +} + +static int cmd_update0(const char *arg) +{ + return cmd_update_common(arg, 0); +} + +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; int oid[OID_SIZE]; - Z_IUOriginPartToKeep *toKeep; - Z_IUSuppliedRecords *notToKeep; oident update_oid; char action[20], recid[20], fname[80]; int action_no; @@ -1911,7 +2012,10 @@ static int cmd_update(const char *arg) update_oid.proto = PROTO_Z3950; update_oid.oclass = CLASS_EXTSERV; - update_oid.value = VAL_DBUPDATE; + if (version == 0) + update_oid.value = VAL_DBUPDATE0; + else + update_oid.value = VAL_DBUPDATE; oid_ent_to_oid (&update_oid, oid); req->packageType = odr_oiddup(out,oid); req->packageName = esPackageName; @@ -1923,41 +2027,90 @@ static int cmd_update(const char *arg) r->direct_reference = odr_oiddup(out,oid); r->indirect_reference = 0; r->descriptor = 0; - r->which = Z_External_update; - r->u.update = (Z_IUUpdate *) odr_malloc(out, sizeof(*r->u.update)); - r->u.update->which = Z_IUUpdate_esRequest; - r->u.update->u.esRequest = (Z_IUUpdateEsRequest *) - odr_malloc(out, sizeof(*r->u.update->u.esRequest)); - toKeep = r->u.update->u.esRequest->toKeep = (Z_IUOriginPartToKeep *) - odr_malloc(out, sizeof(*r->u.update->u.esRequest->toKeep)); - toKeep->databaseName = databaseNames[0]; - toKeep->schema = 0; - toKeep->elementSetName = 0; - toKeep->actionQualifier = 0; - toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action)); - *toKeep->action = action_no; - - notToKeep = r->u.update->u.esRequest->notToKeep = (Z_IUSuppliedRecords *) - odr_malloc(out, sizeof(*r->u.update->u.esRequest->notToKeep)); - notToKeep->num = 1; - notToKeep->elements = (Z_IUSuppliedRecords_elem **) - odr_malloc(out, sizeof(*notToKeep->elements)); - notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *) - odr_malloc(out, sizeof(**notToKeep->elements)); - notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; - if (*recid) - { - notToKeep->elements[0]->u.opaque = (Odr_oct *) - odr_malloc (out, sizeof(Odr_oct)); - notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid; - notToKeep->elements[0]->u.opaque->size = strlen(recid); - notToKeep->elements[0]->u.opaque->len = strlen(recid); + if (version == 0) + { + Z_IU0OriginPartToKeep *toKeep; + Z_IU0SuppliedRecords *notToKeep; + + r->which = Z_External_update0; + r->u.update0 = (Z_IU0Update *) odr_malloc(out, sizeof(*r->u.update0)); + r->u.update0->which = Z_IUUpdate_esRequest; + r->u.update0->u.esRequest = (Z_IU0UpdateEsRequest *) + odr_malloc(out, sizeof(*r->u.update0->u.esRequest)); + toKeep = r->u.update0->u.esRequest->toKeep = (Z_IU0OriginPartToKeep *) + odr_malloc(out, sizeof(*r->u.update0->u.esRequest->toKeep)); + + toKeep->databaseName = databaseNames[0]; + toKeep->schema = 0; + toKeep->elementSetName = 0; + + toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action)); + *toKeep->action = action_no; + + notToKeep = r->u.update0->u.esRequest->notToKeep = (Z_IU0SuppliedRecords *) + odr_malloc(out, sizeof(*r->u.update0->u.esRequest->notToKeep)); + notToKeep->num = 1; + notToKeep->elements = (Z_IU0SuppliedRecords_elem **) + odr_malloc(out, sizeof(*notToKeep->elements)); + notToKeep->elements[0] = (Z_IU0SuppliedRecords_elem *) + odr_malloc(out, sizeof(**notToKeep->elements)); + notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; + if (*recid) + { + notToKeep->elements[0]->u.opaque = (Odr_oct *) + odr_malloc (out, sizeof(Odr_oct)); + notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid; + notToKeep->elements[0]->u.opaque->size = strlen(recid); + notToKeep->elements[0]->u.opaque->len = strlen(recid); + } + else + notToKeep->elements[0]->u.opaque = 0; + notToKeep->elements[0]->supplementalId = 0; + notToKeep->elements[0]->correlationInfo = 0; + notToKeep->elements[0]->record = record_this; } else - notToKeep->elements[0]->u.opaque = 0; - notToKeep->elements[0]->supplementalId = 0; - notToKeep->elements[0]->correlationInfo = 0; - notToKeep->elements[0]->record = record_this; + { + Z_IUOriginPartToKeep *toKeep; + Z_IUSuppliedRecords *notToKeep; + + r->which = Z_External_update; + r->u.update = (Z_IUUpdate *) odr_malloc(out, sizeof(*r->u.update)); + r->u.update->which = Z_IUUpdate_esRequest; + r->u.update->u.esRequest = (Z_IUUpdateEsRequest *) + odr_malloc(out, sizeof(*r->u.update->u.esRequest)); + toKeep = r->u.update->u.esRequest->toKeep = (Z_IUOriginPartToKeep *) + odr_malloc(out, sizeof(*r->u.update->u.esRequest->toKeep)); + + toKeep->databaseName = databaseNames[0]; + toKeep->schema = 0; + toKeep->elementSetName = 0; + toKeep->actionQualifier = 0; + toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action)); + *toKeep->action = action_no; + + notToKeep = r->u.update->u.esRequest->notToKeep = (Z_IUSuppliedRecords *) + odr_malloc(out, sizeof(*r->u.update->u.esRequest->notToKeep)); + notToKeep->num = 1; + notToKeep->elements = (Z_IUSuppliedRecords_elem **) + odr_malloc(out, sizeof(*notToKeep->elements)); + notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *) + odr_malloc(out, sizeof(**notToKeep->elements)); + notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; + if (*recid) + { + notToKeep->elements[0]->u.opaque = (Odr_oct *) + odr_malloc (out, sizeof(Odr_oct)); + notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid; + notToKeep->elements[0]->u.opaque->size = strlen(recid); + notToKeep->elements[0]->u.opaque->len = strlen(recid); + } + else + notToKeep->elements[0]->u.opaque = 0; + notToKeep->elements[0]->supplementalId = 0; + notToKeep->elements[0]->correlationInfo = 0; + notToKeep->elements[0]->record = record_this; + } send_apdu(apdu); @@ -2421,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, @@ -2762,16 +2917,7 @@ int cmd_charset(const char* arg) else printf ("Output charset conversion disabled\n"); } - if (outputCharset && negotiationCharset) - { - odr_set_charset (out, negotiationCharset, outputCharset); - odr_set_charset (in, outputCharset, negotiationCharset); - } - else - { - odr_set_charset (out, 0, 0); - odr_set_charset (in, 0, 0); - } + return 1; } @@ -3192,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 @@ -3231,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); @@ -3586,6 +3737,7 @@ static struct { {"refid", cmd_refid, "",NULL,0,NULL}, {"itemorder", cmd_itemorder, "ill|item ",NULL,0,NULL}, {"update", cmd_update, " []",NULL,0,NULL}, + {"update0", cmd_update0, " []",NULL,0,NULL}, {"packagename", cmd_packagename, "",NULL,0,NULL}, {"proxy", cmd_proxy, "[('tcp'|'ssl')][':']",NULL,0,NULL}, {"charset", cmd_charset, " ",NULL,0,NULL}, @@ -3916,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) { @@ -3928,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; @@ -3985,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); }