X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=ir-tcl.c;h=3d6eea94d226a323861c2d85668c25bb7c584b13;hb=2eebe462e1445d88490289b7011886b4cbba307d;hp=baaf68d132f28cf694aa364d75cd8791ae5c3ca0;hpb=184be1f49bc141230b8dfdd11dfb2acf538d1858;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index baaf68d..3d6eea9 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -4,7 +4,18 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.14 1995-03-20 08:53:22 adam + * Revision 1.17 1995-03-21 13:41:03 adam + * Comstack cs_create not used too often. Non-blocking connect. + * + * Revision 1.16 1995/03/21 08:26:06 adam + * New method, setName, to specify the result set name (other than Default). + * New method, responseStatus, which returns diagnostic info, if any, after + * present response / search response. + * + * Revision 1.15 1995/03/20 15:24:07 adam + * Diagnostic records saved on searchResponse. + * + * Revision 1.14 1995/03/20 08:53:22 adam * Event loop in tclmain.c rewritten. New method searchStatus. * * Revision 1.13 1995/03/17 18:26:17 adam @@ -51,7 +62,10 @@ #include #include #include + +#if MOSI #include +#endif #include #include @@ -61,44 +75,49 @@ #include "ir-tcl.h" +#define CS_BLOCK 0 + typedef struct { - COMSTACK cs_link; + char *cs_type; + int connectFlag; + COMSTACK cs_link; + - int preferredMessageSize; - int maximumRecordSize; + int preferredMessageSize; + int maximumRecordSize; Odr_bitmask options; Odr_bitmask protocolVersion; - char *idAuthentication; - char *implementationName; - char *implementationId; + char *idAuthentication; + char *implementationName; + char *implementationId; - char *hostname; + char *hostname; - char *buf_out; - int len_out; + char *buf_out; + int len_out; - char *buf_in; - int len_in; + char *buf_in; + int len_in; - char *sbuf; - int slen; + char *sbuf; + int slen; - ODR odr_in; - ODR odr_out; - ODR odr_pr; + ODR odr_in; + ODR odr_out; + ODR odr_pr; Tcl_Interp *interp; - char *callback; + char *callback; - int smallSetUpperBound; - int largeSetLowerBound; - int mediumSetPresentNumber; - int replaceIndicator; - char **databaseNames; - int num_databaseNames; - char *query_method; + int smallSetUpperBound; + int largeSetLowerBound; + int mediumSetPresentNumber; + int replaceIndicator; + char **databaseNames; + int num_databaseNames; + char *query_method; - CCL_bibset bibset; + CCL_bibset bibset; struct IRSetObj_ *child; } IRObj; @@ -119,23 +138,24 @@ typedef struct IRRecordList_ { } IRRecordList; typedef struct IRSetObj_ { - IRObj *parent; - int searchStatus; - int resultCount; - int start; - int number; - int numberOfRecordsReturned; - Z_Records *z_records; - int which; - int condition; - char *addinfo; + IRObj *parent; + int searchStatus; + int resultCount; + int start; + int number; + int numberOfRecordsReturned; + char *setName; + int recordFlag; + int which; + int condition; + char *addinfo; IRRecordList *record_list; } IRSetObj; typedef struct { int type; char *name; - int (*method) (void * obj, Tcl_Interp *interp, int argc, char **argv); + int (*method) (void *obj, Tcl_Interp *interp, int argc, char **argv); } IRMethod; static int do_disconnect (void *obj,Tcl_Interp *interp, int argc, char **argv); @@ -472,6 +492,7 @@ static int do_connect (void *obj, Tcl_Interp *interp, { void *addr; IRObj *p = obj; + int r; if (argc == 3) { @@ -480,8 +501,9 @@ static int do_connect (void *obj, Tcl_Interp *interp, interp->result = "already connected"; return TCL_ERROR; } - if (cs_type(p->cs_link) == tcpip_type) + if (!strcmp (p->cs_type, "tcpip")) { + p->cs_link = cs_create (tcpip_type, CS_BLOCK); addr = tcpip_strtoaddr (argv[2]); if (!addr) { @@ -490,8 +512,10 @@ static int do_connect (void *obj, Tcl_Interp *interp, } printf ("tcp/ip connect %s\n", argv[2]); } - else if (cs_type (p->cs_link) == mosi_type) +#if MOSI + else if (!strcmp (p->cs_type, "mosi")) { + p->cs_link = cs_create (mosi_type, CS_BLOCK); addr = mosi_strtoaddr (argv[2]); if (!addr) { @@ -500,17 +524,33 @@ static int do_connect (void *obj, Tcl_Interp *interp, } printf ("mosi connect %s\n", argv[2]); } - if (cs_connect (p->cs_link, addr) < 0) +#endif + else { - interp->result = "cs_connect fail"; - do_disconnect (p, interp, argc, argv); + interp->result = "unknown cs type"; return TCL_ERROR; } if (ir_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR) return TCL_ERROR; + if ((r=cs_connect (p->cs_link, addr)) < 0) + { + interp->result = "cs_connect fail"; + return TCL_ERROR; + } ir_select_add (cs_fileno (p->cs_link), p); + if (r == 1) + { + ir_select_add_write (cs_fileno (p->cs_link), p); + p->connectFlag = 1; + } + else + { + p->connectFlag = 0; + if (p->callback) + Tcl_Eval (p->interp, p->callback); + } } - Tcl_AppendResult (interp, p->hostname, NULL); + Tcl_AppendElement (interp, p->hostname); return TCL_OK; } @@ -527,21 +567,10 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, free (p->hostname); p->hostname = NULL; ir_select_remove (cs_fileno (p->cs_link), p); - } - if (cs_type (p->cs_link) == tcpip_type) - { - cs_close (p->cs_link); - p->cs_link = cs_create (tcpip_type, 0); - } - else if (cs_type (p->cs_link) == mosi_type) - { + + assert (p->cs_link); cs_close (p->cs_link); - p->cs_link = cs_create (mosi_type, 0); - } - else - { - interp->result = "unknown comstack type"; - return TCL_ERROR; + p->cs_link = NULL; } return TCL_OK; } @@ -549,28 +578,18 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, /* * do_comstack: Set/get comstack method on IR object */ -static int do_comstack (void *obj, Tcl_Interp *interp, +static int do_comstack (void *o, Tcl_Interp *interp, int argc, char **argv) { - char *cs_type = NULL; + IRObj *obj = o; + if (argc == 3) { - cs_close (((IRObj*) obj)->cs_link); - if (!strcmp (argv[2], "tcpip")) - ((IRObj *)obj)->cs_link = cs_create (tcpip_type, 0); - else if (!strcmp (argv[2], "mosi")) - ((IRObj *)obj)->cs_link = cs_create (mosi_type, 0); - else - { - interp->result = "wrong comstack type"; + free (obj->cs_type); + if (ir_strdup (interp, &obj->cs_type, argv[2]) == TCL_ERROR) return TCL_ERROR; - } } - if (cs_type(((IRObj *)obj)->cs_link) == tcpip_type) - cs_type = "tcpip"; - else if (cs_type(((IRObj *)obj)->cs_link) == mosi_type) - cs_type = "comstack"; - Tcl_AppendResult (interp, cs_type, NULL); + Tcl_AppendElement (interp, obj->cs_type); return TCL_OK; } @@ -643,6 +662,26 @@ static int do_query (void *obj, Tcl_Interp *interp, return TCL_OK; } +/* + * do_replaceIndicator: Set/get replace Set indicator + */ +static int do_replaceIndicator (void *obj, Tcl_Interp *interp, + int argc, char **argv) +{ + IRObj *p = obj; + char buf[20]; + + if (argc == 3) + { + if (Tcl_GetInt (interp, argv[2], + &p->replaceIndicator)==TCL_ERROR) + return TCL_ERROR; + } + sprintf (buf, "%d", p->replaceIndicator); + Tcl_AppendResult (interp, buf, NULL); + return TCL_OK; +} + /* * ir_obj_method: IR Object methods */ @@ -663,6 +702,7 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp, { 0, "disconnect", do_disconnect }, { 0, "callback", do_callback }, { 1, "databaseNames", do_databaseNames}, + { 1, "replaceIndicator", do_replaceIndicator}, { 1, "query", do_query }, { 0, NULL, NULL} }; @@ -695,10 +735,13 @@ static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp, } if (!(obj = ir_malloc (interp, sizeof(*obj)))) return TCL_ERROR; - obj->cs_link = cs_create (tcpip_type, 0); + if (ir_strdup (interp, &obj->cs_type, "tcpip") == TCL_ERROR) + return TCL_ERROR; + obj->cs_link = NULL; obj->maximumRecordSize = 32768; obj->preferredMessageSize = 4096; + obj->connectFlag = 0; obj->idAuthentication = NULL; @@ -788,9 +831,14 @@ static int do_search (void *o, Tcl_Interp *interp, req.largeSetLowerBound = &p->largeSetLowerBound; req.mediumSetPresentNumber = &p->mediumSetPresentNumber; req.replaceIndicator = &p->replaceIndicator; - req.resultSetName = "Default"; + req.resultSetName = obj->setName ? obj->setName : "Default"; req.num_databaseNames = p->num_databaseNames; req.databaseNames = p->databaseNames; + printf ("Search:"); + for (r=0; rnum_databaseNames; r++) + { + printf (" %s", p->databaseNames[r]); + } req.smallSetElementSetNames = 0; req.mediumSetElementSetNames = 0; req.preferredRecordSyntax = 0; @@ -813,6 +861,7 @@ static int do_search (void *o, Tcl_Interp *interp, assert((RPNquery = ccl_rpn_query(rpn))); RPNquery->attributeSetId = bib1; query.u.type_1 = RPNquery; + printf ("- RPN\n"); } else if (!strcmp (p->query_method, "ccl")) { @@ -820,6 +869,7 @@ static int do_search (void *o, Tcl_Interp *interp, query.u.type_2 = &ccl_query; ccl_query.buf = argv[2]; ccl_query.len = strlen (argv[2]); + printf ("- CCL\n"); } else { @@ -875,6 +925,25 @@ static int do_searchStatus (void *o, Tcl_Interp *interp, } /* + * do_setName: Set result Set name + */ +static int do_setName (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IRSetObj *obj = o; + + if (argc == 3) + { + free (obj->setName); + if (ir_strdup (interp, &obj->setName, argv[2]) + == TCL_ERROR) + return TCL_ERROR; + } + Tcl_AppendElement (interp, obj->setName); + return TCL_OK; +} + +/* * do_numberOfRecordsReturned: Get number of records returned */ static int do_numberOfRecordsReturned (void *o, Tcl_Interp *interp, @@ -1064,15 +1133,17 @@ static int do_recordMarc (void *o, Tcl_Interp *interp, int argc, char **argv) } /* - * do_presentStatus: Return present status (after present response) + * do_responseStatus: Return response status (present or search) */ -static int do_presentStatus (void *o, Tcl_Interp *interp, +static int do_responseStatus (void *o, Tcl_Interp *interp, int argc, char **argv) { IRSetObj *obj = o; const char *cp; char buf[28]; + if (!obj->recordFlag) + return TCL_OK; switch (obj->which) { case Z_Records_DBOSD: @@ -1215,13 +1286,14 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, static IRMethod tab[] = { { 0, "search", do_search }, { 0, "searchStatus", do_searchStatus }, + { 0, "setName", do_setName }, { 0, "resultCount", do_resultCount }, { 0, "numberOfRecordsReturned", do_numberOfRecordsReturned }, { 0, "present", do_present }, { 0, "recordType", do_recordType }, { 0, "recordMarc", do_recordMarc }, { 0, "recordDiag", do_recordDiag }, - { 0, "presentStatus", do_presentStatus }, + { 0, "responseStatus", do_responseStatus }, { 0, "loadFile", do_loadFile }, { 0, NULL, NULL} }; @@ -1260,7 +1332,7 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; if (!(obj = ir_malloc (interp, sizeof(*obj)))) return TCL_ERROR; - obj->z_records = NULL; + obj->setName = NULL; obj->record_list = NULL; obj->addinfo = NULL; obj->parent = (IRObj *) parent_info.clientData; @@ -1271,22 +1343,6 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, /* ------------------------------------------------------- */ -static void ir_searchResponse (void *o, Z_SearchResponse *searchrs) -{ - IRObj *p = o; - IRSetObj *obj = p->child; - - if (obj) - { - obj->searchStatus = searchrs->searchStatus ? 1 : 0; - obj->resultCount = *searchrs->resultCount; - printf ("Search response %d, %d hits\n", - obj->searchStatus, obj->resultCount); - } - else - printf ("Search response, no object!\n"); -} - static void ir_initResponse (void *obj, Z_InitResponse *initrs) { if (!*initrs->result) @@ -1313,79 +1369,109 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs) #endif } -static void ir_presentResponse (void *o, Z_PresentResponse *presrs) +static void ir_handleRecords (void *o, Z_Records *zrs) { IRObj *p = o; IRSetObj *setobj = p->child; - Z_Records *zrs = presrs->records; - setobj->z_records = presrs->records; - - printf ("Received presentResponse\n"); - if (zrs) - { - setobj->which = zrs->which; - if (zrs->which == Z_Records_NSD) - { - const char *addinfo; - printf ("They are diagnostic!!!\n"); - - setobj->numberOfRecordsReturned = 0; - setobj->condition = *zrs->u.nonSurrogateDiagnostic->condition; - free (setobj->addinfo); - setobj->addinfo = NULL; - addinfo = zrs->u.nonSurrogateDiagnostic->addinfo; - if (addinfo && (setobj->addinfo = malloc (strlen(addinfo) + 1))) - strcpy (setobj->addinfo, addinfo); - return; - } - else + setobj->which = zrs->which; + setobj->recordFlag = 1; + if (zrs->which == Z_Records_NSD) + { + const char *addinfo; + + setobj->numberOfRecordsReturned = 0; + setobj->condition = *zrs->u.nonSurrogateDiagnostic->condition; + free (setobj->addinfo); + setobj->addinfo = NULL; + addinfo = zrs->u.nonSurrogateDiagnostic->addinfo; + if (addinfo && (setobj->addinfo = malloc (strlen(addinfo) + 1))) + strcpy (setobj->addinfo, addinfo); + printf ("Diagnostic response. %s (%d): %s\n", + diagbib1_str (setobj->condition), + setobj->condition, + setobj->addinfo ? setobj->addinfo : ""); + } + else + { + int offset; + IRRecordList *rl; + + setobj->numberOfRecordsReturned = + zrs->u.databaseOrSurDiagnostics->num_records; + printf ("Got %d records\n", setobj->numberOfRecordsReturned); + for (offset = 0; offsetnumberOfRecordsReturned; offset++) { - int offset; - IRRecordList *rl; - - setobj->numberOfRecordsReturned = - zrs->u.databaseOrSurDiagnostics->num_records; - printf ("Got %d records\n", setobj->numberOfRecordsReturned); - for (offset = 0; offsetnumberOfRecordsReturned; offset++) + rl = new_IR_record (setobj, setobj->start + offset, + zrs->u.databaseOrSurDiagnostics-> + records[offset]->which); + if (rl->which == Z_NamePlusRecord_surrogateDiagnostic) + { + Z_DiagRec *diagrec; + + diagrec = zrs->u.databaseOrSurDiagnostics-> + records[offset]->u.surrogateDiagnostic; + + rl->u.diag.condition = *diagrec->condition; + if (diagrec->addinfo && (rl->u.diag.addinfo = + malloc (strlen (diagrec->addinfo)+1))) + strcpy (rl->u.diag.addinfo, diagrec->addinfo); + } + else { - rl = new_IR_record (setobj, setobj->start + offset, - zrs->u.databaseOrSurDiagnostics-> - records[offset]->which); - if (rl->which == Z_NamePlusRecord_surrogateDiagnostic) + Z_DatabaseRecord *zr; + Odr_external *oe; + + zr = zrs->u.databaseOrSurDiagnostics->records[offset] + ->u.databaseRecord; + oe = (Odr_external*) zr; + if (oe->which == ODR_EXTERNAL_octet + && zr->u.octet_aligned->len) { - Z_DiagRec *diagrec; - - diagrec = zrs->u.databaseOrSurDiagnostics-> - records[offset]->u.surrogateDiagnostic; - - rl->u.diag.condition = *diagrec->condition; - if (diagrec->addinfo && (rl->u.diag.addinfo = - malloc (strlen (diagrec->addinfo)+1))) - strcpy (rl->u.diag.addinfo, diagrec->addinfo); + const char *buf = (char*) zr->u.octet_aligned->buf; + rl->u.marc.rec = iso2709_cvt (buf); } else - { - Z_DatabaseRecord *zr; - Odr_external *oe; - - zr = zrs->u.databaseOrSurDiagnostics->records[offset] - ->u.databaseRecord; - oe = (Odr_external*) zr; - if (oe->which == ODR_EXTERNAL_octet - && zr->u.octet_aligned->len) - { - const char *buf = (char*) zr->u.octet_aligned->buf; - rl->u.marc.rec = iso2709_cvt (buf); - } - else - rl->u.marc.rec = NULL; - } + rl->u.marc.rec = NULL; } } } +} + +static void ir_searchResponse (void *o, Z_SearchResponse *searchrs) +{ + IRObj *p = o; + IRSetObj *setobj = p->child; + Z_Records *zrs = searchrs->records; + + if (setobj) + { + setobj->searchStatus = searchrs->searchStatus ? 1 : 0; + setobj->resultCount = *searchrs->resultCount; + printf ("Search response %d, %d hits\n", + setobj->searchStatus, setobj->resultCount); + if (zrs) + ir_handleRecords (o, zrs); + else + setobj->recordFlag = 0; + } + else + printf ("Search response, no object!\n"); +} + + +static void ir_presentResponse (void *o, Z_PresentResponse *presrs) +{ + IRObj *p = o; + IRSetObj *setobj = p->child; + Z_Records *zrs = presrs->records; + + printf ("Received presentResponse\n"); + if (zrs) + ir_handleRecords (o, zrs); else { + setobj->recordFlag = 0; printf ("No records!\n"); } } @@ -1398,7 +1484,24 @@ void ir_select_read (ClientData clientData) IRObj *p = clientData; Z_APDU *apdu; int r; - + + if (p->connectFlag) + { + r = cs_rcvconnect (p->cs_link); + if (r == 1) + return; + p->connectFlag = 0; + if (r < 0) + { + printf ("cs_rcvconnect error\n"); + ir_select_remove_write (cs_fileno (p->cs_link), p); + return; + } + ir_select_remove_write (cs_fileno (p->cs_link), p); + if (p->callback) + Tcl_Eval (p->interp, p->callback); + return; + } do { if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) <= 0) @@ -1443,7 +1546,25 @@ void ir_select_write (ClientData clientData) { IRObj *p = clientData; int r; - + + printf ("In write handler.....\n"); + if (p->connectFlag) + { + r = cs_rcvconnect (p->cs_link); + if (r == 1) + return; + p->connectFlag = 0; + if (r < 0) + { + printf ("cs_rcvconnect error\n"); + ir_select_remove_write (cs_fileno (p->cs_link), p); + return; + } + ir_select_remove_write (cs_fileno (p->cs_link), p); + if (p->callback) + Tcl_Eval (p->interp, p->callback); + return; + } if ((r=cs_put (p->cs_link, p->sbuf, p->slen)) < 0) { printf ("select write fail\n");