X-Git-Url: http://lists.indexdata.dk/cgi-bin?a=blobdiff_plain;f=ir-tcl.c;h=3d6eea94d226a323861c2d85668c25bb7c584b13;hb=2eebe462e1445d88490289b7011886b4cbba307d;hp=d9c4908d37c23eaf292ac98ec940cc19ea6b8cfe;hpb=f05f33b0806afdf3eaa97f767b99c974649159f8;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index d9c4908..3d6eea9 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -4,7 +4,15 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.15 1995-03-20 15:24:07 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 @@ -54,7 +62,10 @@ #include #include #include + +#if MOSI #include +#endif #include #include @@ -67,43 +78,46 @@ #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; @@ -124,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); @@ -477,6 +492,7 @@ static int do_connect (void *obj, Tcl_Interp *interp, { void *addr; IRObj *p = obj; + int r; if (argc == 3) { @@ -485,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) { @@ -495,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) { @@ -505,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; } @@ -532,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, CS_BLOCK); - } - 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, CS_BLOCK); - } - else - { - interp->result = "unknown comstack type"; - return TCL_ERROR; + p->cs_link = NULL; } return TCL_OK; } @@ -554,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, CS_BLOCK); - else if (!strcmp (argv[2], "mosi")) - ((IRObj *)obj)->cs_link = cs_create (mosi_type, CS_BLOCK); - 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; } @@ -648,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 */ @@ -668,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} }; @@ -700,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, CS_BLOCK); + 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; @@ -793,7 +831,7 @@ 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:"); @@ -887,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, @@ -1076,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: @@ -1227,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} }; @@ -1272,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; @@ -1314,6 +1374,8 @@ static void ir_handleRecords (void *o, Z_Records *zrs) IRObj *p = o; IRSetObj *setobj = p->child; + setobj->which = zrs->which; + setobj->recordFlag = 1; if (zrs->which == Z_Records_NSD) { const char *addinfo; @@ -1325,7 +1387,7 @@ static void ir_handleRecords (void *o, Z_Records *zrs) addinfo = zrs->u.nonSurrogateDiagnostic->addinfo; if (addinfo && (setobj->addinfo = malloc (strlen(addinfo) + 1))) strcpy (setobj->addinfo, addinfo); - printf ("Diagnostic response. %s (%d), info %s\n", + printf ("Diagnostic response. %s (%d): %s\n", diagbib1_str (setobj->condition), setobj->condition, setobj->addinfo ? setobj->addinfo : ""); @@ -1379,16 +1441,19 @@ static void ir_handleRecords (void *o, Z_Records *zrs) static void ir_searchResponse (void *o, Z_SearchResponse *searchrs) { IRObj *p = o; - IRSetObj *obj = p->child; + IRSetObj *setobj = p->child; + Z_Records *zrs = searchrs->records; - if (obj) + if (setobj) { - obj->searchStatus = searchrs->searchStatus ? 1 : 0; - obj->resultCount = *searchrs->resultCount; + setobj->searchStatus = searchrs->searchStatus ? 1 : 0; + setobj->resultCount = *searchrs->resultCount; printf ("Search response %d, %d hits\n", - obj->searchStatus, obj->resultCount); - if (searchrs->records) - ir_handleRecords (o, searchrs->records); + setobj->searchStatus, setobj->resultCount); + if (zrs) + ir_handleRecords (o, zrs); + else + setobj->recordFlag = 0; } else printf ("Search response, no object!\n"); @@ -1400,16 +1465,13 @@ static void ir_presentResponse (void *o, Z_PresentResponse *presrs) 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; ir_handleRecords (o, zrs); - } else { + setobj->recordFlag = 0; printf ("No records!\n"); } } @@ -1422,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) @@ -1469,6 +1548,23 @@ void ir_select_write (ClientData 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");