X-Git-Url: http://git.indexdata.com/?p=ir-tcl-moved-to-github.git;a=blobdiff_plain;f=ir-tcl.c;h=2d3e9ef6cca0a9f10f1b9af0e0019bb3a5103f0a;hp=7fc284b7fe9538be1e04f3281e6cffb6e44301b7;hb=e5bca6e2527eb47c1a44c6d5d61aa3cdfd438bc4;hpb=3e1ca5be8142497fbde0bd45db62e887aa9cf8bc diff --git a/ir-tcl.c b/ir-tcl.c index 7fc284b..2d3e9ef 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -1,10 +1,44 @@ /* * IR toolkit for tcl/tk - * (c) Index Data 1995-2000 + * (c) Index Data 1995-2003 * See the file LICENSE for details. * * $Log: ir-tcl.c,v $ - * Revision 1.115 2000-09-13 12:18:49 adam + * Revision 1.126 2003-11-29 17:24:09 adam + * Added getXml method (Franck Falcoz) + * + * Revision 1.125 2003/04/29 10:51:23 adam + * Null terminate octet aligned records + * + * Revision 1.124 2003/03/05 22:02:47 adam + * Add Tcl_InitStubs + * + * Revision 1.123 2003/03/05 21:21:41 adam + * APDU log. default largeSetLowerBound changed from 2 to 1 + * + * Revision 1.122 2003/03/05 18:02:08 adam + * Fix bug with idAuthentication that didn't work for empty group. + * + * Revision 1.121 2003/01/30 13:27:07 adam + * Changed version to 1.4.1. Added WIN32 version resource. + * IrTcl ignores unexpected PDU's, rather than die. + * + * Revision 1.120 2002/03/20 14:48:54 adam + * implemented USR.1 SearchResult-1 + * + * Revision 1.119 2001/12/03 00:31:06 adam + * Towards 1.4. Configure updates. + * + * Revision 1.118 2001/03/27 16:27:21 adam + * Fixed bug in do_responseStatus. + * + * Revision 1.117 2001/03/26 11:39:34 adam + * Fixed bug in ir_deleteDiags - crash when receiving multiple diags. + * + * Revision 1.116 2001/02/09 11:58:04 adam + * Updated for Tcl8.1 and higher where internal encoding is UTF-8. + * + * Revision 1.115 2000/09/13 12:18:49 adam * Logging utility patch (YAZ version 1.7). * * Revision 1.114 1999/05/17 20:37:41 adam @@ -442,6 +476,7 @@ #endif static char *wrongArgs = "wrong # args: should be \""; +static FILE *odr_print_file = 0; static int ir_tcl_error_exec (Tcl_Interp *interp, int argc, char **argv) { @@ -770,7 +805,7 @@ static int do_init_request (void *obj, Tcl_Interp *interp, req->preferredMessageSize = &p->preferredMessageSize; req->maximumRecordSize = &p->maximumRecordSize; - if (p->idAuthenticationGroupId) + if (p->idAuthenticationGroupId || p->idAuthenticationUserId) { Z_IdPass *pass = odr_malloc (p->odr_out, sizeof(*pass)); Z_IdAuthentication *auth = odr_malloc (p->odr_out, sizeof(*auth)); @@ -793,9 +828,7 @@ static int do_init_request (void *obj, Tcl_Interp *interp, pass->password = NULL; req->idAuthentication = auth; } - else if (!p->idAuthenticationOpen || !*p->idAuthenticationOpen) - req->idAuthentication = NULL; - else + else if (p->idAuthenticationOpen && *p->idAuthenticationOpen) { Z_IdAuthentication *auth = odr_malloc (p->odr_out, sizeof(*auth)); @@ -804,6 +837,8 @@ static int do_init_request (void *obj, Tcl_Interp *interp, auth->u.open = p->idAuthenticationOpen; req->idAuthentication = auth; } + else + req->idAuthentication = NULL; req->implementationId = p->implementationId; req->implementationName = p->implementationName; req->implementationVersion = p->implementationVersion; @@ -1029,7 +1064,7 @@ static int do_implementationName (void *obj, Tcl_Interp *interp, if (argc == 0) return ir_tcl_strdup (interp, &p->implementationName, - "Index Data/IrTcl on YAZ"); + "IrTcl/YAZ"); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationName); if (argc == 3) @@ -1052,7 +1087,7 @@ static int do_implementationId (void *obj, Tcl_Interp *interp, IrTcl_Obj *p = obj; if (argc == 0) - return ir_tcl_strdup (interp, &p->implementationId, "YAZ (id=81)"); + return ir_tcl_strdup (interp, &p->implementationId, "81"); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationId); Tcl_AppendResult (interp, p->implementationId, (char*) NULL); @@ -1069,10 +1104,10 @@ static int do_implementationVersion (void *obj, Tcl_Interp *interp, if (argc == 0) return ir_tcl_strdup (interp, &p->implementationVersion, - "YAZ: " YAZ_VERSION #ifdef IR_TCL_VERSION - " / Irtcl: " IR_TCL_VERSION + IR_TCL_VERSION "/" #endif + YAZ_VERSION ); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationVersion); @@ -1165,6 +1200,12 @@ static int do_idAuthentication (void *obj, Tcl_Interp *interp, { if (argc == 3) { + xfree (p->idAuthenticationGroupId); + xfree (p->idAuthenticationUserId); + xfree (p->idAuthenticationPassword); + p->idAuthenticationGroupId = NULL; + p->idAuthenticationUserId = NULL; + p->idAuthenticationPassword = NULL; if (argv[2][0] && ir_tcl_strdup (interp, &p->idAuthenticationOpen, argv[2]) == TCL_ERROR) @@ -1172,6 +1213,8 @@ static int do_idAuthentication (void *obj, Tcl_Interp *interp, } else if (argc == 5) { + xfree (p->idAuthenticationOpen); + p->idAuthenticationOpen = NULL; if (argv[2][0] && ir_tcl_strdup (interp, &p->idAuthenticationGroupId, argv[2]) == TCL_ERROR) @@ -1188,7 +1231,7 @@ static int do_idAuthentication (void *obj, Tcl_Interp *interp, } if (p->idAuthenticationOpen) Tcl_AppendElement (interp, p->idAuthenticationOpen); - else if (p->idAuthenticationGroupId) + else if (p->idAuthenticationGroupId || p->idAuthenticationUserId) { Tcl_AppendElement (interp, p->idAuthenticationGroupId); Tcl_AppendElement (interp, p->idAuthenticationUserId); @@ -1675,7 +1718,7 @@ static int do_largeSetLowerBound (void *o, Tcl_Interp *interp, if (argc <= 0) { - p->largeSetLowerBound = 2; + p->largeSetLowerBound = 1; return TCL_OK; } return ir_tcl_get_set_int (&p->largeSetLowerBound, interp, argc, argv); @@ -1935,7 +1978,11 @@ static void ir_obj_delete (ClientData clientData) ir_tcl_del_q (obj); odr_destroy (obj->odr_in); odr_destroy (obj->odr_out); - odr_destroy (obj->odr_pr); + if (obj->odr_pr) + { + obj->odr_pr->print = 0; + odr_destroy (obj->odr_pr); + } xfree (obj); } @@ -1972,7 +2019,12 @@ int ir_obj_init (ClientData clientData, Tcl_Interp *interp, obj->odr_in = odr_createmem (ODR_DECODE); odr_choice_enable_bias (obj->odr_in, 0); obj->odr_out = odr_createmem (ODR_ENCODE); - obj->odr_pr = odr_createmem (ODR_PRINT); + obj->odr_pr = 0; + if (odr_print_file) + { + obj->odr_pr = odr_createmem (ODR_PRINT); + odr_setprint(obj->odr_pr, odr_print_file); + } obj->state = IR_TCL_R_Idle; obj->interp = interp; @@ -2032,7 +2084,11 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) Odr_oct ccl_query; IrTcl_SetObj *obj = o; IrTcl_Obj *p; - int r; + int r, code; +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + Tcl_DString ds; +#endif + char *query_str; if (argc <= 0) return TCL_OK; @@ -2045,16 +2101,23 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) NULL); return TCL_ERROR; } - logf (LOG_DEBUG, "search %s %s", *argv, argv[2]); +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + query_str = Tcl_UtfToExternalDString(0, argv[2], -1, &ds); +#else + query_str = argv[2]; +#endif + logf (LOG_DEBUG, "search %s %s", *argv, query_str); if (!obj->set_inher.num_databaseNames) { Tcl_AppendResult (interp, "no databaseNames", NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } if (!p->cs_link) { Tcl_AppendResult (interp, "not connected", NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } apdu = zget_APDU (p->odr_out, Z_APDU_searchRequest); req = apdu->u.searchRequest; @@ -2119,11 +2182,12 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) { Z_RPNQuery *RPNquery; - RPNquery = p_query_rpn (p->odr_out, p->protocol_type, argv[2]); + RPNquery = p_query_rpn (p->odr_out, p->protocol_type, query_str); if (!RPNquery) { Tcl_AppendResult (interp, "query syntax error", NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } query.which = Z_Query_type_1; query.u.type_1 = RPNquery; @@ -2141,18 +2205,19 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) bib1.oclass = CLASS_ATTSET; bib1.value = VAL_BIB1; - rpn = ccl_find_str(p->bibset, argv[2], &error, &pos); + rpn = ccl_find_str(p->bibset, query_str, &error, &pos); if (error) { Tcl_AppendResult (interp, "ccl syntax error ", ccl_err_msg(error), NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } #if 0 ccl_pr_tree (rpn, stderr); fprintf (stderr, "\n"); #endif - assert((RPNquery = ccl_rpn_query(rpn))); + RPNquery = ccl_rpn_query(p->odr_out, rpn); RPNquery->attributeSetId = oid_getoidbyent (&bib1); query.which = Z_Query_type_1; query.u.type_1 = RPNquery; @@ -2162,16 +2227,22 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) { query.which = Z_Query_type_2; query.u.type_2 = &ccl_query; - ccl_query.buf = (unsigned char *) argv[2]; - ccl_query.len = strlen (argv[2]); + ccl_query.buf = (unsigned char *) query_str; + ccl_query.len = strlen (query_str); } else { Tcl_AppendResult (interp, "invalid query method ", obj->set_inher.queryType, NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } - return ir_tcl_send_APDU (interp, p, apdu, "search", *argv); + code = ir_tcl_send_APDU (interp, p, apdu, "search", *argv); + out: +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + Tcl_DStringFree (&ds); +#endif + return code; } /* @@ -2238,7 +2309,7 @@ static int do_presentResponse (void *o, Tcl_Interp *interp, * do_sortResponse: add sort response handler */ static int do_sortResponse (void *o, Tcl_Interp *interp, - int argc, char **argv) + int argc, char **argv) { IrTcl_SetObj *obj = o; @@ -2293,6 +2364,54 @@ static int do_searchStatus (void *o, Tcl_Interp *interp, return ir_tcl_get_set_int (&obj->searchStatus, interp, argc, argv); } +static void reset_searchResult (IrTcl_SetObj *setobj) +{ + int i; + for (i = 0; isearchResult_num; i++) + xfree (setobj->searchResult_terms[i]); + xfree (setobj->searchResult_terms); + xfree (setobj->searchResult_count); + setobj->searchResult_terms = 0; + setobj->searchResult_num = 0; +} + + +/* + * do_searchResult Get USR:Search-Result1 (after search response) + */ +static int do_searchResult (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_SetObj *obj = o; + int i; + + if (argc == 0) + { + obj->searchResult_num = 0; + obj->searchResult_terms = 0; + obj->searchResult_count = 0; + return TCL_OK; + } + else if (argc == -1) + { + reset_searchResult (obj); + return TCL_OK; + } + for (i = 0; isearchResult_num; i++) + { + char str[40]; + sprintf (str, "%d", obj->searchResult_count[i]); + Tcl_AppendResult (interp, "{", NULL); + if (obj->searchResult_terms[i]) + Tcl_AppendElement (interp, obj->searchResult_terms[i]); + else + Tcl_AppendElement (interp, ""); + Tcl_AppendElement (interp, str); + Tcl_AppendResult (interp, "} ", NULL); + } + return TCL_OK; +} + /* * do_presentStatus: Get search status (after search/present response) */ @@ -2640,6 +2759,41 @@ static int do_getSutrs (void *o, Tcl_Interp *interp, int argc, char **argv) return TCL_OK; } +/* + * do_getXml: Get XML Record + */ +static int do_getXml (void *o, Tcl_Interp *interp, int argc, char **argv) +{ + IrTcl_SetObj *obj = o; + int offset; + IrTcl_RecordList *rl; + + if (argc <= 0) + return TCL_OK; + if (argc != 3) + { + Tcl_AppendResult (interp, wrongArgs, *argv, " ", argv[1], + " position\"", NULL); + return TCL_ERROR; + } + if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR) + return TCL_ERROR; + rl = find_IR_record (obj, offset); + if (!rl) + { + Tcl_AppendResult (interp, "No record at #", argv[2], NULL); + return TCL_ERROR; + } + if (rl->which != Z_NamePlusRecord_databaseRecord) + { + Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL); + return TCL_ERROR; + } + if (!rl->u.dbrec.buf || rl->u.dbrec.type != VAL_TEXT_XML) + return TCL_OK; + Tcl_AppendElement (interp, rl->u.dbrec.buf); + return TCL_OK; +} /* * do_getGrs: Get a GRS-1 Record @@ -2761,6 +2915,10 @@ static int do_responseStatus (void *o, Tcl_Interp *interp, Tcl_AppendElement (interp, "NSD"); return ir_diagResult (interp, obj->nonSurrogateDiagnosticList, obj->nonSurrogateDiagnosticNum); + case Z_Records_multipleNSD: + Tcl_AppendElement (interp, "NSD"); + return ir_diagResult (interp, obj->nonSurrogateDiagnosticList, + obj->nonSurrogateDiagnosticNum); } return TCL_OK; } @@ -3183,6 +3341,7 @@ static IrTcl_Method ir_set_method_tab[] = { { "type", do_type, NULL}, { "getMarc", do_getMarc, NULL}, { "getSutrs", do_getSutrs, NULL}, + { "getXml", do_getXml, NULL}, { "getGrs", do_getGrs, NULL}, { "getExplain", do_getExplain, NULL}, { "recordType", do_recordType, NULL}, @@ -3194,6 +3353,7 @@ static IrTcl_Method ir_set_method_tab[] = { { "sort", do_sort, NULL }, { "sortResponse", do_sortResponse, NULL}, { "sortStatus", do_sortStatus, NULL}, + { "searchResult", do_searchResult, NULL}, { NULL, NULL} }; @@ -3379,10 +3539,16 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) Z_APDU *apdu; IrTcl_ScanObj *obj = o; IrTcl_Obj *p = obj->parent; + char *start_term; + int code; #if CCL2RPN oident bib1; struct ccl_rpn_node *rpn; int pos; + int r; +#endif +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + Tcl_DString ds; #endif if (argc <= 0) @@ -3393,16 +3559,23 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) " scanQuery\"", NULL); return TCL_ERROR; } - logf (LOG_DEBUG, "scan %s %s", *argv, argv[2]); +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + start_term = Tcl_UtfToExternalDString(0, argv[2], -1, &ds); +#else + start_term = argv[2]; +#endif + logf (LOG_DEBUG, "scan %s %s", *argv, start_term); if (!p->set_inher.num_databaseNames) { Tcl_AppendResult (interp, "no databaseNames", NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } if (!p->cs_link) { Tcl_AppendResult (interp, "not connected", NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } apdu = zget_APDU (p->odr_out, Z_APDU_scanRequest); @@ -3412,28 +3585,34 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) req->num_databaseNames = p->set_inher.num_databaseNames; req->databaseNames = p->set_inher.databaseNames; -#if !CCL2RPN +#if 1 +/* !CCL2RPN */ if (!(req->termListAndStartPoint = p_query_scan (p->odr_out, p->protocol_type, - &req->attributeSet, argv[2]))) + &req->attributeSet, start_term))) { Tcl_AppendResult (interp, "query syntax error", NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } #else - rpn = ccl_find_str(p->bibset, argv[2], &r, &pos); + rpn = ccl_find_str(p->bibset, start_term, &r, &pos); if (r) { Tcl_AppendResult (interp, "ccl syntax error ", ccl_err_msg(r), NULL); - return ir_tcl_error_exec (interp, argc, argv); + code = ir_tcl_error_exec (interp, argc, argv); + goto out; } bib1.proto = p->protocol_type; bib1.oclass = CLASS_ATTSET; bib1.value = VAL_BIB1; req->attributeSet = oid_getoidbyent (&bib1); - if (!(req->termListAndStartPoint = ccl_scan_query (rpn))) - return TCL_ERROR; + if (!(req->termListAndStartPoint = ccl_scan_query (p->odr_out, rpn))) + { + code = TCL_ERROR; + goto out; + } #endif req->stepSize = &obj->stepSize; req->numberOfTermsRequested = &obj->numberOfTermsRequested; @@ -3444,7 +3623,12 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) logf (LOG_DEBUG, "preferredPositionInResponse=%d", *req->preferredPositionInResponse); - return ir_tcl_send_APDU (interp, p, apdu, "scan", *argv); + code = ir_tcl_send_APDU (interp, p, apdu, "scan", *argv); + out: +#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0) + Tcl_DStringFree (&ds); +#endif + return code; } /* @@ -3719,18 +3903,24 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp, static int ir_log_init_proc (ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { + int lev; if (argc <= 1 || argc > 4) { Tcl_AppendResult (interp, wrongArgs, *argv, " ?level ?prefix ?filename\"", NULL); return TCL_OK; } + lev = yaz_log_mask_str (argv[1]); if (argc == 2) - yaz_log_init (yaz_log_mask_str (argv[1]), "", NULL); + yaz_log_init (lev, "", NULL); else if (argc == 3) - yaz_log_init (yaz_log_mask_str (argv[1]), argv[2], NULL); + yaz_log_init (lev, argv[2], NULL); else - yaz_log_init (yaz_log_mask_str (argv[1]), argv[2], argv[3]); + yaz_log_init (lev, argv[2], argv[3]); + if (lev & LOG_DEBUG) + odr_print_file = yaz_log_file(); + else + odr_print_file = 0; return TCL_OK; } @@ -3818,7 +4008,7 @@ static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num) { int i; for (i = 0; i<*dst_num; i++) - xfree (dst_list[i]->addinfo); + xfree ((*dst_list)[i].addinfo); xfree (*dst_list); *dst_list = NULL; *dst_num = 0; @@ -3927,8 +4117,11 @@ static void ir_handleDBRecord (IrTcl_Obj *p, IrTcl_RecordList *rl, if (oe->which == Z_External_octet && rl->u.dbrec.size > 0) { char *buf = (char*) oe->u.octet_aligned->buf; - if ((rl->u.dbrec.buf = ir_tcl_malloc (rl->u.dbrec.size))) + if ((rl->u.dbrec.buf = ir_tcl_malloc (rl->u.dbrec.size+1))) + { memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size); + rl->u.dbrec.buf[rl->u.dbrec.size] = '\0'; + } } else if (rl->u.dbrec.type == VAL_SUTRS && oe->which == Z_External_sutrs) @@ -4018,6 +4211,77 @@ static void ir_handleZRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, } } +static char *set_queryExpression (Z_QueryExpression *qe) +{ + char *termz = 0; + if (!qe) + return 0; + if (qe->which == Z_QueryExpression_term) + { + if (qe->u.term->queryTerm) + { + Z_Term *term = qe->u.term->queryTerm; + if (term->which == Z_Term_general) + { + termz = xmalloc (term->u.general->len+1); + memcpy (termz, term->u.general->buf, term->u.general->len); + termz[term->u.general->len] = 0; + } + } + } + return termz; +} + +static void set_searchResult (Z_OtherInformation *o, + IrTcl_SetObj *setobj) +{ + int i; + if (!o) + return ; + for (i = 0; i < o->num_elements; i++) + { + if (o->list[i]->which == Z_OtherInfo_externallyDefinedInfo) + { + ODR odr = odr_createmem (ODR_DECODE); + Z_External *ext = o->list[i]->information.externallyDefinedInfo; + Z_SearchInfoReport *sr = 0; + + if (ext->which == Z_External_single) + { + odr_setbuf (odr, ext->u.single_ASN1_type->buf, + ext->u.single_ASN1_type->len, 0); + z_SearchInfoReport (odr, &sr, 0, "searchInfo"); + } + if (ext->which == Z_External_searchResult1) + sr = ext->u.searchResult1; + if (sr) + { + int j; + reset_searchResult (setobj); + + setobj->searchResult_num = sr->num; + setobj->searchResult_terms = + xmalloc (sr->num * sizeof(*setobj->searchResult_terms)); + setobj->searchResult_count = + xmalloc (sr->num * sizeof(*setobj->searchResult_count)); + + for (j = 0; j < sr->num; j++) + { + setobj->searchResult_terms[j] = + set_queryExpression ( + sr->elements[j]->subqueryExpression); + if (sr->elements[j]->subqueryCount) + setobj->searchResult_count[j] = + *sr->elements[j]->subqueryCount; + else + setobj->searchResult_count[j] = 0; + } + } + odr_destroy (odr); + } + } +} + static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, IrTcl_SetObj *setobj) { @@ -4041,6 +4305,7 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, logf (LOG_DEBUG, "status %d hits %d", setobj->searchStatus, setobj->resultCount); + set_searchResult (searchrs->additionalSearchInfo, setobj); if (zrs) { const char *es; @@ -4216,6 +4481,7 @@ static void ir_select_read (ClientData clientData) char *object_name; Tcl_CmdInfo cmd_info; const char *apdu_call; + int round = 0; logf(LOG_DEBUG, "Read handler fd=%d", cs_fileno(p->cs_link)); if (p->state == IR_TCL_R_Connecting) @@ -4254,6 +4520,8 @@ static void ir_select_read (ClientData clientData) { p->state = IR_TCL_R_Reading; + round++; + yaz_log(LOG_DEBUG, "round %d", round); /* read incoming APDU */ if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) == 1) { @@ -4296,12 +4564,16 @@ static void ir_select_read (ClientData clientData) ir_obj_delete ((ClientData) p); return; } + if (p->odr_pr) + z_APDU(p->odr_pr, &apdu, 0, 0); /* handle APDU and invoke callback */ rq = p->request_queue; - if (!rq) - { - logf (LOG_FATAL, "Internal error. No queue entry"); - exit (1); + if (!rq) + { + /* no corresponding request. Skip it. */ + logf(LOG_DEBUG, "no corresponding request. Skipping it"); + p->state = IR_TCL_R_Idle; + return; } object_name = rq->object_name; logf (LOG_DEBUG, "Object %s", object_name); @@ -4492,6 +4764,11 @@ DllEntryPoint(hInst, reason, reserved) */ EXPORT (int,Irtcl_Init) (Tcl_Interp *interp) { +#if USE_TCL_STUBS + if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { + return TCL_ERROR; + } +#endif Tcl_CreateCommand (interp, "ir", ir_obj_mk, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand (interp, "ir-set", ir_set_obj_mk,