/*
* 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.116 2001-02-09 11:58:04 adam
+ * 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
#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)
{
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));
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));
auth->u.open = p->idAuthenticationOpen;
req->idAuthentication = auth;
}
+ else
+ req->idAuthentication = NULL;
req->implementationId = p->implementationId;
req->implementationName = p->implementationName;
req->implementationVersion = p->implementationVersion;
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)
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);
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);
{
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)
}
else if (argc == 5)
{
+ xfree (p->idAuthenticationOpen);
+ p->idAuthenticationOpen = NULL;
if (argv[2][0] &&
ir_tcl_strdup (interp, &p->idAuthenticationGroupId, argv[2])
== TCL_ERROR)
}
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);
if (argc <= 0)
{
- p->largeSetLowerBound = 2;
+ p->largeSetLowerBound = 1;
return TCL_OK;
}
return ir_tcl_get_set_int (&p->largeSetLowerBound, interp, argc, argv);
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);
}
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;
* 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;
return ir_tcl_get_set_int (&obj->searchStatus, interp, argc, argv);
}
+static void reset_searchResult (IrTcl_SetObj *setobj)
+{
+ int i;
+ for (i = 0; i<setobj->searchResult_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; i<obj->searchResult_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)
*/
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;
}
{ "sort", do_sort, NULL },
{ "sortResponse", do_sortResponse, NULL},
{ "sortStatus", do_sortStatus, NULL},
+ { "searchResult", do_searchResult, NULL},
{ NULL, NULL}
};
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, start_term)))
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;
}
{
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;
}
}
+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)
{
logf (LOG_DEBUG, "status %d hits %d",
setobj->searchStatus, setobj->resultCount);
+ set_searchResult (searchrs->additionalSearchInfo, setobj);
if (zrs)
{
const char *es;
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)
{
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)
{
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);
*/
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,