X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fyaz-client.cpp;h=6acdc7031b640c00911f09ec5fdb816985c37193;hb=66767801433aba6cd2ac9fc744a1057867df7fa9;hp=8a88bc3ca33d6cbdf616686249b20dce1508c431;hpb=c6e5ad789740135af3558298f6e2014ae99ee7dd;p=yazpp-moved-to-github.git diff --git a/src/yaz-client.cpp b/src/yaz-client.cpp index 8a88bc3..6acdc70 100644 --- a/src/yaz-client.cpp +++ b/src/yaz-client.cpp @@ -4,7 +4,15 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-client.cpp,v $ - * Revision 1.5 1999-04-09 11:46:57 adam + * Revision 1.7 1999-04-21 12:09:01 adam + * Many improvements. Modified to proxy server to work with "sessions" + * based on cookies. + * + * Revision 1.6 1999/04/20 10:30:05 adam + * Implemented various stuff for client and proxy. Updated calls + * to ODR to reflect new name parameter. + * + * Revision 1.5 1999/04/09 11:46:57 adam * Added object Yaz_Z_Assoc. Much more functional client. * * Revision 1.4 1999/03/23 14:17:57 adam @@ -24,6 +32,7 @@ #include #include +#include #include #include #include @@ -42,6 +51,7 @@ private: int m_interactive_flag; char m_thisCommand[1024]; char m_lastCommand[1024]; + int m_setOffset; Yaz_SocketManager *m_socketManager; public: MyClient(IYaz_PDU_Observable *the_PDU_Observable, @@ -52,16 +62,29 @@ public: int wait(); void recv_initResponse(Z_InitResponse *initResponse); void recv_searchResponse(Z_SearchResponse *searchResponse); + void recv_presentResponse(Z_PresentResponse *presentResponse); + void recv_records (Z_Records *records); + void recv_diagrecs(Z_DiagRec **pp, int num); + void recv_namePlusRecord (Z_NamePlusRecord *zpr, int offset); + void recv_record(Z_DatabaseRecord *record, int offset, + const char *databaseName); + void recv_textRecord(int type, const char *buf, size_t len); + void recv_genericRecord(Z_GenericRecord *r); + void display_genericRecord(Z_GenericRecord *r, int level); + void display_variant(Z_Variant *v, int level); int processCommand(const char *cmd); const char *MyClient::getCommand(); int cmd_open(char *host); int cmd_quit(char *args); int cmd_close(char *args); int cmd_find(char *args); + int cmd_show(char *args); + int cmd_cookie(char *args); + int cmd_init(char *args); }; IYaz_PDU_Observer *MyClient::clone(IYaz_PDU_Observable *the_PDU_Observable) -{ +{ return new MyClient(the_PDU_Observable, m_socketManager); } @@ -69,6 +92,7 @@ MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable, Yaz_SocketManager *the_socketManager) : Yaz_IR_Assoc (the_PDU_Observable) { + m_setOffset = 1; m_interactive_flag = 1; m_thisCommand[0] = '\0'; m_lastCommand[0] = '\0'; @@ -90,6 +114,249 @@ void MyClient::recv_initResponse(Z_InitResponse *initResponse) printf ("Fail\n"); } +void MyClient::recv_diagrecs(Z_DiagRec **pp, int num) +{ + int i; + oident *ent; + Z_DefaultDiagFormat *r; + + printf("Diagnostic message(s) from database:\n"); + for (i = 0; iwhich != Z_DiagRec_defaultFormat) + { + printf("Diagnostic record not in default format.\n"); + return; + } + else + r = p->u.defaultFormat; + if (!(ent = oid_getentbyoid(r->diagnosticSetId)) || + ent->oclass != CLASS_DIAGSET || ent->value != VAL_BIB1) + printf("Missing or unknown diagset\n"); + printf(" [%d] %s", *r->condition, diagbib1_str(*r->condition)); +#ifdef ASN_COMPILED + switch (r->which) + { + case Z_DefaultDiagFormat_v2Addinfo: + printf (" -- v2 addinfo '%s'\n", r->u.v2Addinfo); + break; + case Z_DefaultDiagFormat_v3Addinfo: + printf (" -- v3 addinfo '%s'\n", r->u.v3Addinfo); + break; + } +#else + if (r->addinfo && *r->addinfo) + printf(" -- '%s'\n", r->addinfo); + else + printf("\n"); +#endif + } +} + +void MyClient::recv_textRecord(int type, const char *buf, size_t len) +{ + fwrite (buf, 1, len, stdout); + fputc ('\n', stdout); +} + +void MyClient::display_variant(Z_Variant *v, int level) +{ + int i; + + for (i = 0; i < v->num_triples; i++) + { + printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->zclass, + *v->triples[i]->type); + if (v->triples[i]->which == Z_Triple_internationalString) + printf(",value=%s\n", v->triples[i]->value.internationalString); + else + printf("\n"); + } +} + +void MyClient::display_genericRecord(Z_GenericRecord *r, int level) +{ + int i; + + if (!r) + return; + for (i = 0; i < r->num_elements; i++) + { + Z_TaggedElement *t; + + printf("%*s", level * 4, ""); + t = r->elements[i]; + printf("("); + if (t->tagType) + printf("%d,", *t->tagType); + else + printf("?,"); + if (t->tagValue->which == Z_StringOrNumeric_numeric) + printf("%d) ", *t->tagValue->u.numeric); + else + printf("%s) ", t->tagValue->u.string); + if (t->content->which == Z_ElementData_subtree) + { + printf("\n"); + display_genericRecord(t->content->u.subtree, level+1); + } + else if (t->content->which == Z_ElementData_string) + printf("%s\n", t->content->u.string); + else if (t->content->which == Z_ElementData_numeric) + printf("%d\n", *t->content->u.numeric); + else if (t->content->which == Z_ElementData_oid) + { + int *ip = t->content->u.oid; + oident *oent; + + if ((oent = oid_getentbyoid(t->content->u.oid))) + printf("OID: %s\n", oent->desc); + else + { + printf("{"); + while (ip && *ip >= 0) + printf(" %d", *(ip++)); + printf(" }\n"); + } + } + else if (t->content->which == Z_ElementData_noDataRequested) + printf("[No data requested]\n"); + else if (t->content->which == Z_ElementData_elementEmpty) + printf("[Element empty]\n"); + else if (t->content->which == Z_ElementData_elementNotThere) + printf("[Element not there]\n"); + else + printf("??????\n"); + if (t->appliedVariant) + display_variant(t->appliedVariant, level+1); + if (t->metaData && t->metaData->supportedVariants) + { + int c; + + printf("%*s---- variant list\n", (level+1)*4, ""); + for (c = 0; c < t->metaData->num_supportedVariants; c++) + { + printf("%*svariant #%d\n", (level+1)*4, "", c); + display_variant(t->metaData->supportedVariants[c], level + 2); + } + } + } +} + +void MyClient::recv_genericRecord(Z_GenericRecord *r) +{ + display_genericRecord(r, 0); +} + +void MyClient::recv_record(Z_DatabaseRecord *record, int offset, + const char *databaseName) +{ + Z_External *r = (Z_External*) record; + oident *ent = oid_getentbyoid(r->direct_reference); + + /* + * Tell the user what we got. + */ + if (r->direct_reference) + { + printf("Record type: "); + if (ent) + printf("%s\n", ent->desc); + } + /* Check if this is a known, ASN.1 type tucked away in an octet string */ + Z_ext_typeent *etype = z_ext_getentbyref(ent->value); + if (ent && (r->which == Z_External_octet || r->which == Z_External_single) + && (etype = z_ext_getentbyref(ent->value))) + + { + void *rr; + /* + * Call the given decoder to process the record. + */ + odr_setbuf(odr_decode(), (char*)record->u.octet_aligned->buf, + record->u.octet_aligned->len, 0); + if (!(*etype->fun)(odr_decode(), (char **)&rr, 0, 0)) + { + odr_perror(odr_decode(), "Decoding constructed record."); + fprintf(stderr, "[Near %d]\n", odr_offset(odr_decode())); + fprintf(stderr, "Packet dump:\n---------\n"); + odr_dumpBER(stderr, (char*)record->u.octet_aligned->buf, + record->u.octet_aligned->len); + fprintf(stderr, "---------\n"); + } + if (etype->what == Z_External_sutrs) + { + Z_SUTRS *sutrs = (Z_SUTRS *) rr; + recv_textRecord ((int) VAL_SUTRS, (const char *) sutrs->buf, + (size_t) sutrs->len); + } + return; + } + if (r->which == Z_External_octet && record->u.octet_aligned->len) + { + recv_textRecord((int) ent->value, + (const char *) record->u.octet_aligned->buf, + (size_t) record->u.octet_aligned->len); + } + else if (ent && ent->value == VAL_SUTRS && r->which == Z_External_sutrs) + recv_textRecord((int) VAL_SUTRS, (const char *) r->u.sutrs->buf, + (size_t) r->u.sutrs->len); + else if (ent && ent->value == VAL_GRS1 && r->which == Z_External_grs1) + recv_genericRecord(r->u.grs1); + else + { + printf("Unknown record representation.\n"); + if (!z_External(odr_print(), &r, 0, 0)) + { + odr_perror(odr_print(), "Printing external"); + odr_reset(odr_print()); + } + } +} + +void MyClient::recv_namePlusRecord (Z_NamePlusRecord *zpr, int offset) +{ + if (zpr->databaseName) + printf("[%s]", zpr->databaseName); + if (zpr->which == Z_NamePlusRecord_surrogateDiagnostic) + recv_diagrecs(&zpr->u.surrogateDiagnostic, 1); + else + recv_record(zpr->u.databaseRecord, offset, zpr->databaseName); +} + +void MyClient::recv_records (Z_Records *records) +{ +#ifdef ASN_COMPILED + Z_DiagRec dr, *dr_p = &dr; +#endif + if (!records) + return; + int i; + switch (records->which) + { + case Z_Records_DBOSD: + for (i = 0; i < records->u.databaseOrSurDiagnostics->num_records; i++) + recv_namePlusRecord(records->u.databaseOrSurDiagnostics-> + records[i], i + m_setOffset); + m_setOffset += records->u.databaseOrSurDiagnostics->num_records; + break; + case Z_Records_NSD: +#ifdef ASN_COMPILED + dr.which = Z_DiagRec_defaultFormat; + dr.u.defaultFormat = records->u.nonSurrogateDiagnostic; + recv_diagrecs (&dr_p, 1); +#else + recv_diagrecs (&records->u.nonSurrogateDiagnostic, 1); +#endif + break; + case Z_Records_multipleNSD: + recv_diagrecs (records->u.multipleNonSurDiagnostics->diagRecs, + records->u.multipleNonSurDiagnostics->num_diagRecs); + break; + } +} + void MyClient::recv_searchResponse(Z_SearchResponse *searchResponse) { printf ("Got SearchResponse. Status "); @@ -100,6 +367,13 @@ void MyClient::recv_searchResponse(Z_SearchResponse *searchResponse) } printf ("Ok\n"); printf ("Hits: %d\n", *searchResponse->resultCount); + recv_records (searchResponse->records); +} + +void MyClient::recv_presentResponse(Z_PresentResponse *presentResponse) +{ + printf ("Got PresentResponse\n"); + recv_records (presentResponse->records); } int MyClient::wait() @@ -118,6 +392,12 @@ int MyClient::wait() int MyClient::cmd_open(char *host) { client (host); + m_socketManager->processEvent(); + return 1; +} + +int MyClient::cmd_init(char *args) +{ if (send_initRequest() >= 0) wait(); else @@ -150,6 +430,23 @@ int MyClient::cmd_find(char *args) return 1; } +int MyClient::cmd_show(char *args) +{ + int start = m_setOffset, number = 1; + + sscanf (args, "%d %d", &start, &number); + m_setOffset = start; + if (send_presentRequest(start, number) >= 0) + wait(); + return 1; +} + +int MyClient::cmd_cookie(char *args) +{ + set_cookie(*args ? args : 0); + return 1; +} + int MyClient::processCommand(const char *commandLine) { char cmdStr[1024], cmdArgs[1024]; @@ -160,10 +457,13 @@ int MyClient::processCommand(const char *commandLine) int (MyClient::*fun)(char *arg); char *ad; } cmd[] = { - {"open", &cmd_open, "('tcp'|'osi')':'['/'][':']"}, + {"open", &cmd_open, "[':'][/]"}, {"quit", &cmd_quit, ""}, {"close", &cmd_close, ""}, - {"find", &cmd_find, ""}, + {"find", &cmd_find, ""}, + {"show", &cmd_show, "[ []]"}, + {"cookie", &cmd_cookie, ""}, + {"init", &cmd_init, ""}, {0,0,0} }; @@ -216,7 +516,7 @@ const char *MyClient::getCommand() *cp = '\0'; cp = m_thisCommand; // Remove leading spaces... - while (strchr ("\t \n", *cp)) + while (*cp && strchr ("\t \n", *cp)) cp++; // Save command if non-empty if (*cp != '\0')