2 * Copyright (c) 1995-2002, Index Data
3 * See the file LICENSE for details.
5 * $Id: client.c,v 1.151 2002-05-03 13:48:27 adam Exp $
12 #include <yaz/yaz-util.h>
14 #include <yaz/tcpip.h>
16 #include <yaz/xmosi.h>
19 #include <yaz/proto.h>
20 #include <yaz/marcdisp.h>
21 #include <yaz/diagbib1.h>
22 #include <yaz/otherinfo.h>
24 #include <yaz/pquery.h>
25 #include <yaz/sortspec.h>
32 #include <yaz/yaz-ccl.h>
35 #if HAVE_READLINE_READLINE_H
36 #include <readline/readline.h>
38 #if HAVE_READLINE_HISTORY_H
39 #include <readline/history.h>
46 #include "tabcomplete.h"
48 #define C_PROMPT "Z> "
50 static ODR out, in, print; /* encoding and decoding streams */
51 static FILE *apdu_file = 0;
52 static COMSTACK conn = 0; /* our z-association */
53 static Z_IdAuthentication *auth = 0; /* our current auth definition */
54 char *databaseNames[128];
55 int num_databaseNames = 0;
56 static Z_External *record_last = 0;
57 static int setnumber = -1; /* current result set number */
58 static int smallSetUpperBound = 0;
59 static int largeSetLowerBound = 1;
60 static int mediumSetPresentNumber = 0;
61 static Z_ElementSetNames *elementSetNames = 0;
62 static int setno = 1; /* current set offset */
63 static enum oid_proto protocol = PROTO_Z3950; /* current app protocol */
64 static enum oid_value recordsyntax = VAL_USMARC;
65 static enum oid_value schema = VAL_NONE;
66 static int sent_close = 0;
67 static NMEM session_mem = NULL; /* memory handle for init-response */
68 static Z_InitResponse *session = 0; /* session parameters */
69 static char last_scan_line[512] = "0";
70 static char last_scan_query[512] = "0";
71 static char ccl_fields[512] = "default.bib";
72 static char* esPackageName = 0;
73 static char* yazProxy = 0;
74 static int kilobytes = 1024;
76 static char last_cmd[32] = "?";
77 static FILE *marcdump = 0;
78 static char *refid = NULL;
86 static QueryType queryType = QueryType_Prefix;
89 static CCL_bibset bibset; /* CCL bibset handle */
92 #if HAVE_READLINE_COMPLETION_OVER
95 /* readline doesn't have this var. Define it ourselves. */
96 int rl_attempted_completion_over = 0;
99 /* set this one to 1, to avoid decode of unknown MARCs */
100 #define AVOID_MARC_DECODE 1
102 /* nice helper macro as extensive tabbing gives spaces at the en of the args lines */
103 #define REMOVE_TAILING_BLANKS(a) {\
104 char* args_end=(a)+strlen(a)-1; \
105 while(isspace(*args_end)) {*args_end=0;--args_end;}; \
109 void process_cmd_line(char* line);
110 char ** readline_completer(char *text, int start, int end);
111 char *command_generator(const char *text, int state);
114 ODR getODROutputStream()
119 void send_apdu(Z_APDU *a)
126 z_APDU(print, &a, 0, 0);
129 if (!z_APDU(out, &a, 0, 0))
131 odr_perror(out, "Encoding APDU");
134 buf = odr_getbuf(out, &len, 0);
135 /* printf ("sending APDU of size %d\n", len); */
136 if (cs_put(conn, buf, len) < 0)
138 fprintf(stderr, "cs_put: %s", cs_errmsg(cs_errno(conn)));
141 odr_reset(out); /* release the APDU structure */
144 static void print_stringn(const unsigned char *buf, size_t len)
147 for (i = 0; i<len; i++)
148 if ((buf[i] <= 126 && buf[i] >= 32) || strchr ("\n\r\t\f", buf[i]))
149 printf ("%c", buf[i]);
151 printf ("\\X%02X", buf[i]);
154 static void print_refid (Z_ReferenceId *id)
158 printf ("Reference Id: ");
159 print_stringn (id->buf, id->len);
164 static Z_ReferenceId *set_refid (ODR out)
169 id = (Z_ReferenceId *) odr_malloc (out, sizeof(*id));
170 id->size = id->len = strlen(refid);
171 id->buf = (unsigned char *) odr_malloc (out, id->len);
172 memcpy (id->buf, refid, id->len);
176 /* INIT SERVICE ------------------------------- */
178 static void send_initRequest(const char* type_and_host)
180 Z_APDU *apdu = zget_APDU(out, Z_APDU_initRequest);
181 Z_InitRequest *req = apdu->u.initRequest;
183 ODR_MASK_SET(req->options, Z_Options_search);
184 ODR_MASK_SET(req->options, Z_Options_present);
185 ODR_MASK_SET(req->options, Z_Options_namedResultSets);
186 ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
187 ODR_MASK_SET(req->options, Z_Options_scan);
188 ODR_MASK_SET(req->options, Z_Options_sort);
189 ODR_MASK_SET(req->options, Z_Options_extendedServices);
190 ODR_MASK_SET(req->options, Z_Options_delSet);
192 ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
193 ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
194 ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
196 *req->maximumRecordSize = 1024*kilobytes;
197 *req->preferredMessageSize = 1024*kilobytes;
199 req->idAuthentication = auth;
201 req->referenceId = set_refid (out);
204 yaz_oi_set_string_oidval(&req->otherInfo, out, VAL_PROXY,
208 printf("Sent initrequest.\n");
211 static int process_initResponse(Z_InitResponse *res)
213 /* save session parameters for later use */
214 session_mem = odr_extract_mem(in);
218 printf("Connection rejected by target.\n");
220 printf("Connection accepted by target.\n");
221 if (res->implementationId)
222 printf("ID : %s\n", res->implementationId);
223 if (res->implementationName)
224 printf("Name : %s\n", res->implementationName);
225 if (res->implementationVersion)
226 printf("Version: %s\n", res->implementationVersion);
227 if (res->userInformationField)
229 printf("UserInformationfield:\n");
230 if (!z_External(print, (Z_External**)&res-> userInformationField,
233 odr_perror(print, "Printing userinfo\n");
236 if (res->userInformationField->which == Z_External_octet)
238 printf("Guessing visiblestring:\n");
239 printf("'%s'\n", res->userInformationField->u. octet_aligned->buf);
244 if (ODR_MASK_GET(res->options, Z_Options_search))
246 if (ODR_MASK_GET(res->options, Z_Options_present))
248 if (ODR_MASK_GET(res->options, Z_Options_delSet))
250 if (ODR_MASK_GET(res->options, Z_Options_resourceReport))
251 printf (" resourceReport");
252 if (ODR_MASK_GET(res->options, Z_Options_resourceCtrl))
253 printf (" resourceCtrl");
254 if (ODR_MASK_GET(res->options, Z_Options_accessCtrl))
255 printf (" accessCtrl");
256 if (ODR_MASK_GET(res->options, Z_Options_scan))
258 if (ODR_MASK_GET(res->options, Z_Options_sort))
260 if (ODR_MASK_GET(res->options, Z_Options_extendedServices))
261 printf (" extendedServices");
262 if (ODR_MASK_GET(res->options, Z_Options_level_1Segmentation))
263 printf (" level1Segmentation");
264 if (ODR_MASK_GET(res->options, Z_Options_level_2Segmentation))
265 printf (" level2Segmentation");
266 if (ODR_MASK_GET(res->options, Z_Options_concurrentOperations))
267 printf (" concurrentOperations");
268 if (ODR_MASK_GET(res->options, Z_Options_namedResultSets))
270 printf (" namedResultSets");
273 if (ODR_MASK_GET(res->options, Z_Options_encapsulation))
274 printf (" encapsulation");
275 if (ODR_MASK_GET(res->options, Z_Options_resultCount))
276 printf (" resultCount");
277 if (ODR_MASK_GET(res->options, Z_Options_negotiationModel))
278 printf (" negotiationModel");
279 if (ODR_MASK_GET(res->options, Z_Options_duplicateDetection))
280 printf (" duplicateDetection");
281 if (ODR_MASK_GET(res->options, Z_Options_queryType104))
282 printf (" queryType104");
288 static int cmd_base(char *arg)
295 printf("Usage: base <database> <database> ...\n");
298 for (i = 0; i<num_databaseNames; i++)
299 xfree (databaseNames[i]);
300 num_databaseNames = 0;
303 if (!(cp = strchr(arg, ' ')))
304 cp = arg + strlen(arg);
307 databaseNames[num_databaseNames] = (char *)xmalloc (1 + cp - arg);
308 memcpy (databaseNames[num_databaseNames], arg, cp - arg);
309 databaseNames[num_databaseNames++][cp - arg] = '\0';
317 int cmd_open(char *arg)
320 char type_and_host[101], base[101];
325 printf("Already connected.\n");
331 nmem_destroy (session_mem);
337 if (sscanf (arg, "%100[^/]/%100s", type_and_host, base) < 1)
341 conn = cs_create_host(yazProxy, 1, &add);
343 conn = cs_create_host(type_and_host, 1, &add);
347 printf ("Couldn't create comstack\n");
350 printf("Connecting...");
352 if (cs_connect(conn, add) < 0)
354 printf ("error = %s\n", cs_strerror(conn));
355 if (conn->cerrno == CSYSERR)
363 send_initRequest(type_and_host);
369 int cmd_authentication(char *arg)
371 static Z_IdAuthentication au;
372 static char user[40], group[40], pass[40];
373 static Z_IdPass idPass;
378 printf("Auth field set to null\n");
382 r = sscanf (arg, "%39s %39s %39s", user, group, pass);
385 printf("Auth field set to null\n");
391 au.which = Z_IdAuthentication_open;
397 au.which = Z_IdAuthentication_idPass;
398 au.u.idPass = &idPass;
399 idPass.groupId = group;
400 idPass.userId = user;
401 idPass.password = pass;
406 /* SEARCH SERVICE ------------------------------ */
408 static void display_variant(Z_Variant *v, int level)
412 for (i = 0; i < v->num_triples; i++)
414 printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->zclass,
415 *v->triples[i]->type);
416 if (v->triples[i]->which == Z_Triple_internationalString)
417 printf(",value=%s\n", v->triples[i]->value.internationalString);
423 static void display_grs1(Z_GenericRecord *r, int level)
429 for (i = 0; i < r->num_elements; i++)
433 printf("%*s", level * 4, "");
437 printf("%d,", *t->tagType);
440 if (t->tagValue->which == Z_StringOrNumeric_numeric)
441 printf("%d) ", *t->tagValue->u.numeric);
443 printf("%s) ", t->tagValue->u.string);
444 if (t->content->which == Z_ElementData_subtree)
447 display_grs1(t->content->u.subtree, level+1);
449 else if (t->content->which == Z_ElementData_string)
450 printf("%s\n", t->content->u.string);
451 else if (t->content->which == Z_ElementData_numeric)
452 printf("%d\n", *t->content->u.numeric);
453 else if (t->content->which == Z_ElementData_oid)
455 int *ip = t->content->u.oid;
458 if ((oent = oid_getentbyoid(t->content->u.oid)))
459 printf("OID: %s\n", oent->desc);
463 while (ip && *ip >= 0)
464 printf(" %d", *(ip++));
468 else if (t->content->which == Z_ElementData_noDataRequested)
469 printf("[No data requested]\n");
470 else if (t->content->which == Z_ElementData_elementEmpty)
471 printf("[Element empty]\n");
472 else if (t->content->which == Z_ElementData_elementNotThere)
473 printf("[Element not there]\n");
476 if (t->appliedVariant)
477 display_variant(t->appliedVariant, level+1);
478 if (t->metaData && t->metaData->supportedVariants)
482 printf("%*s---- variant list\n", (level+1)*4, "");
483 for (c = 0; c < t->metaData->num_supportedVariants; c++)
485 printf("%*svariant #%d\n", (level+1)*4, "", c);
486 display_variant(t->metaData->supportedVariants[c], level + 2);
493 static void print_record(const unsigned char *buf, size_t len)
496 print_stringn (buf, len);
497 /* add newline if not already added ... */
498 if (i <= 0 || buf[i-1] != '\n')
502 static void display_record(Z_External *r)
504 oident *ent = oid_getentbyoid(r->direct_reference);
508 * Tell the user what we got.
510 if (r->direct_reference)
512 printf("Record type: ");
514 printf("%s\n", ent->desc);
515 else if (!odr_oid(print, &r->direct_reference, 0, 0))
517 odr_perror(print, "print oid");
521 /* Check if this is a known, ASN.1 type tucked away in an octet string */
522 if (ent && r->which == Z_External_octet)
524 Z_ext_typeent *type = z_ext_getentbyref(ent->value);
530 * Call the given decoder to process the record.
532 odr_setbuf(in, (char*)r->u.octet_aligned->buf,
533 r->u.octet_aligned->len, 0);
534 if (!(*type->fun)(in, (char **)&rr, 0, 0))
536 odr_perror(in, "Decoding constructed record.");
537 fprintf(stderr, "[Near %d]\n", odr_offset(in));
538 fprintf(stderr, "Packet dump:\n---------\n");
539 odr_dumpBER(stderr, (char*)r->u.octet_aligned->buf,
540 r->u.octet_aligned->len);
541 fprintf(stderr, "---------\n");
545 * Note: we throw away the original, BER-encoded record here.
546 * Do something else with it if you want to keep it.
548 r->u.sutrs = (Z_SUTRS *) rr; /* we don't actually check the type here. */
549 r->which = type->what;
552 if (ent && ent->value == VAL_SOIF)
553 print_record((const unsigned char *) r->u.octet_aligned->buf,
554 r->u.octet_aligned->len);
555 else if (r->which == Z_External_octet && r->u.octet_aligned->len)
557 const char *octet_buf = (char*)r->u.octet_aligned->buf;
558 if (ent->value == VAL_TEXT_XML || ent->value == VAL_APPLICATION_XML ||
559 ent->value == VAL_HTML)
561 print_record((const unsigned char *) octet_buf,
562 r->u.octet_aligned->len);
564 else if (ent->value == VAL_POSTSCRIPT)
566 int size = r->u.octet_aligned->len;
569 print_record((const unsigned char *) octet_buf, size);
574 #if AVOID_MARC_DECODE
575 /* primitive check for a marc OID 5.1-29 except 16 */
576 ent->oidsuffix[0] == 5 && ent->oidsuffix[1] < 30 &&
577 ent->oidsuffix[1] != 16
583 if (marc_display_exl (octet_buf, NULL, 0 /* debug */,
584 r->u.octet_aligned->len) <= 0)
586 printf ("bad MARC. Dumping as it is:\n");
587 print_record((const unsigned char*) octet_buf,
588 r->u.octet_aligned->len);
593 print_record((const unsigned char*) octet_buf,
594 r->u.octet_aligned->len);
598 fwrite (octet_buf, 1, r->u.octet_aligned->len, marcdump);
600 else if (ent && ent->value == VAL_SUTRS)
602 if (r->which != Z_External_sutrs)
604 printf("Expecting single SUTRS type for SUTRS.\n");
607 print_record(r->u.sutrs->buf, r->u.sutrs->len);
609 else if (ent && ent->value == VAL_GRS1)
611 if (r->which != Z_External_grs1)
613 printf("Expecting single GRS type for GRS.\n");
616 display_grs1(r->u.grs1, 0);
620 printf("Unknown record representation.\n");
621 if (!z_External(print, &r, 0, 0))
623 odr_perror(print, "Printing external");
629 static void display_diagrecs(Z_DiagRec **pp, int num)
633 Z_DefaultDiagFormat *r;
635 printf("Diagnostic message(s) from database:\n");
636 for (i = 0; i<num; i++)
638 Z_DiagRec *p = pp[i];
639 if (p->which != Z_DiagRec_defaultFormat)
641 printf("Diagnostic record not in default format.\n");
645 r = p->u.defaultFormat;
646 if (!(ent = oid_getentbyoid(r->diagnosticSetId)) ||
647 ent->oclass != CLASS_DIAGSET || ent->value != VAL_BIB1)
648 printf("Missing or unknown diagset\n");
649 printf(" [%d] %s", *r->condition, diagbib1_str(*r->condition));
652 case Z_DefaultDiagFormat_v2Addinfo:
653 printf (" -- v2 addinfo '%s'\n", r->u.v2Addinfo);
655 case Z_DefaultDiagFormat_v3Addinfo:
656 printf (" -- v3 addinfo '%s'\n", r->u.v3Addinfo);
663 static void display_nameplusrecord(Z_NamePlusRecord *p)
666 printf("[%s]", p->databaseName);
667 if (p->which == Z_NamePlusRecord_surrogateDiagnostic)
668 display_diagrecs(&p->u.surrogateDiagnostic, 1);
669 else if (p->which == Z_NamePlusRecord_databaseRecord)
670 display_record(p->u.databaseRecord);
673 static void display_records(Z_Records *p)
677 if (p->which == Z_Records_NSD)
679 Z_DiagRec dr, *dr_p = &dr;
680 dr.which = Z_DiagRec_defaultFormat;
681 dr.u.defaultFormat = p->u.nonSurrogateDiagnostic;
682 display_diagrecs (&dr_p, 1);
684 else if (p->which == Z_Records_multipleNSD)
685 display_diagrecs (p->u.multipleNonSurDiagnostics->diagRecs,
686 p->u.multipleNonSurDiagnostics->num_diagRecs);
689 printf("Records: %d\n", p->u.databaseOrSurDiagnostics->num_records);
690 for (i = 0; i < p->u.databaseOrSurDiagnostics->num_records; i++)
691 display_nameplusrecord(p->u.databaseOrSurDiagnostics->records[i]);
695 static int send_deleteResultSetRequest(char *arg)
700 Z_APDU *apdu = zget_APDU(out, Z_APDU_deleteResultSetRequest);
701 Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
703 req->referenceId = set_refid (out);
705 req->num_resultSetList =
706 sscanf (arg, "%30s %30s %30s %30s %30s %30s %30s %30s",
707 names[0], names[1], names[2], names[3],
708 names[4], names[5], names[6], names[7]);
710 req->deleteFunction = (int *)
711 odr_malloc (out, sizeof(*req->deleteFunction));
712 if (req->num_resultSetList > 0)
714 *req->deleteFunction = Z_DeleteRequest_list;
715 req->resultSetList = (char **)
716 odr_malloc (out, sizeof(*req->resultSetList)*
717 req->num_resultSetList);
718 for (i = 0; i<req->num_resultSetList; i++)
719 req->resultSetList[i] = names[i];
723 *req->deleteFunction = Z_DeleteRequest_all;
724 req->resultSetList = 0;
728 printf("Sent deleteResultSetRequest.\n");
732 static int send_searchRequest(char *arg)
734 Z_APDU *apdu = zget_APDU(out, Z_APDU_searchRequest);
735 Z_SearchRequest *req = apdu->u.searchRequest;
739 struct ccl_rpn_node *rpn = NULL;
743 Z_RPNQuery *RPNquery;
747 if (queryType == QueryType_CCL2RPN)
749 rpn = ccl_find_str(bibset, arg, &error, &pos);
752 printf("CCL ERROR: %s\n", ccl_err_msg(error));
757 req->referenceId = set_refid (out);
758 if (!strcmp(arg, "@big")) /* strictly for troublemaking */
760 static unsigned char big[2100];
763 /* send a very big referenceid to test transport stack etc. */
764 memset(big, 'A', 2100);
765 bigo.len = bigo.size = 2100;
767 req->referenceId = &bigo;
772 sprintf(setstring, "%d", ++setnumber);
773 req->resultSetName = setstring;
775 *req->smallSetUpperBound = smallSetUpperBound;
776 *req->largeSetLowerBound = largeSetLowerBound;
777 *req->mediumSetPresentNumber = mediumSetPresentNumber;
778 if (smallSetUpperBound > 0 || (largeSetLowerBound > 1 &&
779 mediumSetPresentNumber > 0))
783 prefsyn.proto = protocol;
784 prefsyn.oclass = CLASS_RECSYN;
785 prefsyn.value = recordsyntax;
786 req->preferredRecordSyntax =
787 odr_oiddup(out, oid_ent_to_oid(&prefsyn, oid));
788 req->smallSetElementSetNames =
789 req->mediumSetElementSetNames = elementSetNames;
791 req->num_databaseNames = num_databaseNames;
792 req->databaseNames = databaseNames;
798 case QueryType_Prefix:
799 query.which = Z_Query_type_1;
800 RPNquery = p_query_rpn (out, protocol, arg);
803 printf("Prefix query error\n");
806 query.u.type_1 = RPNquery;
809 query.which = Z_Query_type_2;
810 query.u.type_2 = &ccl_query;
811 ccl_query.buf = (unsigned char*) arg;
812 ccl_query.len = strlen(arg);
815 case QueryType_CCL2RPN:
816 query.which = Z_Query_type_1;
817 RPNquery = ccl_rpn_query(out, rpn);
820 printf ("Couldn't convert from CCL to RPN\n");
823 query.u.type_1 = RPNquery;
824 ccl_rpn_delete (rpn);
828 printf ("Unsupported query type\n");
833 printf("Sent searchRequest.\n");
837 /* display Query Expression as part of searchResult-1 */
838 static void display_queryExpression (Z_QueryExpression *qe)
842 if (qe->which == Z_QueryExpression_term)
844 if (qe->u.term->queryTerm)
846 Z_Term *term = qe->u.term->queryTerm;
847 if (term->which == Z_Term_general)
848 printf (" %.*s", term->u.general->len, term->u.general->buf);
854 /* see if we can find USR:SearchResult-1 */
855 static void display_searchResult (Z_OtherInformation *o)
860 for (i = 0; i < o->num_elements; i++)
862 if (o->list[i]->which == Z_OtherInfo_externallyDefinedInfo)
864 Z_External *ext = o->list[i]->information.externallyDefinedInfo;
866 if (ext->which == Z_External_searchResult1)
869 Z_SearchInfoReport *sr = ext->u.searchResult1;
870 printf ("SearchResult-1:");
871 for (j = 0; j < sr->num; j++)
873 if (!sr->elements[j]->subqueryExpression)
875 display_queryExpression (
876 sr->elements[j]->subqueryExpression);
877 display_queryExpression (
878 sr->elements[j]->subqueryInterpretation);
879 display_queryExpression (
880 sr->elements[j]->subqueryRecommendation);
881 if (sr->elements[j]->subqueryCount)
882 printf ("(%d)", *sr->elements[j]->subqueryCount);
890 static int process_searchResponse(Z_SearchResponse *res)
892 printf ("Received SearchResponse.\n");
893 print_refid (res->referenceId);
894 if (*res->searchStatus)
895 printf("Search was a success.\n");
897 printf("Search was a bloomin' failure.\n");
898 printf("Number of hits: %d", *res->resultCount);
900 printf (", setno %d", setnumber);
902 display_searchResult (res->additionalSearchInfo);
903 printf("records returned: %d\n",
904 *res->numberOfRecordsReturned);
905 setno += *res->numberOfRecordsReturned;
907 display_records(res->records);
911 static void print_level(int iLevel)
914 for (i = 0; i < iLevel * 4; i++)
918 static void print_int(int iLevel, const char *pTag, int *pInt)
923 printf("%s: %d\n", pTag, *pInt);
927 static void print_string(int iLevel, const char *pTag, const char *pString)
932 printf("%s: %s\n", pTag, pString);
936 static void print_oid(int iLevel, const char *pTag, Odr_oid *pOid)
944 for (; *pInt != -1; pInt++)
945 printf(" %d", *pInt);
950 static void print_referenceId(int iLevel, Z_ReferenceId *referenceId)
952 if (referenceId != NULL)
957 printf("Ref Id (%d, %d): ", referenceId->len, referenceId->size);
958 for (i = 0; i < referenceId->len; i++)
959 printf("%c", referenceId->buf[i]);
964 static void print_string_or_numeric(int iLevel, const char *pTag, Z_StringOrNumeric *pStringNumeric)
966 if (pStringNumeric != NULL)
968 switch (pStringNumeric->which)
970 case Z_StringOrNumeric_string:
971 print_string(iLevel, pTag, pStringNumeric->u.string);
974 case Z_StringOrNumeric_numeric:
975 print_int(iLevel, pTag, pStringNumeric->u.numeric);
980 printf("%s: valid type for Z_StringOrNumeric\n", pTag);
986 static void print_universe_report_duplicate(int iLevel, Z_UniverseReportDuplicate *pUniverseReportDuplicate)
988 if (pUniverseReportDuplicate != NULL)
991 printf("Universe Report Duplicate: \n");
993 print_string_or_numeric(iLevel, "Hit No",
994 pUniverseReportDuplicate->hitno);
999 print_universe_report_hits(int iLevel,
1000 Z_UniverseReportHits *pUniverseReportHits)
1002 if (pUniverseReportHits != NULL)
1004 print_level(iLevel);
1005 printf("Universe Report Hits: \n");
1007 print_string_or_numeric(iLevel, "Database",
1008 pUniverseReportHits->database);
1009 print_string_or_numeric(iLevel, "Hits", pUniverseReportHits->hits);
1013 static void print_universe_report(int iLevel, Z_UniverseReport *pUniverseReport)
1015 if (pUniverseReport != NULL)
1017 print_level(iLevel);
1018 printf("Universe Report: \n");
1020 print_int(iLevel, "Total Hits", pUniverseReport->totalHits);
1021 switch (pUniverseReport->which)
1023 case Z_UniverseReport_databaseHits:
1024 print_universe_report_hits(iLevel, pUniverseReport->u.databaseHits);
1027 case Z_UniverseReport_duplicate:
1028 print_universe_report_duplicate(iLevel, pUniverseReport->u.duplicate);
1032 print_level(iLevel);
1033 printf("Type: %d\n", pUniverseReport->which);
1039 static void print_external(int iLevel, Z_External *pExternal)
1041 if (pExternal != NULL)
1043 print_level(iLevel);
1044 printf("External: \n");
1046 print_oid(iLevel, "Direct Reference", pExternal->direct_reference);
1047 print_int(iLevel, "InDirect Reference", pExternal->indirect_reference);
1048 print_string(iLevel, "Descriptor", pExternal->descriptor);
1049 switch (pExternal->which)
1051 case Z_External_universeReport:
1052 print_universe_report(iLevel, pExternal->u.universeReport);
1056 print_level(iLevel);
1057 printf("Type: %d\n", pExternal->which);
1063 static int process_resourceControlRequest (Z_ResourceControlRequest *req)
1065 printf ("Received ResourceControlRequest.\n");
1066 print_referenceId(1, req->referenceId);
1067 print_int(1, "Suspended Flag", req->suspendedFlag);
1068 print_int(1, "Partial Results Available", req->partialResultsAvailable);
1069 print_int(1, "Response Required", req->responseRequired);
1070 print_int(1, "Triggered Request Flag", req->triggeredRequestFlag);
1071 print_external(1, req->resourceReport);
1075 void process_ESResponse(Z_ExtendedServicesResponse *res)
1078 switch (*res->operationStatus)
1080 case Z_ExtendedServicesResponse_done:
1083 case Z_ExtendedServicesResponse_accepted:
1084 printf ("accepted\n");
1086 case Z_ExtendedServicesResponse_failure:
1087 printf ("failure\n");
1088 display_diagrecs(res->diagnostics, res->num_diagnostics);
1091 printf ("unknown\n");
1093 if ( (*res->operationStatus != Z_ExtendedServicesResponse_failure) &&
1094 (res->num_diagnostics != 0) ) {
1095 display_diagrecs(res->diagnostics, res->num_diagnostics);
1097 print_refid (res->referenceId);
1098 if (res->taskPackage &&
1099 res->taskPackage->which == Z_External_extendedService)
1101 Z_TaskPackage *taskPackage = res->taskPackage->u.extendedService;
1102 Odr_oct *id = taskPackage->targetReference;
1103 Z_External *ext = taskPackage->taskSpecificParameters;
1107 printf ("Target Reference: ");
1108 print_stringn (id->buf, id->len);
1111 if (ext->which == Z_External_update)
1113 Z_IUUpdateTaskPackage *utp = ext->u.update->u.taskPackage;
1114 if (utp && utp->targetPart)
1116 Z_IUTargetPart *targetPart = utp->targetPart;
1119 for (i = 0; i<targetPart->num_taskPackageRecords; i++)
1122 Z_IUTaskPackageRecordStructure *tpr =
1123 targetPart->taskPackageRecords[i];
1124 printf ("task package record %d\n", i+1);
1125 if (tpr->which == Z_IUTaskPackageRecordStructure_record)
1127 display_record (tpr->u.record);
1131 printf ("other type\n");
1141 const char *get_ill_element (void *clientData, const char *element)
1146 static Z_External *create_external_itemRequest()
1148 struct ill_get_ctl ctl;
1149 ILL_ItemRequest *req;
1151 int item_request_size = 0;
1152 char *item_request_buf = 0;
1156 ctl.f = get_ill_element;
1158 req = ill_get_ItemRequest(&ctl, "ill", 0);
1160 printf ("ill_get_ItemRequest failed\n");
1162 if (!ill_ItemRequest (out, &req, 0, 0))
1166 ill_ItemRequest(print, &req, 0, 0);
1169 item_request_buf = odr_getbuf (out, &item_request_size, 0);
1170 if (item_request_buf)
1171 odr_setbuf (out, item_request_buf, item_request_size, 1);
1172 printf ("Couldn't encode ItemRequest, size %d\n", item_request_size);
1179 item_request_buf = odr_getbuf (out, &item_request_size, 0);
1180 oid.proto = PROTO_GENERAL;
1181 oid.oclass = CLASS_GENERAL;
1182 oid.value = VAL_ISO_ILL_1;
1184 r = (Z_External *) odr_malloc (out, sizeof(*r));
1185 r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid));
1186 r->indirect_reference = 0;
1188 r->which = Z_External_single;
1190 r->u.single_ASN1_type = (Odr_oct *)
1191 odr_malloc (out, sizeof(*r->u.single_ASN1_type));
1192 r->u.single_ASN1_type->buf = (unsigned char *)
1193 odr_malloc (out, item_request_size);
1194 r->u.single_ASN1_type->len = item_request_size;
1195 r->u.single_ASN1_type->size = item_request_size;
1196 memcpy (r->u.single_ASN1_type->buf, item_request_buf,
1198 printf ("len = %d\n", item_request_size);
1204 #ifdef YAZ_MODULE_ill
1205 static Z_External *create_external_ILL_APDU(int which)
1207 struct ill_get_ctl ctl;
1210 int ill_request_size = 0;
1211 char *ill_request_buf = 0;
1215 ctl.f = get_ill_element;
1217 ill_apdu = ill_get_APDU(&ctl, "ill", 0);
1219 if (!ill_APDU (out, &ill_apdu, 0, 0))
1223 printf ("-------------------\n");
1224 ill_APDU(print, &ill_apdu, 0, 0);
1226 printf ("-------------------\n");
1228 ill_request_buf = odr_getbuf (out, &ill_request_size, 0);
1229 if (ill_request_buf)
1230 odr_setbuf (out, ill_request_buf, ill_request_size, 1);
1231 printf ("Couldn't encode ILL-Request, size %d\n", ill_request_size);
1237 ill_request_buf = odr_getbuf (out, &ill_request_size, 0);
1239 oid.proto = PROTO_GENERAL;
1240 oid.oclass = CLASS_GENERAL;
1241 oid.value = VAL_ISO_ILL_1;
1243 r = (Z_External *) odr_malloc (out, sizeof(*r));
1244 r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid));
1245 r->indirect_reference = 0;
1247 r->which = Z_External_single;
1249 r->u.single_ASN1_type = (Odr_oct *)
1250 odr_malloc (out, sizeof(*r->u.single_ASN1_type));
1251 r->u.single_ASN1_type->buf = (unsigned char *)
1252 odr_malloc (out, ill_request_size);
1253 r->u.single_ASN1_type->len = ill_request_size;
1254 r->u.single_ASN1_type->size = ill_request_size;
1255 memcpy (r->u.single_ASN1_type->buf, ill_request_buf, ill_request_size);
1256 printf ("len = %d\n", ill_request_size);
1263 static Z_External *create_ItemOrderExternal(const char *type, int itemno)
1265 Z_External *r = (Z_External *) odr_malloc(out, sizeof(Z_External));
1266 oident ItemOrderRequest;
1268 ItemOrderRequest.proto = PROTO_Z3950;
1269 ItemOrderRequest.oclass = CLASS_EXTSERV;
1270 ItemOrderRequest.value = VAL_ITEMORDER;
1272 r->direct_reference = odr_oiddup(out,oid_getoidbyent(&ItemOrderRequest));
1273 r->indirect_reference = 0;
1276 r->which = Z_External_itemOrder;
1278 r->u.itemOrder = (Z_ItemOrder *) odr_malloc(out,sizeof(Z_ItemOrder));
1279 memset(r->u.itemOrder, 0, sizeof(Z_ItemOrder));
1280 r->u.itemOrder->which=Z_IOItemOrder_esRequest;
1282 r->u.itemOrder->u.esRequest = (Z_IORequest *)
1283 odr_malloc(out,sizeof(Z_IORequest));
1284 memset(r->u.itemOrder->u.esRequest, 0, sizeof(Z_IORequest));
1286 r->u.itemOrder->u.esRequest->toKeep = (Z_IOOriginPartToKeep *)
1287 odr_malloc(out,sizeof(Z_IOOriginPartToKeep));
1288 memset(r->u.itemOrder->u.esRequest->toKeep, 0, sizeof(Z_IOOriginPartToKeep));
1289 r->u.itemOrder->u.esRequest->notToKeep = (Z_IOOriginPartNotToKeep *)
1290 odr_malloc(out,sizeof(Z_IOOriginPartNotToKeep));
1291 memset(r->u.itemOrder->u.esRequest->notToKeep, 0, sizeof(Z_IOOriginPartNotToKeep));
1293 r->u.itemOrder->u.esRequest->toKeep->supplDescription = NULL;
1294 r->u.itemOrder->u.esRequest->toKeep->contact = NULL;
1295 r->u.itemOrder->u.esRequest->toKeep->addlBilling = NULL;
1297 r->u.itemOrder->u.esRequest->notToKeep->resultSetItem =
1298 (Z_IOResultSetItem *) odr_malloc(out, sizeof(Z_IOResultSetItem));
1299 memset(r->u.itemOrder->u.esRequest->notToKeep->resultSetItem, 0, sizeof(Z_IOResultSetItem));
1300 r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->resultSetId = "1";
1302 r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->item =
1303 (int *) odr_malloc(out, sizeof(int));
1304 *r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->item = itemno;
1307 if (!strcmp (type, "item") || !strcmp(type, "2"))
1309 printf ("using item-request\n");
1310 r->u.itemOrder->u.esRequest->notToKeep->itemRequest =
1311 create_external_itemRequest();
1313 else if (!strcmp(type, "ill") || !strcmp(type, "1"))
1315 printf ("using ILL-request\n");
1316 r->u.itemOrder->u.esRequest->notToKeep->itemRequest =
1317 create_external_ILL_APDU(ILL_APDU_ILL_Request);
1319 else if (!strcmp(type, "xml") || !strcmp(type, "3"))
1321 const char *xml_buf =
1323 " <type>request</type>\n"
1324 " <libraryNo>000200</libraryNo>\n"
1325 " <borrowerTicketNo> 1212 </borrowerTicketNo>\n"
1327 r->u.itemOrder->u.esRequest->notToKeep->itemRequest =
1328 z_ext_record (out, VAL_TEXT_XML, xml_buf, strlen(xml_buf));
1331 r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 0;
1334 r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 0;
1339 static int send_itemorder(const char *type, int itemno)
1341 Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest);
1342 Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
1343 oident ItemOrderRequest;
1345 ItemOrderRequest.proto = PROTO_Z3950;
1346 ItemOrderRequest.oclass = CLASS_EXTSERV;
1347 ItemOrderRequest.value = VAL_ITEMORDER;
1348 req->packageType = odr_oiddup(out,oid_getoidbyent(&ItemOrderRequest));
1349 req->packageName = esPackageName;
1351 req->taskSpecificParameters = create_ItemOrderExternal(type, itemno);
1357 static int cmd_update(char *arg)
1359 Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest );
1360 Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
1363 Z_IUOriginPartToKeep *toKeep;
1364 Z_IUSuppliedRecords *notToKeep;
1366 printf ("Update request\n");
1371 update_oid.proto = PROTO_Z3950;
1372 update_oid.oclass = CLASS_EXTSERV;
1373 update_oid.value = VAL_DBUPDATE;
1374 oid_ent_to_oid (&update_oid, oid);
1375 req->packageType = odr_oiddup(out,oid);
1376 req->packageName = esPackageName;
1378 req->referenceId = set_refid (out);
1380 r = req->taskSpecificParameters = (Z_External *)
1381 odr_malloc (out, sizeof(*r));
1382 r->direct_reference = odr_oiddup(out,oid);
1383 r->indirect_reference = 0;
1385 r->which = Z_External_update;
1386 r->u.update = (Z_IUUpdate *) odr_malloc(out, sizeof(*r->u.update));
1387 r->u.update->which = Z_IUUpdate_esRequest;
1388 r->u.update->u.esRequest = (Z_IUUpdateEsRequest *)
1389 odr_malloc(out, sizeof(*r->u.update->u.esRequest));
1390 toKeep = r->u.update->u.esRequest->toKeep = (Z_IUOriginPartToKeep *)
1391 odr_malloc(out, sizeof(*r->u.update->u.esRequest->toKeep));
1392 toKeep->databaseName = databaseNames[0];
1394 toKeep->elementSetName = 0;
1395 toKeep->actionQualifier = 0;
1396 toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
1397 *toKeep->action = Z_IUOriginPartToKeep_recordInsert;
1399 notToKeep = r->u.update->u.esRequest->notToKeep = (Z_IUSuppliedRecords *)
1400 odr_malloc(out, sizeof(*r->u.update->u.esRequest->notToKeep));
1402 notToKeep->elements = (Z_IUSuppliedRecords_elem **)
1403 odr_malloc(out, sizeof(*notToKeep->elements));
1404 notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *)
1405 odr_malloc(out, sizeof(**notToKeep->elements));
1406 notToKeep->elements[0]->u.number = 0;
1407 notToKeep->elements[0]->supplementalId = 0;
1408 notToKeep->elements[0]->correlationInfo = 0;
1409 notToKeep->elements[0]->record = record_last;
1416 static int cmd_itemorder(char *arg)
1421 if (sscanf (arg, "%10s %d", type, &itemno) != 2)
1424 printf("Item order request\n");
1426 send_itemorder(type, itemno);
1430 static int cmd_find(char *arg)
1434 printf("Find what?\n");
1439 printf("Not connected yet\n");
1442 if (!send_searchRequest(arg))
1447 static int cmd_delete(char *arg)
1451 printf("Not connected yet\n");
1454 if (!send_deleteResultSetRequest(arg))
1459 static int cmd_ssub(char *arg)
1461 if (!(smallSetUpperBound = atoi(arg)))
1466 static int cmd_lslb(char *arg)
1468 if (!(largeSetLowerBound = atoi(arg)))
1473 static int cmd_mspn(char *arg)
1475 if (!(mediumSetPresentNumber = atoi(arg)))
1480 static int cmd_status(char *arg)
1482 printf("smallSetUpperBound: %d\n", smallSetUpperBound);
1483 printf("largeSetLowerBound: %d\n", largeSetLowerBound);
1484 printf("mediumSetPresentNumber: %d\n", mediumSetPresentNumber);
1488 static int cmd_setnames(char *arg)
1490 if (*arg == '1') /* enable ? */
1492 else if (*arg == '0') /* disable ? */
1494 else if (setnumber < 0) /* no args, toggle .. */
1500 printf("Set numbering enabled.\n");
1502 printf("Set numbering disabled.\n");
1506 /* PRESENT SERVICE ----------------------------- */
1508 static int send_presentRequest(char *arg)
1510 Z_APDU *apdu = zget_APDU(out, Z_APDU_presentRequest);
1511 Z_PresentRequest *req = apdu->u.presentRequest;
1512 Z_RecordComposition compo;
1517 char setstring[100];
1519 req->referenceId = set_refid (out);
1520 if ((p = strchr(arg, '+')))
1527 if (p && (p=strchr(p+1, '+')))
1529 strcpy (setstring, p+1);
1530 req->resultSetId = setstring;
1532 else if (setnumber >= 0)
1534 sprintf(setstring, "%d", setnumber);
1535 req->resultSetId = setstring;
1537 req->resultSetStartPoint = &setno;
1538 req->numberOfRecordsRequested = &nos;
1539 prefsyn.proto = protocol;
1540 prefsyn.oclass = CLASS_RECSYN;
1541 prefsyn.value = recordsyntax;
1542 req->preferredRecordSyntax =
1543 odr_oiddup (out, oid_ent_to_oid(&prefsyn, oid));
1545 if (schema != VAL_NONE)
1549 prefschema.proto = protocol;
1550 prefschema.oclass = CLASS_SCHEMA;
1551 prefschema.value = schema;
1553 req->recordComposition = &compo;
1554 compo.which = Z_RecordComp_complex;
1555 compo.u.complex = (Z_CompSpec *)
1556 odr_malloc(out, sizeof(*compo.u.complex));
1557 compo.u.complex->selectAlternativeSyntax = (bool_t *)
1558 odr_malloc(out, sizeof(bool_t));
1559 *compo.u.complex->selectAlternativeSyntax = 0;
1561 compo.u.complex->generic = (Z_Specification *)
1562 odr_malloc(out, sizeof(*compo.u.complex->generic));
1563 compo.u.complex->generic->schema = (Odr_oid *)
1564 odr_oiddup(out, oid_ent_to_oid(&prefschema, oid));
1565 if (!compo.u.complex->generic->schema)
1567 /* OID wasn't a schema! Try record syntax instead. */
1568 prefschema.oclass = CLASS_RECSYN;
1569 compo.u.complex->generic->schema = (Odr_oid *)
1570 odr_oiddup(out, oid_ent_to_oid(&prefschema, oid));
1572 if (!elementSetNames)
1573 compo.u.complex->generic->elementSpec = 0;
1576 compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
1577 odr_malloc(out, sizeof(Z_ElementSpec));
1578 compo.u.complex->generic->elementSpec->which =
1579 Z_ElementSpec_elementSetName;
1580 compo.u.complex->generic->elementSpec->u.elementSetName =
1581 elementSetNames->u.generic;
1583 compo.u.complex->num_dbSpecific = 0;
1584 compo.u.complex->dbSpecific = 0;
1585 compo.u.complex->num_recordSyntax = 0;
1586 compo.u.complex->recordSyntax = 0;
1588 else if (elementSetNames)
1590 req->recordComposition = &compo;
1591 compo.which = Z_RecordComp_simple;
1592 compo.u.simple = elementSetNames;
1595 printf("Sent presentRequest (%d+%d).\n", setno, nos);
1599 static void close_session (void)
1605 nmem_destroy (session_mem);
1611 void process_close(Z_Close *req)
1613 Z_APDU *apdu = zget_APDU(out, Z_APDU_close);
1614 Z_Close *res = apdu->u.close;
1616 static char *reasons[] =
1621 "cost limit reached",
1623 "security violation",
1630 printf("Reason: %s, message: %s\n", reasons[*req->closeReason],
1631 req->diagnosticInformation ? req->diagnosticInformation : "NULL");
1636 *res->closeReason = Z_Close_finished;
1638 printf("Sent response.\n");
1643 static int cmd_show(char *arg)
1647 printf("Not connected yet\n");
1650 if (!send_presentRequest(arg))
1655 int cmd_quit(char *arg)
1657 printf("See you later, alligator.\n");
1663 int cmd_cancel(char *arg)
1665 Z_APDU *apdu = zget_APDU(out, Z_APDU_triggerResourceControlRequest);
1666 Z_TriggerResourceControlRequest *req =
1667 apdu->u.triggerResourceControlRequest;
1672 printf("Session not initialized yet\n");
1675 if (!ODR_MASK_GET(session->options, Z_Options_triggerResourceCtrl))
1677 printf("Target doesn't support cancel (trigger resource ctrl)\n");
1680 *req->requestedAction = Z_TriggerResourceCtrl_cancel;
1681 req->resultSetWanted = &rfalse;
1684 printf("Sent cancel request\n");
1688 int send_scanrequest(const char *query, int pp, int num, const char *term)
1690 Z_APDU *apdu = zget_APDU(out, Z_APDU_scanRequest);
1691 Z_ScanRequest *req = apdu->u.scanRequest;
1696 if (queryType == QueryType_CCL2RPN)
1700 struct ccl_rpn_node *rpn;
1702 rpn = ccl_find_str (bibset, query, &error, &pos);
1705 printf("CCL ERROR: %s\n", ccl_err_msg(error));
1709 bib1.proto = PROTO_Z3950;
1710 bib1.oclass = CLASS_ATTSET;
1711 bib1.value = VAL_BIB1;
1712 req->attributeSet = oid_ent_to_oid (&bib1, oid);
1713 if (!(req->termListAndStartPoint = ccl_scan_query (out, rpn)))
1715 printf("Couldn't convert CCL to Scan term\n");
1718 ccl_rpn_delete (rpn);
1721 if (use_rpn && !(req->termListAndStartPoint =
1722 p_query_scan(out, protocol, &req->attributeSet, query)))
1724 printf("Prefix query error\n");
1729 if (req->termListAndStartPoint->term &&
1730 req->termListAndStartPoint->term->which == Z_Term_general &&
1731 req->termListAndStartPoint->term->u.general)
1733 req->termListAndStartPoint->term->u.general->buf =
1734 (unsigned char *) odr_strdup(out, term);
1735 req->termListAndStartPoint->term->u.general->len =
1736 req->termListAndStartPoint->term->u.general->size =
1740 req->referenceId = set_refid (out);
1741 req->num_databaseNames = num_databaseNames;
1742 req->databaseNames = databaseNames;
1743 req->numberOfTermsRequested = #
1744 req->preferredPositionInResponse = &pp;
1749 int send_sortrequest(char *arg, int newset)
1751 Z_APDU *apdu = zget_APDU(out, Z_APDU_sortRequest);
1752 Z_SortRequest *req = apdu->u.sortRequest;
1753 Z_SortKeySpecList *sksl = (Z_SortKeySpecList *)
1754 odr_malloc (out, sizeof(*sksl));
1758 sprintf (setstring, "%d", setnumber);
1760 sprintf (setstring, "default");
1762 req->referenceId = set_refid (out);
1764 req->num_inputResultSetNames = 1;
1765 req->inputResultSetNames = (Z_InternationalString **)
1766 odr_malloc (out, sizeof(*req->inputResultSetNames));
1767 req->inputResultSetNames[0] = odr_strdup (out, setstring);
1769 if (newset && setnumber >= 0)
1770 sprintf (setstring, "%d", ++setnumber);
1772 req->sortedResultSetName = odr_strdup (out, setstring);
1774 req->sortSequence = yaz_sort_spec (out, arg);
1775 if (!req->sortSequence)
1777 printf ("Missing sort specifications\n");
1784 void display_term(Z_TermInfo *t)
1786 if (t->term->which == Z_Term_general)
1788 printf("%.*s", t->term->u.general->len, t->term->u.general->buf);
1789 sprintf(last_scan_line, "%.*s", t->term->u.general->len,
1790 t->term->u.general->buf);
1793 printf("Term (not general)");
1794 if (t->globalOccurrences)
1795 printf (" (%d)\n", *t->globalOccurrences);
1800 void process_scanResponse(Z_ScanResponse *res)
1803 Z_Entry **entries = NULL;
1804 int num_entries = 0;
1806 printf("Received ScanResponse\n");
1807 print_refid (res->referenceId);
1808 printf("%d entries", *res->numberOfEntriesReturned);
1809 if (res->positionOfTerm)
1810 printf (", position=%d", *res->positionOfTerm);
1812 if (*res->scanStatus != Z_Scan_success)
1813 printf("Scan returned code %d\n", *res->scanStatus);
1816 if ((entries = res->entries->entries))
1817 num_entries = res->entries->num_entries;
1818 for (i = 0; i < num_entries; i++)
1820 int pos_term = res->positionOfTerm ? *res->positionOfTerm : -1;
1821 if (entries[i]->which == Z_Entry_termInfo)
1823 printf("%c ", i + 1 == pos_term ? '*' : ' ');
1824 display_term(entries[i]->u.termInfo);
1827 display_diagrecs(&entries[i]->u.surrogateDiagnostic, 1);
1829 if (res->entries->nonsurrogateDiagnostics)
1830 display_diagrecs (res->entries->nonsurrogateDiagnostics,
1831 res->entries->num_nonsurrogateDiagnostics);
1834 void process_sortResponse(Z_SortResponse *res)
1836 printf("Received SortResponse: status=");
1837 switch (*res->sortStatus)
1839 case Z_SortStatus_success:
1840 printf ("success"); break;
1841 case Z_SortStatus_partial_1:
1842 printf ("partial"); break;
1843 case Z_SortStatus_failure:
1844 printf ("failure"); break;
1846 printf ("unknown (%d)", *res->sortStatus);
1849 print_refid (res->referenceId);
1850 if (res->diagnostics)
1851 display_diagrecs(res->diagnostics,
1852 res->num_diagnostics);
1855 void process_deleteResultSetResponse (Z_DeleteResultSetResponse *res)
1857 printf("Got deleteResultSetResponse status=%d\n",
1858 *res->deleteOperationStatus);
1859 if (res->deleteListStatuses)
1862 for (i = 0; i < res->deleteListStatuses->num; i++)
1864 printf ("%s status=%d\n", res->deleteListStatuses->elements[i]->id,
1865 *res->deleteListStatuses->elements[i]->status);
1870 int cmd_sort_generic(char *arg, int newset)
1874 printf("Session not initialized yet\n");
1877 if (!ODR_MASK_GET(session->options, Z_Options_sort))
1879 printf("Target doesn't support sort\n");
1884 if (send_sortrequest(arg, newset) < 0)
1891 int cmd_sort(char *arg)
1893 return cmd_sort_generic (arg, 0);
1896 int cmd_sort_newset (char *arg)
1898 return cmd_sort_generic (arg, 1);
1901 int cmd_scan(char *arg)
1905 printf("Session not initialized yet\n");
1908 if (!ODR_MASK_GET(session->options, Z_Options_scan))
1910 printf("Target doesn't support scan\n");
1915 strcpy (last_scan_query, arg);
1916 if (send_scanrequest(arg, 1, 20, 0) < 0)
1921 if (send_scanrequest(last_scan_query, 1, 20, last_scan_line) < 0)
1927 int cmd_schema(char *arg)
1934 schema = oid_getvalbyname (arg);
1935 if (schema == VAL_NONE)
1937 printf ("unknown schema\n");
1943 int cmd_format(char *arg)
1947 printf("Usage: format <recordsyntax>\n");
1950 recordsyntax = oid_getvalbyname (arg);
1951 if (recordsyntax == VAL_NONE)
1953 printf ("unknown record syntax\n");
1959 int cmd_elements(char *arg)
1961 static Z_ElementSetNames esn;
1962 static char what[100];
1966 elementSetNames = 0;
1970 esn.which = Z_ElementSetNames_generic;
1971 esn.u.generic = what;
1972 elementSetNames = &esn;
1976 int cmd_attributeset(char *arg)
1982 printf("Usage: attributeset <setname>\n");
1985 sscanf(arg, "%s", what);
1986 if (p_query_attset (what))
1988 printf("Unknown attribute set name\n");
1994 int cmd_querytype (char *arg)
1996 if (!strcmp (arg, "ccl"))
1997 queryType = QueryType_CCL;
1998 else if (!strcmp (arg, "prefix") || !strcmp(arg, "rpn"))
1999 queryType = QueryType_Prefix;
2001 else if (!strcmp (arg, "ccl2rpn") || !strcmp (arg, "cclrpn"))
2002 queryType = QueryType_CCL2RPN;
2006 printf ("Querytype must be one of:\n");
2007 printf (" prefix - Prefix query\n");
2008 printf (" ccl - CCL query\n");
2010 printf (" ccl2rpn - CCL query converted to RPN\n");
2017 int cmd_refid (char *arg)
2023 refid = (char *) xmalloc (strlen(arg)+1);
2024 strcpy (refid, arg);
2029 int cmd_close(char *arg)
2036 apdu = zget_APDU(out, Z_APDU_close);
2037 req = apdu->u.close;
2038 *req->closeReason = Z_Close_finished;
2040 printf("Sent close request.\n");
2045 int cmd_packagename(char* arg)
2047 xfree (esPackageName);
2048 esPackageName = NULL;
2051 esPackageName = (char *) xmalloc (strlen(arg)+1);
2052 strcpy (esPackageName, arg);
2057 int cmd_proxy(char* arg)
2063 yazProxy = (char *) xmalloc (strlen(arg)+1);
2064 strcpy (yazProxy, arg);
2069 int cmd_source(char* arg)
2071 /* first should open the file and read one line at a time.. */
2073 char line[1024], *cp;
2076 char* args_end=(arg)+strlen(arg)-1;
2077 while(isspace(*args_end))
2082 REMOVE_TAILING_BLANKS(arg);
2085 fprintf(stderr,"Error in source command use a filename\n");
2089 includeFile = fopen (arg, "r");
2092 fprintf(stderr,"Unable to open file %s for reading\n",arg);
2096 while(!feof(includeFile)) {
2097 memset(line,0,sizeof(line));
2098 fgets(line,sizeof(line),includeFile);
2100 if(strlen(line) < 2) continue;
2101 if(line[0] == '#') continue;
2103 if ((cp = strrchr (line, '\n')))
2106 process_cmd_line(line);
2109 if(fclose(includeFile)<0) {
2110 perror("unable to close include file");
2116 int cmd_subshell(char* args)
2121 system(getenv("SHELL"));
2127 int cmd_set_apdufile(char* arg)
2129 REMOVE_TAILING_BLANKS(arg);
2131 if(apdu_file && apdu_file != stderr) { /* don't close stdout*/
2132 perror("unable to close apdu log file");
2140 if(!strcmp(arg,"-"))
2143 apdu_file=fopen(arg, "a");
2146 perror("unable to open apdu log file no apdu log loaded");
2148 odr_setprint(print, apdu_file);
2154 int cmd_set_cclfields(char* arg)
2159 REMOVE_TAILING_BLANKS(arg);
2161 bibset = ccl_qual_mk ();
2162 inf = fopen (arg, "r");
2165 ccl_qual_file (bibset, inf);
2169 fprintf(stderr,"Not compiled with the yaz ccl module\n");
2175 int cmd_set_marcdump(char* arg)
2177 if(marcdump && marcdump != stderr) { /* don't close stdout*/
2178 perror("unable to close apdu log file");
2186 if(!strcmp(arg,"-"))
2189 marcdump=fopen(arg, "a");
2192 perror("unable to open apdu marcdump file no marcdump done\n");
2198 int cmd_set_proxy(char* arg) {
2199 if(yazProxy) free(yazProxy);
2202 if(strlen(arg) > 1) {
2203 yazProxy=strdup(arg);
2209 this command takes 3 arge {name class oid}
2211 int cmd_register_oid(char* args) {
2216 {"appctx",CLASS_APPCTX},
2217 {"absyn",CLASS_ABSYN},
2218 {"attset",CLASS_ATTSET},
2219 {"transyn",CLASS_TRANSYN},
2220 {"diagset",CLASS_DIAGSET},
2221 {"recsyn",CLASS_RECSYN},
2222 {"resform",CLASS_RESFORM},
2223 {"accform",CLASS_ACCFORM},
2224 {"extserv",CLASS_EXTSERV},
2225 {"userinfo",CLASS_USERINFO},
2226 {"elemspec",CLASS_ELEMSPEC},
2227 {"varset",CLASS_VARSET},
2228 {"schema",CLASS_SCHEMA},
2229 {"tagset",CLASS_TAGSET},
2230 {"general",CLASS_GENERAL},
2233 char oname_str[101], oclass_str[101], oid_str[101];
2236 oid_class oidclass = CLASS_GENERAL;
2237 int val = 0, oid[OID_SIZE];
2238 struct oident * new_oident=NULL;
2240 if (sscanf (args, "%100[^ ] %100[^ ] %100s",
2241 oname_str,oclass_str, oid_str) < 1) {
2242 printf("Error in regristrate command \n");
2246 for (i = 0; oid_classes[i].className; i++) {
2247 if (!strcmp(oid_classes[i].className, oclass_str))
2249 oidclass=oid_classes[i].oclass;
2254 if(!(oid_classes[i].className)) {
2255 printf("Unknonwn oid class %s\n",oclass_str);
2263 while (isdigit (*name))
2265 val = val*10 + (*name - '0');
2278 new_oident=oid_addent (oid,PROTO_GENERAL,oidclass,oname_str,VAL_DYNAMIC);
2279 if(strcmp(new_oident->desc,oname_str)) {
2280 fprintf(stderr,"oid is already named as %s, regristration faild\n",
2286 int cmd_push_command(char* arg) {
2287 #if HAVE_READLINE_HISTORY_H
2291 fprintf(stderr,"Not compiled with the readline/history module\n");
2296 void source_rcfile() {
2297 /* Look for a $HOME/.yazclientrc and source it if it exists */
2298 struct stat statbuf;
2300 char* homedir=getenv("HOME");
2301 if(!homedir) return;
2303 sprintf(buffer,"%s/.yazclientrc",homedir);
2305 if(stat(buffer,&statbuf)==0) {
2309 if(stat(".yazclientrc",&statbuf)==0) {
2310 cmd_source(".yazclientrc");
2315 static void initialize(void)
2320 if (!(out = odr_createmem(ODR_ENCODE)) ||
2321 !(in = odr_createmem(ODR_DECODE)) ||
2322 !(print = odr_createmem(ODR_PRINT)))
2324 fprintf(stderr, "failed to allocate ODR streams\n");
2329 setvbuf(stdout, 0, _IONBF, 0);
2331 odr_setprint(print, apdu_file);
2334 bibset = ccl_qual_mk ();
2335 inf = fopen (ccl_fields, "r");
2338 ccl_qual_file (bibset, inf);
2342 cmd_base("Default");
2344 #if HAVE_READLINE_READLINE_H
2345 rl_attempted_completion_function = (CPPFunction*)readline_completer;
2352 #if HAVE_GETTIMEOFDAY
2353 struct timeval tv_start, tv_end;
2356 void wait_and_handle_responce()
2361 int netbufferlen = 0;
2369 if ((res = cs_get(conn, &netbuffer, &netbufferlen)) < 0)
2371 printf("Target closed connection\n");
2377 printf("Target closed connection.\n");
2381 odr_reset(in); /* release APDU from last round */
2383 odr_setbuf(in, netbuffer, res, 0);
2384 if (!z_APDU(in, &apdu, 0, 0))
2386 odr_perror(in, "Decoding incoming APDU");
2387 fprintf(stderr, "[Near %d]\n", odr_offset(in));
2388 fprintf(stderr, "Packet dump:\n---------\n");
2389 odr_dumpBER(stderr, netbuffer, res);
2390 fprintf(stderr, "---------\n");
2392 z_APDU(print, &apdu, 0, 0);
2396 if (apdu_file && !z_APDU(print, &apdu, 0, 0))
2398 odr_perror(print, "Failed to print incoming APDU");
2404 case Z_APDU_initResponse:
2405 process_initResponse(apdu->u.initResponse);
2407 case Z_APDU_searchResponse:
2408 process_searchResponse(apdu->u.searchResponse);
2410 case Z_APDU_scanResponse:
2411 process_scanResponse(apdu->u.scanResponse);
2413 case Z_APDU_presentResponse:
2414 print_refid (apdu->u.presentResponse->referenceId);
2416 *apdu->u.presentResponse->numberOfRecordsReturned;
2417 if (apdu->u.presentResponse->records)
2418 display_records(apdu->u.presentResponse->records);
2420 printf("No records.\n");
2421 printf ("nextResultSetPosition = %d\n",
2422 *apdu->u.presentResponse->nextResultSetPosition);
2424 case Z_APDU_sortResponse:
2425 process_sortResponse(apdu->u.sortResponse);
2427 case Z_APDU_extendedServicesResponse:
2428 printf("Got extended services response\n");
2429 process_ESResponse(apdu->u.extendedServicesResponse);
2432 printf("Target has closed the association.\n");
2433 process_close(apdu->u.close);
2435 case Z_APDU_resourceControlRequest:
2436 process_resourceControlRequest
2437 (apdu->u.resourceControlRequest);
2439 case Z_APDU_deleteResultSetResponse:
2440 process_deleteResultSetResponse(apdu->u.
2441 deleteResultSetResponse);
2444 printf("Received unknown APDU type (%d).\n",
2449 while (conn && cs_more(conn));
2450 #if HAVE_GETTIMEOFDAY
2451 gettimeofday (&tv_end, 0);
2453 printf ("S/U S/U=%ld/%ld %ld/%ld",
2454 (long) tv_start.tv_sec,
2455 (long) tv_start.tv_usec,
2456 (long) tv_end.tv_sec,
2457 (long) tv_end.tv_usec);
2459 printf ("Elapsed: %.6f\n",
2460 (double) tv_end.tv_usec / 1e6 + tv_end.tv_sec -
2461 ((double) tv_start.tv_usec / 1e6 + tv_start.tv_sec));
2468 static int cmd_help (char *line);
2472 int (*fun)(char *arg);
2474 char *(*rl_completerfunction)(const char *text, int state);
2475 int complete_filenames;
2477 {"open", cmd_open, "('tcp'|'ssl')':<host>[':'<port>][/<db>]",NULL,0},
2478 {"quit", cmd_quit, "",NULL,0},
2479 {"find", cmd_find, "<query>",NULL,0},
2480 {"delete", cmd_delete, "<setname>",NULL,0},
2481 {"base", cmd_base, "<base-name>",NULL,0},
2482 {"show", cmd_show, "<rec#>['+'<#recs>['+'<setname>]]",NULL,0},
2483 {"scan", cmd_scan, "<term>",NULL,0},
2484 {"sort", cmd_sort, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0},
2485 {"sort+", cmd_sort_newset, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0},
2486 {"authentication", cmd_authentication, "<acctstring>",NULL,0},
2487 {"lslb", cmd_lslb, "<largeSetLowerBound>",NULL,0},
2488 {"ssub", cmd_ssub, "<smallSetUpperBound>",NULL,0},
2489 {"mspn", cmd_mspn, "<mediumSetPresentNumber>",NULL,0},
2490 {"status", cmd_status, "",NULL,0},
2491 {"setnames", cmd_setnames, "",NULL,0},
2492 {"cancel", cmd_cancel, "",NULL,0},
2493 {"format", cmd_format, "<recordsyntax>",complete_format,0},
2494 {"schema", cmd_schema, "<schema>",complete_schema,0},
2495 {"elements", cmd_elements, "<elementSetName>",NULL,0},
2496 {"close", cmd_close, "",NULL,0},
2497 {"attributeset", cmd_attributeset, "<attrset>",complete_attributeset,0},
2498 {"querytype", cmd_querytype, "<type>",complete_querytype,0},
2499 {"refid", cmd_refid, "<id>",NULL,0},
2500 {"itemorder", cmd_itemorder, "ill|item <itemno>",NULL,0},
2501 {"update", cmd_update, "<item>",NULL,0},
2502 {"packagename", cmd_packagename, "<packagename>",NULL,0},
2503 {"proxy", cmd_proxy, "[('tcp'|'ssl')]<host>[':'<port>]",NULL,0},
2504 {".", cmd_source, "<filename>",NULL,1},
2505 {"!", cmd_subshell, "Subshell command",NULL,0},
2506 {"set_apdufile", cmd_set_apdufile, "<filename>",NULL,0},
2507 {"set_marcdump", cmd_set_marcdump," <filename>",NULL,0},
2508 {"set_cclfields", cmd_set_cclfields,"<filename>",NULL,1},
2509 {"register_oid",cmd_register_oid,"<name> <class> <oid>",NULL,0},
2510 {"push_command",cmd_push_command,"<command>",command_generator,0},
2511 /* Server Admin Functions */
2512 {"adm-reindex", cmd_adm_reindex, "<database-name>",NULL,0},
2513 {"adm-truncate", cmd_adm_truncate, "('database'|'index')<object-name>",NULL,0},
2514 {"adm-create", cmd_adm_create, "",NULL,0},
2515 {"adm-drop", cmd_adm_drop, "('database'|'index')<object-name>",NULL,0},
2516 {"adm-import", cmd_adm_import, "<record-type> <dir> <pattern>",NULL,0},
2517 {"adm-refresh", cmd_adm_refresh, "",NULL,0},
2518 {"adm-commit", cmd_adm_commit, "",NULL,0},
2519 {"adm-shutdown", cmd_adm_shutdown, "",NULL,0},
2520 {"adm-startup", cmd_adm_startup, "",NULL,0},
2521 {"help", cmd_help, "", NULL},
2525 static int cmd_help (char *line)
2531 sscanf (line, "%20s", topic);
2534 printf("Commands:\n");
2535 for (i = 0; cmd[i].cmd; i++)
2536 if (*topic == 0 || strcmp (topic, cmd[i].cmd) == 0)
2537 printf(" %s %s\n", cmd[i].cmd, cmd[i].ad);
2538 if (strcmp (topic, "find") == 0)
2541 printf (" \"term\" Simple Term\n");
2542 printf (" @attr [attset] type=value op Attribute\n");
2543 printf (" @and opl opr And\n");
2544 printf (" @or opl opr Or\n");
2545 printf (" @not opl opr And-Not\n");
2546 printf (" @set set Result set\n");
2548 printf ("Bib-1 attribute types\n");
2550 printf ("4=Title 7=ISBN 8=ISSN 30=Date 62=Abstract 1003=Author 1016=Any\n");
2551 printf ("2=Relation: ");
2552 printf ("1< 2<= 3= 4>= 5> 6!= 102=Relevance\n");
2553 printf ("3=Position: ");
2554 printf ("1=First in Field 2=First in subfield 3=Any position\n");
2555 printf ("4=Structure: ");
2556 printf ("1=Phrase 2=Word 3=Key 4=Year 5=Date 6=WordList\n");
2557 printf ("5=Truncation: ");
2558 printf ("1=Right 2=Left 3=L&R 100=No 101=# 102=Re-1 103=Re-2\n");
2559 printf ("6=Completeness:");
2560 printf ("1=Incomplete subfield 2=Complete subfield 3=Complete field\n");
2565 void process_cmd_line(char* line)
2568 char word[32], arg[1024];
2570 #if HAVE_GETTIMEOFDAY
2571 gettimeofday (&tv_start, 0);
2574 if ((res = sscanf(line, "%31s %1023[^;]", word, arg)) <= 0)
2576 strcpy(word, last_cmd);
2581 strcpy(last_cmd, word);
2583 /* removed tailing spaces from the arg command */
2586 char* lastnonspace=NULL;
2595 *(++lastnonspace) = 0;
2599 for (i = 0; cmd[i].cmd; i++)
2600 if (!strncmp(cmd[i].cmd, word, strlen(word)))
2602 res = (*cmd[i].fun)(arg);
2606 if (!cmd[i].cmd) /* dump our help-screen */
2608 printf("Unknown command: %s.\n", word);
2613 if(apdu_file) fflush(apdu_file);
2616 wait_and_handle_responce();
2625 char *command_generator(const char *text, int state)
2631 for( ; cmd[idx].cmd; ++idx) {
2632 if (!strncmp(cmd[idx].cmd,text,strlen(text))) {
2633 ++idx; /* skip this entry on the next run */
2634 return strdup(cmd[idx-1].cmd);
2642 This function only known how to complete on the first word
2644 char ** readline_completer(char *text, int start, int end) {
2645 #if HAVE_READLINE_READLINE_H
2648 #if HAVE_READLINE_RL_COMPLETION_MATCHES
2649 char** res=rl_completion_matches(text,
2652 char** res=completion_matches(text,
2653 (CPFunction*)command_generator);
2655 rl_attempted_completion_over = 1;
2658 char arg[1024],word[32];
2660 if ((res = sscanf(rl_line_buffer, "%31s %1023[^;]", word, arg)) <= 0) {
2661 rl_attempted_completion_over = 1;
2665 if(start != strlen(word) +1 ) {
2666 rl_attempted_completion_over = 1;
2669 for (i = 0; cmd[i].cmd; i++) {
2670 if (!strncmp(cmd[i].cmd, word, strlen(word))) {
2676 if(!cmd[i].complete_filenames)
2677 rl_attempted_completion_over = 1;
2678 if(cmd[i].rl_completerfunction) {
2679 #ifdef HAVE_READLINE_RL_COMPLETION_MATCHES
2681 rl_completion_matches(text,
2682 cmd[i].rl_completerfunction);
2685 completion_matches(text,
2686 (CPFunction*)cmd[i].rl_completerfunction);
2688 rl_attempted_completion_over = 1;
2691 rl_attempted_completion_over = 1;
2701 static void client(void)
2707 #if HAVE_GETTIMEOFDAY
2708 gettimeofday (&tv_start, 0);
2713 char *line_in = NULL;
2714 #if HAVE_READLINE_READLINE_H
2717 line_in=readline(C_PROMPT);
2720 #if HAVE_READLINE_HISTORY_H
2722 add_history(line_in);
2724 strncpy(line, line_in, 1023);
2733 if (!fgets(line, 1023, stdin))
2735 if ((end_p = strchr (line, '\n')))
2738 process_cmd_line(line);
2742 int main(int argc, char **argv)
2745 char *open_command = 0;
2746 char *auth_command = 0;
2750 while ((ret = options("k:c:a:m:v:p:u:", argv, argc, &arg)) != -2)
2757 open_command = (char *) xmalloc (strlen(arg)+6);
2758 strcpy (open_command, "open ");
2759 strcat (open_command, arg);
2763 kilobytes = atoi(arg);
2766 if (!(marcdump = fopen (arg, "a")))
2773 strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
2774 ccl_fields[sizeof(ccl_fields)-1] = '\0';
2777 if (!strcmp(arg, "-"))
2780 apdu_file=fopen(arg, "a");
2783 yazProxy=strdup(arg);
2788 auth_command = (char *) xmalloc (strlen(arg)+6);
2789 strcpy (auth_command, "auth ");
2790 strcat (auth_command, arg);
2794 yaz_log_init (yaz_log_mask_str(arg), "", NULL);
2797 fprintf (stderr, "Usage: %s [-m <marclog>] [ -a <apdulog>] "
2798 "[-c cclfields]\n [-p <proxy-addr>] [-u <auth>] "
2799 "[-k size] [<server-addr>]\n",
2807 #ifdef HAVE_GETTIMEOFDAY
2808 gettimeofday (&tv_start, 0);
2810 process_cmd_line (auth_command);
2811 #if HAVE_READLINE_HISTORY_H
2812 add_history(auth_command);
2814 xfree(auth_command);
2818 #ifdef HAVE_GETTIMEOFDAY
2819 gettimeofday (&tv_start, 0);
2821 process_cmd_line (open_command);
2822 #if HAVE_READLINE_HISTORY_H
2823 add_history(open_command);
2825 xfree(open_command);