X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=client%2Fclient.c;h=991bc06a784c5cdfe08859375025cde891923121;hp=f85f0e1da51a660908ad6f3f68887a72f71816fb;hb=248491b25960ff7c08860dd0065f7e04cc550e90;hpb=fb6d99a0c7e07d9cc4a315c447deaf6564a85505 diff --git a/client/client.c b/client/client.c index f85f0e1..991bc06 100644 --- a/client/client.c +++ b/client/client.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2005, Index Data ApS + * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: client.c,v 1.292 2005-06-25 15:46:01 adam Exp $ + * $Id: client.c,v 1.308 2006-05-07 19:43:00 adam Exp $ */ #include @@ -100,7 +100,10 @@ static int mediumSetPresentNumber = 0; static Z_ElementSetNames *elementSetNames = 0; static int setno = 1; /* current set offset */ static enum oid_proto protocol = PROTO_Z3950; /* current app protocol */ -static enum oid_value recordsyntax = VAL_USMARC; +#define RECORDSYNTAX_MAX 20 +static enum oid_value recordsyntax_list[RECORDSYNTAX_MAX] = { VAL_USMARC }; +static int recordsyntax_size = 1; + static char *record_schema = 0; static int sent_close = 0; static NMEM session_mem = NULL; /* memory handle for init-response */ @@ -133,6 +136,7 @@ static int scan_stepSize = 0; static int scan_position = 1; static int scan_size = 20; static char cur_host[200]; +static int last_hit_count = 0; typedef enum { QueryType_Prefix, @@ -165,9 +169,11 @@ struct { void process_cmd_line(char* line); -char ** readline_completer(char *text, int start, int end); -char *command_generator(const char *text, int state); -char** curret_global_list=NULL; +#if HAVE_READLINE_READLINE_H +char **readline_completer(char *text, int start, int end); +#endif +static char *command_generator(const char *text, int state); +char** current_global_list = NULL; int cmd_register_tab(const char* arg); static void close_session (void); @@ -337,12 +343,10 @@ static void send_initRequest(const char* type_and_host) p0->which = Z_OtherInfo_externallyDefinedInfo; p0->information.externallyDefinedInfo = - yaz_set_proposal_charneg( - out, - (const char**)&negotiationCharset, - negotiationCharset ? 1 : 0, - (const char**)&yazLang, yazLang ? 1 : 0, - negotiationCharsetRecords); + yaz_set_proposal_charneg_list(out, ",", + negotiationCharset, + yazLang, + negotiationCharsetRecords); } } @@ -405,7 +409,7 @@ static int process_initResponse(Z_InitResponse *res) if (oid->value == VAL_OCLCUI) { Z_OCLC_UserInformation *oclc_ui; ODR decode = odr_createmem(ODR_DECODE); - odr_setbuf(decode, sat->buf, sat->len, 0); + odr_setbuf(decode, (char *) sat->buf, sat->len, 0); if (!z_OCLC_UserInformation(decode, &oclc_ui, 0, 0)) printf ("Bad OCLC UserInformation:\n"); else @@ -878,7 +882,7 @@ static void display_record(Z_External *r) if (!(*type->fun)(in, &rr, 0, 0)) { odr_perror(in, "Decoding constructed record."); - fprintf(stdout, "[Near %d]\n", odr_offset(in)); + fprintf(stdout, "[Near %ld]\n", (long) odr_offset(in)); fprintf(stdout, "Packet dump:\n---------\n"); odr_dumpBER(stdout, (char*)r->u.octet_aligned->buf, r->u.octet_aligned->len); @@ -1447,7 +1451,7 @@ static int send_SRW_searchRequest(const char *arg) if (record_schema) sr->u.request->recordSchema = record_schema; - if (recordsyntax == VAL_TEXT_XML) + if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML) sr->u.explain_request->recordPacking = "xml"; return send_srw(sr); } @@ -1526,9 +1530,9 @@ static int send_searchRequest(const char *arg) if (smallSetUpperBound > 0 || (largeSetLowerBound > 1 && mediumSetPresentNumber > 0)) { - req->preferredRecordSyntax = - yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax); - + if (recordsyntax_size > 0) + req->preferredRecordSyntax = + yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax_list[0]); req->smallSetElementSetNames = req->mediumSetElementSetNames = elementSetNames; } @@ -1548,7 +1552,8 @@ static int send_searchRequest(const char *arg) const char *pqf_msg; size_t off; int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off); - printf("%*s^\n", off+4, ""); + int ioff = off; + printf("%*s^\n", ioff+4, ""); printf("Prefix query error: %s (code %d)\n", pqf_msg, code); yaz_pqf_destroy (pqf_parser); @@ -1595,10 +1600,11 @@ static int send_searchRequest(const char *arg) } /* display Query Expression as part of searchResult-1 */ -static void display_queryExpression (Z_QueryExpression *qe) +static void display_queryExpression (const char *lead, Z_QueryExpression *qe) { if (!qe) return; + printf(" %s=", lead); if (qe->which == Z_QueryExpression_term) { if (qe->u.term->queryTerm) @@ -1607,16 +1613,16 @@ static void display_queryExpression (Z_QueryExpression *qe) switch (term->which) { case Z_Term_general: - printf (" %.*s", term->u.general->len, term->u.general->buf); + printf ("%.*s", term->u.general->len, term->u.general->buf); break; case Z_Term_characterString: - printf (" %s", term->u.characterString); + printf ("%s", term->u.characterString); break; case Z_Term_numeric: - printf (" %d", *term->u.numeric); + printf ("%d", *term->u.numeric); break; case Z_Term_null: - printf (" null"); + printf ("null"); break; } } @@ -1642,16 +1648,20 @@ static void display_searchResult (Z_OtherInformation *o) printf ("SearchResult-1:"); for (j = 0; j < sr->num; j++) { + if (j) + printf(","); if (!sr->elements[j]->subqueryExpression) - printf (" %d", j); - display_queryExpression ( + printf("%d", j); + display_queryExpression("term", sr->elements[j]->subqueryExpression); - display_queryExpression ( + display_queryExpression("interpretation", sr->elements[j]->subqueryInterpretation); - display_queryExpression ( + display_queryExpression("recommendation", sr->elements[j]->subqueryRecommendation); if (sr->elements[j]->subqueryCount) - printf ("(%d)", *sr->elements[j]->subqueryCount); + printf(" cnt=%d", *sr->elements[j]->subqueryCount); + if (sr->elements[j]->subqueryId) + printf(" id=%s ", sr->elements[j]->subqueryId); } printf ("\n"); } @@ -1668,6 +1678,7 @@ static int process_searchResponse(Z_SearchResponse *res) else printf("Search was a bloomin' failure.\n"); printf("Number of hits: %d", *res->resultCount); + last_hit_count = *res->resultCount; if (setnumber >= 0) printf (", setno %d", setnumber); printf ("\n"); @@ -2132,6 +2143,11 @@ static int send_itemorder(const char *type, int itemno) static int only_z3950() { + if (!conn) + { + printf ("Not connected yet\n"); + return 1; + } if (protocol == PROTO_HTTP) { printf ("Not supported by SRW\n"); @@ -2165,7 +2181,7 @@ static int cmd_update_common(const char *arg, int version) Z_External *record_this = 0; if (only_z3950()) - return 0; + return 1; *action = 0; *recid = 0; sscanf (arg, "%19s %19s%n", action, recid, &noread); @@ -2313,43 +2329,49 @@ static int cmd_update_common(const char *arg, int version) static int cmd_xmles(const char *arg) { - int noread = 0; - char oid_str[51]; - int oid_value_xmles = VAL_XMLES; - Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest); - Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; - - Z_External *ext = (Z_External *) odr_malloc(out, sizeof(*ext)); - req->taskSpecificParameters = ext; - ext->descriptor = 0; - ext->which = Z_External_octet; - ext->u.single_ASN1_type = (Odr_oct *) odr_malloc (out, sizeof(Odr_oct)); - - sscanf(arg, "%50s%n", oid_str, &noread); - if (noread == 0) - { - printf("Missing OID for xmles\n"); - return 0; - } - arg += noread; - oid_value_xmles = oid_getvalbyname(oid_str); - if (oid_value_xmles == VAL_NONE) + if (only_z3950()) + return 1; + else { - printf("Bad OID: %s\n", oid_str); - return 0; + int noread = 0; + char oid_str[51]; + int oid_value_xmles = VAL_XMLES; + Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest); + Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest; + + Z_External *ext = (Z_External *) odr_malloc(out, sizeof(*ext)); + + req->taskSpecificParameters = ext; + ext->indirect_reference = 0; + ext->descriptor = 0; + ext->which = Z_External_octet; + ext->u.single_ASN1_type = (Odr_oct *) odr_malloc (out, sizeof(Odr_oct)); + sscanf(arg, "%50s%n", oid_str, &noread); + if (noread == 0) + { + printf("Missing OID for xmles\n"); + return 0; + } + arg += noread; + oid_value_xmles = oid_getvalbyname(oid_str); + if (oid_value_xmles == VAL_NONE) + { + printf("Bad OID: %s\n", oid_str); + return 0; + } + + if (parse_cmd_doc(&arg, out, (char **) &ext->u.single_ASN1_type->buf, + &ext->u.single_ASN1_type->len, 0) == 0) + return 0; + req->packageType = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV, + oid_value_xmles); + + ext->direct_reference = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV, + oid_value_xmles); + send_apdu(apdu); + + return 2; } - - if (parse_cmd_doc(&arg, out, (char **) &ext->u.single_ASN1_type->buf, - &ext->u.single_ASN1_type->len, 0) == 0) - return 0; - req->packageType = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV, - oid_value_xmles); - - ext->direct_reference = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV, - oid_value_xmles); - send_apdu(apdu); - - return 2; } static int cmd_itemorder(const char *arg) @@ -2358,7 +2380,7 @@ static int cmd_itemorder(const char *arg) int itemno; if (only_z3950()) - return 0; + return 1; if (sscanf (arg, "%10s %d", type, &itemno) != 2) return 0; @@ -2415,7 +2437,7 @@ static int cmd_explain(const char *arg) /* save this for later .. when fetching individual records */ sr = yaz_srw_get(out, Z_SRW_explain_request); - if (recordsyntax == VAL_TEXT_XML) + if (recordsyntax_size > 0 && recordsyntax_list[0] == VAL_TEXT_XML) sr->u.explain_request->recordPacking = "xml"; send_srw(sr); return 2; @@ -2431,8 +2453,8 @@ static int cmd_init(const char *arg) strncpy (cur_host, arg, sizeof(cur_host)-1); cur_host[sizeof(cur_host)-1] = 0; } - if (!conn || protocol != PROTO_Z3950) - return 0; + if (only_z3950()) + return 1; send_initRequest(cur_host); return 2; } @@ -2476,11 +2498,6 @@ static int cmd_find(const char *arg) static int cmd_delete(const char *arg) { - if (!conn) - { - printf("Not connected yet\n"); - return 0; - } if (only_z3950()) return 0; if (!send_deleteResultSetRequest(arg)) @@ -2497,8 +2514,6 @@ static int cmd_ssub(const char *arg) static int cmd_lslb(const char *arg) { - if (only_z3950()) - return 0; if (!(largeSetLowerBound = atoi(arg))) return 0; return 1; @@ -2506,8 +2521,6 @@ static int cmd_lslb(const char *arg) static int cmd_mspn(const char *arg) { - if (only_z3950()) - return 0; if (!(mediumSetPresentNumber = atoi(arg))) return 0; return 1; @@ -2556,7 +2569,15 @@ static void parse_show_args(const char *arg_c, char *setstring, *p = '\0'; } if (*arg) - *start = atoi(arg); + { + if (!strcmp(arg, "all")) + { + *number = last_hit_count; + *start = 1; + } + else + *start = atoi(arg); + } if (p && (p=strchr(p+1, '+'))) strcpy (setstring, p+1); else if (setnumber >= 0) @@ -2582,10 +2603,11 @@ static int send_presentRequest(const char *arg) req->resultSetStartPoint = &setno; req->numberOfRecordsRequested = &nos; - req->preferredRecordSyntax = - yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax); + if (recordsyntax_size == 1) + req->preferredRecordSyntax = + yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax_list[0]); - if (record_schema) + if (record_schema || recordsyntax_size >= 2) { req->recordComposition = &compo; compo.which = Z_RecordComp_complex; @@ -2597,16 +2619,21 @@ static int send_presentRequest(const char *arg) compo.u.complex->generic = (Z_Specification *) odr_malloc(out, sizeof(*compo.u.complex->generic)); + compo.u.complex->generic->which = Z_Schema_oid; - - compo.u.complex->generic->schema.oid = - yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema); - - if (!compo.u.complex->generic->schema.oid) + if (!record_schema) + compo.u.complex->generic->schema.oid = 0; + else { - /* OID wasn't a schema! Try record syntax instead. */ - compo.u.complex->generic->schema.oid = (Odr_oid *) - yaz_str_to_z3950oid(out, CLASS_RECSYN, record_schema); + compo.u.complex->generic->schema.oid = + yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema); + + if (!compo.u.complex->generic->schema.oid) + { + /* OID wasn't a schema! Try record syntax instead. */ + compo.u.complex->generic->schema.oid = (Odr_oid *) + yaz_str_to_z3950oid(out, CLASS_RECSYN, record_schema); + } } if (!elementSetNames) compo.u.complex->generic->elementSpec = 0; @@ -2621,8 +2648,22 @@ static int send_presentRequest(const char *arg) } compo.u.complex->num_dbSpecific = 0; compo.u.complex->dbSpecific = 0; - compo.u.complex->num_recordSyntax = 0; - compo.u.complex->recordSyntax = 0; + if (recordsyntax_size >= 2) + { + int i; + compo.u.complex->num_recordSyntax = recordsyntax_size; + compo.u.complex->recordSyntax = (Odr_oid **) + odr_malloc(out, recordsyntax_size * sizeof(Odr_oid*)); + for (i = 0; i < recordsyntax_size; i++) + compo.u.complex->recordSyntax[i] = + yaz_oidval_to_z3950oid(out, CLASS_RECSYN, + recordsyntax_list[i]); + } + else + { + compo.u.complex->num_recordSyntax = 0; + compo.u.complex->recordSyntax = 0; + } } else if (elementSetNames) { @@ -2649,7 +2690,7 @@ static int send_SRW_presentRequest(const char *arg) sr->u.request->maximumRecords = odr_intdup(out, nos); if (record_schema) sr->u.request->recordSchema = record_schema; - if (recordsyntax == VAL_TEXT_XML) + if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML) sr->u.request->recordPacking = "xml"; return send_srw(sr); } @@ -2664,6 +2705,7 @@ static void close_session (void) odr_reset(out); odr_reset(in); odr_reset(print); + last_hit_count = 0; } void process_close(Z_Close *req) @@ -2740,12 +2782,11 @@ int cmd_cancel(const char *arg) Z_TriggerResourceControlRequest *req = apdu->u.triggerResourceControlRequest; bool_t rfalse = 0; - - if (!conn) - { - printf("Session not initialized yet\n"); - return 0; - } + char command[16]; + + *command = '\0'; + sscanf(arg, "%15s", command); + if (only_z3950()) return 0; if (session_initResponse && @@ -2761,7 +2802,9 @@ int cmd_cancel(const char *arg) send_apdu(apdu); printf("Sent cancel request\n"); - return 2; + if (!strcmp(command, "wait")) + return 2; + return 1; } @@ -2811,7 +2854,8 @@ int send_scanrequest(const char *query, int pp, int num, const char *term) const char *pqf_msg; size_t off; int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off); - printf("%*s^\n", off+7, ""); + int ioff = off; + printf("%*s^\n", ioff+7, ""); printf("Prefix query error: %s (code %d)\n", pqf_msg, code); yaz_pqf_destroy (pqf_parser); return -1; @@ -2968,11 +3012,6 @@ void process_deleteResultSetResponse (Z_DeleteResultSetResponse *res) int cmd_sort_generic(const char *arg, int newset) { - if (!conn) - { - printf("Session not initialized yet\n"); - return 0; - } if (only_z3950()) return 0; if (session_initResponse && @@ -3089,19 +3128,32 @@ int cmd_schema(const char *arg) int cmd_format(const char *arg) { - oid_value nsyntax; + const char *cp = arg; + int nor; + int idx = 0; + oid_value nsyntax[RECORDSYNTAX_MAX]; + char form_str[41]; if (!arg || !*arg) { printf("Usage: format \n"); return 0; } - nsyntax = oid_getvalbyname (arg); - if (strcmp(arg, "none") && nsyntax == VAL_NONE) + while (sscanf(cp, "%40s%n", form_str, &nor) >= 1 && nor > 0 + && idx < RECORDSYNTAX_MAX) { - printf ("unknown record syntax\n"); - return 0; + nsyntax[idx] = oid_getvalbyname(form_str); + if (!strcmp(form_str, "none")) + break; + if (nsyntax[idx] == VAL_NONE) + { + printf ("unknown record syntax: %s\n", form_str); + return 0; + } + cp += nor; + idx++; } - recordsyntax = nsyntax; + recordsyntax_size = idx; + memcpy(recordsyntax_list, nsyntax, idx * sizeof(*nsyntax)); return 1; } @@ -3178,11 +3230,8 @@ int cmd_close(const char *arg) { Z_APDU *apdu; Z_Close *req; - if (!conn) - return 0; if (only_z3950()) return 0; - apdu = zget_APDU(out, Z_APDU_close); req = apdu->u.close; *req->closeReason = Z_Close_finished; @@ -3203,8 +3252,8 @@ int cmd_packagename(const char* arg) int cmd_proxy(const char* arg) { - xfree (yazProxy); - yazProxy = NULL; + xfree(yazProxy); + yazProxy = 0; if (*arg) yazProxy = xstrdup (arg); return 1; @@ -3658,9 +3707,7 @@ static void initialize(void) #if HAVE_READLINE_READLINE_H rl_attempted_completion_function = (CPPFunction*)readline_completer; #endif - - - for(i=0; i=maxOtherInfosSupported) { @@ -4045,7 +4094,8 @@ int cmd_set_otherinfo(const char* args) } extraOtherInfos[otherinfoNo].oidval = -1; if (extraOtherInfos[otherinfoNo].value) - free(extraOtherInfos[otherinfoNo].value); + xfree(extraOtherInfos[otherinfoNo].value); + extraOtherInfos[otherinfoNo].value = 0; return 0; } if (sscan_res<3) { @@ -4054,18 +4104,20 @@ int cmd_set_otherinfo(const char* args) } if (otherinfoNo>=maxOtherInfosSupported) { - printf("Error otherinfo index to large (%d>%d)\n", + printf("Error otherinfo index too large (%d>=%d)\n", otherinfoNo,maxOtherInfosSupported); } oidval = oid_getvalbyname (oidstr); - if (oidval == -1 ) { + if (oidval == VAL_NONE) + { printf("Error in set_otherinfo command unknown oid %s \n",oidstr); return 0; } extraOtherInfos[otherinfoNo].oidval = oidval; - if(extraOtherInfos[otherinfoNo].value) free(extraOtherInfos[otherinfoNo].value); - extraOtherInfos[otherinfoNo].value = strdup(otherinfoString); + if (extraOtherInfos[otherinfoNo].value) + xfree(extraOtherInfos[otherinfoNo].value); + extraOtherInfos[otherinfoNo].value = xstrdup(otherinfoString); return 0; } @@ -4174,7 +4226,10 @@ int cmd_list_all(const char* args) { printf("ssub/lslb/mspn : %d/%d/%d\n",smallSetUpperBound,largeSetLowerBound,mediumSetPresentNumber); /* print present related options */ - printf("Format : %s\n",yaz_z3950_oid_value_to_str(recordsyntax,CLASS_RECSYN)); + printf("Format : %s\n", + (recordsyntax_size > 0) ? + yaz_z3950_oid_value_to_str(recordsyntax_list[0], CLASS_RECSYN) : + "none"); printf("Schema : %s\n",record_schema ? record_schema : "not set"); printf("Elements : %s\n",elementSetNames?elementSetNames->u.generic:""); @@ -4192,25 +4247,26 @@ int cmd_list_all(const char* args) { int cmd_clear_otherinfo(const char* args) { if(strlen(args)>0) { - int otherinfoNo; - otherinfoNo = atoi(args); - if( otherinfoNo >= maxOtherInfosSupported ) { - printf("Error otherinfo index to large (%d>%d)\n",otherinfoNo,maxOtherInfosSupported); + int otherinfoNo = atoi(args); + if (otherinfoNo >= maxOtherInfosSupported) { + printf("Error otherinfo index too large (%d>=%d)\n", + otherinfoNo, maxOtherInfosSupported); return 0; } - - if(extraOtherInfos[otherinfoNo].oidval != -1) { + if (extraOtherInfos[otherinfoNo].oidval != -1) + { /* only clear if set. */ - extraOtherInfos[otherinfoNo].oidval=-1; - free(extraOtherInfos[otherinfoNo].value); + extraOtherInfos[otherinfoNo].oidval = -1; + xfree(extraOtherInfos[otherinfoNo].value); } } else { int i; - - for(i=0; i