* Sebastian Hammer, Adam Dickmeiss
*
* $Log: ir-tcl.c,v $
- * Revision 1.52 1995-08-04 11:32:38 adam
+ * Revision 1.71 1996-01-19 16:22:38 adam
+ * New method: apduDump - returns information about last incoming APDU.
+ *
+ * Revision 1.70 1996/01/10 09:18:34 adam
+ * PDU specific callbacks implemented: initRespnse, searchResponse,
+ * presentResponse and scanResponse.
+ * Bug fix in the command line shell (tclmain.c) - discovered on OSF/1.
+ *
+ * Revision 1.69 1996/01/04 16:12:12 adam
+ * Setting PDUType renamed to eventType.
+ *
+ * Revision 1.68 1996/01/04 11:05:22 adam
+ * New setting: PDUType - returns type of last PDU returned from the target.
+ * Fixed a bug in configure/Makefile.
+ *
+ * Revision 1.67 1996/01/03 09:00:51 adam
+ * Updated to use new version of Yaz (names changed to avoid C++ conflict).
+ *
+ * Revision 1.66 1995/11/28 17:26:39 adam
+ * Removed Carriage return from ir-tcl.c!
+ * Removed misc. debug logs.
+ *
+ * Revision 1.65 1995/11/28 13:53:00 quinn
+ * Windows port.
+ *
+ * Revision 1.64 1995/11/13 15:39:18 adam
+ * Bug fix: {small,medium}SetElementSetNames weren't set correctly.
+ * Bug fix: idAuthentication weren't set correctly.
+ *
+ * Revision 1.63 1995/11/13 09:55:39 adam
+ * Multiple records at a position in a result-set with differnt
+ * element specs.
+ *
+ * Revision 1.62 1995/10/18 17:20:33 adam
+ * Work on target setup in client.tcl.
+ *
+ * Revision 1.61 1995/10/18 16:42:42 adam
+ * New settings: smallSetElementSetNames and mediumSetElementSetNames.
+ *
+ * Revision 1.60 1995/10/18 15:43:31 adam
+ * In search: mediumSetElementSetNames and smallSetElementSetNames are
+ * set to elementSetNames.
+ *
+ * Revision 1.59 1995/10/17 12:18:58 adam
+ * Bug fix: when target connection closed, the connection was not
+ * properly reestablished.
+ *
+ * Revision 1.58 1995/10/16 17:00:55 adam
+ * New setting: elementSetNames.
+ * Various client improvements. Medium presentation format looks better.
+ *
+ * Revision 1.57 1995/09/21 13:11:51 adam
+ * Support of dynamic loading.
+ * Test script uses load command if necessary.
+ *
+ * Revision 1.56 1995/08/29 15:30:14 adam
+ * Work on GRS records.
+ *
+ * Revision 1.55 1995/08/28 09:43:25 adam
+ * Minor changes. configure only searches for yaz beta 3 and versions after
+ * that.
+ *
+ * Revision 1.54 1995/08/24 12:25:16 adam
+ * Modified to work with yaz 1.0b3.
+ *
+ * Revision 1.53 1995/08/04 12:49:26 adam
+ * Bug fix: reading uninitialized variable p.
+ *
+ * Revision 1.52 1995/08/04 11:32:38 adam
* More work on output queue. Memory related routines moved
* to mem.c
*
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
+#ifdef WINDOWS
+#include <time.h>
+#else
#include <sys/time.h>
+#endif
#include <assert.h>
#define CS_BLOCK 0
IrTcl_Method *tab;
} IrTcl_Methods;
-static Tcl_Interp *irTcl_interp;
-
static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num);
static int do_disconnect (void *obj, Tcl_Interp *interp,
int argc, char **argv);
static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj,
- int no, int which)
+ int no, int which,
+ const char *elements)
{
IrTcl_RecordList *rl;
for (rl = setobj->record_list; rl; rl = rl->next)
{
- if (no == rl->no)
+ if (no == rl->no && (!rl->elements || !elements ||
+ !strcmp(elements, rl->elements)))
{
+ free (rl->elements);
switch (rl->which)
{
case Z_NamePlusRecord_databaseRecord:
- free (rl->u.dbrec.buf);
- rl->u.dbrec.buf = NULL;
+ free (rl->u.dbrec.buf);
+ rl->u.dbrec.buf = NULL;
break;
case Z_NamePlusRecord_surrogateDiagnostic:
ir_deleteDiags (&rl->u.surrogateDiagnostics.list,
setobj->record_list = rl;
}
rl->which = which;
+ ir_tcl_strdup (NULL, &rl->elements, elements);
return rl;
}
{ VAL_AUSMARC, "AUSMARC" },
{ VAL_IBERMARC, "IBERMARC" },
{ VAL_SUTRS, "SUTRS" },
+{ VAL_GRS1, "GRS1" },
{ 0, NULL }
};
IrTcl_RecordList *rl;
for (rl = setobj->record_list; rl; rl = rl->next)
- if (no == rl->no)
+ if (no == rl->no &&
+ (!setobj->recordElements || !rl->elements ||
+ !strcmp (setobj->recordElements, rl->elements)))
return rl;
return NULL;
}
switch (rl->which)
{
case Z_NamePlusRecord_databaseRecord:
- free (rl->u.dbrec.buf);
+ free (rl->u.dbrec.buf);
break;
case Z_NamePlusRecord_surrogateDiagnostic:
ir_deleteDiags (&rl->u.surrogateDiagnostics.list,
&rl->u.surrogateDiagnostics.num);
break;
- }
- rl1 = rl->next;
- free (rl);
+ }
+ rl1 = rl->next;
+ free (rl);
}
setobj->record_list = NULL;
}
for (tab_i = tab; tab_i->tab; tab_i++)
for (t = tab_i->tab; t->name; t++)
- if (argc <= 0)
- {
- if ((*t->method)(tab_i->obj, interp, argc, argv) == TCL_ERROR)
- return TCL_ERROR;
+ if (argc <= 0)
+ {
+ if ((*t->method)(tab_i->obj, interp, argc, argv) == TCL_ERROR)
+ return TCL_ERROR;
}
- else
+ else
if (!strcmp (t->name, argv[1]))
return (*t->method)(tab_i->obj, interp, argc, argv);
else
{
*dst = odr_malloc (o, sizeof(**dst));
- (*dst)->size = (*dst)->len = strlen(src);
- (*dst)->buf = odr_malloc (o, (*dst)->len);
- memcpy ((*dst)->buf, src, (*dst)->len);
+ (*dst)->size = (*dst)->len = strlen(src);
+ (*dst)->buf = odr_malloc (o, (*dst)->len);
+ memcpy ((*dst)->buf, src, (*dst)->len);
}
}
if (!src)
{
*dst = NULL;
- return;
+ return;
}
*dst = ir_tcl_malloc (src->len+1);
memcpy (*dst, src->buf, src->len);
return TCL_OK;
if (!p->cs_link)
{
- interp->result = "not connected";
+ interp->result = "init: not connected";
return TCL_ERROR;
}
apdu = zget_APDU (p->odr_out, Z_APDU_initRequest);
Z_IdPass *pass = odr_malloc (p->odr_out, sizeof(*pass));
Z_IdAuthentication *auth = odr_malloc (p->odr_out, sizeof(*auth));
+ logf (LOG_DEBUG, "using pass authentication");
+
auth->which = Z_IdAuthentication_idPass;
auth->u.idPass = pass;
if (p->idAuthenticationGroupId && *p->idAuthenticationGroupId)
{
Z_IdAuthentication *auth = odr_malloc (p->odr_out, sizeof(*auth));
+ logf (LOG_DEBUG, "using open authentication");
auth->which = Z_IdAuthentication_open;
auth->u.open = p->idAuthenticationOpen;
req->idAuthentication = auth;
req->implementationVersion = p->implementationVersion;
req->userInformationField = 0;
- return ir_tcl_send_APDU (interp, p, apdu, "init", argv[0]);
+ return ir_tcl_send_APDU (interp, p, apdu, "init", *argv);
}
/*
if (argc <= 0)
{
ODR_MASK_ZERO (&p->protocolVersion);
- ODR_MASK_SET (&p->protocolVersion, 0);
- ODR_MASK_SET (&p->protocolVersion, 1);
+ ODR_MASK_SET (&p->protocolVersion, 0);
+ ODR_MASK_SET (&p->protocolVersion, 1);
return TCL_OK;
}
if (argc == 3)
if (argc <= 0)
{
ODR_MASK_ZERO (&p->options);
- ODR_MASK_SET (&p->options, 0);
- ODR_MASK_SET (&p->options, 1);
+ ODR_MASK_SET (&p->options, 0);
+ ODR_MASK_SET (&p->options, 1);
ODR_MASK_SET (&p->options, 4);
- ODR_MASK_SET (&p->options, 7);
- ODR_MASK_SET (&p->options, 14);
- return TCL_OK;
+ ODR_MASK_SET (&p->options, 7);
+ ODR_MASK_SET (&p->options, 14);
+ return TCL_OK;
}
return ir_named_bits (options_tab, &p->options, interp, argc-2, argv+2);
}
/*
+ * do_apduInfo: Get APDU information
+ */
+static int do_apduInfo (void *obj, Tcl_Interp *interp, int argc, char **argv)
+{
+ char buf[16];
+ FILE *apduf;
+ IrTcl_Obj *p = obj;
+
+ if (argc <= 0)
+ return TCL_OK;
+ sprintf (buf, "%d", p->apduLen);
+ Tcl_AppendElement (interp, buf);
+ sprintf (buf, "%d", p->apduOffset);
+ Tcl_AppendElement (interp, buf);
+ if (!p->buf_in)
+ {
+ Tcl_AppendElement (interp, "");
+ return TCL_OK;
+ }
+ apduf = fopen ("apdu.tmp", "w");
+ if (!apduf)
+ {
+ Tcl_AppendElement (interp, "");
+ return TCL_OK;
+ }
+ odr_dumpBER (apduf, p->buf_in, p->apduLen);
+ fclose (apduf);
+ if (!(apduf = fopen ("apdu.tmp", "r")))
+ Tcl_AppendElement (interp, "");
+ else
+ {
+ int c;
+
+ Tcl_AppendResult (interp, " {", NULL);
+ while ((c = getc (apduf)) != EOF)
+ {
+ buf[0] = c;
+ buf[1] = '\0';
+ Tcl_AppendResult (interp, buf, NULL);
+ }
+ fclose (apduf);
+ Tcl_AppendResult (interp, "}", NULL);
+ }
+ unlink ("apdu.tmp");
+ return TCL_OK;
+}
+
+/*
* do_failInfo: Get fail information
*/
static int do_failInfo (void *obj, Tcl_Interp *interp, int argc, char **argv)
if (argc <= 0)
{
p->failInfo = 0;
- return TCL_OK;
+ return TCL_OK;
}
sprintf (buf, "%d", p->failInfo);
switch (p->failInfo)
if (argc <= 0)
{
p->preferredMessageSize = 30000;
- return TCL_OK;
+ return TCL_OK;
}
return get_set_int (&p->preferredMessageSize, interp, argc, argv);
}
if (argc <= 0)
{
p->maximumRecordSize = 30000;
- return TCL_OK;
+ return TCL_OK;
}
return get_set_int (&p->maximumRecordSize, interp, argc, argv);
}
if (argc == 0)
{
p->targetImplementationName = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
return ir_tcl_strdel (interp, &p->targetImplementationName);
if (argc == 0)
{
p->targetImplementationId = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
return ir_tcl_strdel (interp, &p->targetImplementationId);
if (argc == 0)
{
p->targetImplementationVersion = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
return ir_tcl_strdel (interp, &p->targetImplementationVersion);
{
if (argc == 3)
{
- if (ir_tcl_strdup (interp, &p->idAuthenticationOpen, argv[2])
+ if (argv[2][0] &&
+ ir_tcl_strdup (interp, &p->idAuthenticationOpen, argv[2])
== TCL_ERROR)
return TCL_ERROR;
}
else if (argc == 5)
{
- if (ir_tcl_strdup (interp, &p->idAuthenticationGroupId, argv[2])
+ if (argv[2][0] &&
+ ir_tcl_strdup (interp, &p->idAuthenticationGroupId, argv[2])
== TCL_ERROR)
return TCL_ERROR;
- if (ir_tcl_strdup (interp, &p->idAuthenticationUserId, argv[3])
+ if (argv[3][0] &&
+ ir_tcl_strdup (interp, &p->idAuthenticationUserId, argv[3])
== TCL_ERROR)
return TCL_ERROR;
- if (ir_tcl_strdup (interp, &p->idAuthenticationPassword, argv[4])
+ if (argv[4][0] &&
+ ir_tcl_strdup (interp, &p->idAuthenticationPassword, argv[4])
== TCL_ERROR)
return TCL_ERROR;
}
* do_connect: connect method on IR object
*/
static int do_connect (void *obj, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
void *addr;
IrTcl_Obj *p = obj;
interp->result = "already connected";
return TCL_ERROR;
}
+ if (ir_tcl_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR)
+ return TCL_ERROR;
if (!strcmp (p->cs_type, "tcpip"))
{
p->cs_link = cs_create (tcpip_type, CS_BLOCK, p->protocol_type);
p->cs_type, NULL);
return TCL_ERROR;
}
- if (ir_tcl_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR)
- return TCL_ERROR;
if ((r=cs_connect (p->cs_link, addr)) < 0)
{
interp->result = "connect fail";
do_disconnect (p, NULL, 2, NULL);
return TCL_ERROR;
}
+ p->eventType = "connect";
ir_select_add (cs_fileno (p->cs_link), p);
if (r == 1)
{
IrTcl_eval (p->interp, p->callback);
}
}
+ else
+ Tcl_AppendResult (interp, p->hostname, NULL);
return TCL_OK;
}
if (argc == 0)
{
p->state = IR_TCL_R_Idle;
+ p->eventType = NULL;
p->hostname = NULL;
- p->cs_link = NULL;
+ p->cs_link = NULL;
return TCL_OK;
}
if (p->hostname)
ir_select_remove_write (cs_fileno (p->cs_link), p);
ir_select_remove (cs_fileno (p->cs_link), p);
+ odr_reset (p->odr_in);
+
assert (p->cs_link);
cs_close (p->cs_link);
p->cs_link = NULL;
ODR_MASK_ZERO (&p->options);
- ODR_MASK_SET (&p->options, 0);
- ODR_MASK_SET (&p->options, 1);
- ODR_MASK_SET (&p->options, 4);
- ODR_MASK_SET (&p->options, 7);
- ODR_MASK_SET (&p->options, 14);
+ ODR_MASK_SET (&p->options, 0);
+ ODR_MASK_SET (&p->options, 1);
+ ODR_MASK_SET (&p->options, 4);
+ ODR_MASK_SET (&p->options, 7);
+ ODR_MASK_SET (&p->options, 14);
ODR_MASK_ZERO (&p->protocolVersion);
- ODR_MASK_SET (&p->protocolVersion, 0);
- ODR_MASK_SET (&p->protocolVersion, 1);
+ ODR_MASK_SET (&p->protocolVersion, 0);
+ ODR_MASK_SET (&p->protocolVersion, 1);
ir_tcl_del_q (p);
}
assert (!p->cs_link);
* do_comstack: Set/get comstack method on IR object
*/
static int do_comstack (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_Obj *obj = o;
/*
+ * do_eventType: Return type of last event
+ */
+static int do_eventType (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_Obj *p = obj;
+
+ if (argc <= 0)
+ {
+ p->eventType = NULL;
+ return TCL_OK;
+ }
+ Tcl_AppendElement (interp, p->eventType ? p->eventType : "");
+ return TCL_OK;
+}
+
+
+/*
* do_callback: add callback
*/
static int do_callback (void *obj, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_Obj *p = obj;
if (argc == 0)
{
p->callback = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
return ir_tcl_strdel (interp, &p->callback);
if (argc == 3)
{
free (p->callback);
- if (argv[2][0])
- {
+ if (argv[2][0])
+ {
if (ir_tcl_strdup (interp, &p->callback, argv[2]) == TCL_ERROR)
return TCL_ERROR;
- }
- else
- p->callback = NULL;
- p->interp = interp;
+ }
+ else
+ p->callback = NULL;
}
return TCL_OK;
}
if (argc == 0)
{
p->failback = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
return ir_tcl_strdel (interp, &p->failback);
else if (argc == 3)
{
free (p->failback);
- if (argv[2][0])
- {
+ if (argv[2][0])
+ {
if (ir_tcl_strdup (interp, &p->failback, argv[2]) == TCL_ERROR)
return TCL_ERROR;
- }
- else
- p->failback = NULL;
- p->interp = interp;
+ }
+ else
+ p->failback = NULL;
}
return TCL_OK;
}
/*
+ * do_initResponse: add init response handler
+ */
+static int do_initResponse (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_Obj *p = obj;
+
+ if (argc == 0)
+ {
+ p->initResponse = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &p->initResponse);
+ if (argc == 3)
+ {
+ free (p->initResponse);
+ if (argv[2][0])
+ {
+ if (ir_tcl_strdup (interp, &p->initResponse, argv[2]) == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ p->initResponse = NULL;
+ }
+ return TCL_OK;
+}
+/*
* do_protocol: Set/get protocol method on IR object
*/
static int do_protocol (void *o, Tcl_Interp *interp, int argc, char **argv)
return TCL_OK;
if (!p->cs_link)
{
- interp->result = "not connected";
+ interp->result = "triggerResourceControl: not connected";
return TCL_ERROR;
}
apdu = zget_APDU (p->odr_out, Z_APDU_triggerResourceControlRequest);
if (argc <= 0)
{
p->num_databaseNames = 0;
- p->databaseNames = NULL;
- return TCL_OK;
+ p->databaseNames = NULL;
+ return TCL_OK;
}
if (argc < 3)
{
if (argc <= 0)
{
p->replaceIndicator = 1;
- return TCL_OK;
+ return TCL_OK;
}
return get_set_int (&p->replaceIndicator, interp, argc, argv);
}
* do_queryType: Set/Get query method
*/
static int do_queryType (void *obj, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetCObj *p = obj;
if (argc == 0)
{
p->userInformationField = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
return ir_tcl_strdel (interp, &p->userInformationField);
* do_smallSetUpperBound: Set/get small set upper bound
*/
static int do_smallSetUpperBound (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetCObj *p = o;
if (argc <= 0)
{
p->smallSetUpperBound = 0;
- return TCL_OK;
+ return TCL_OK;
}
return get_set_int (&p->smallSetUpperBound, interp, argc, argv);
}
if (argc <= 0)
{
p->largeSetLowerBound = 2;
- return TCL_OK;
+ return TCL_OK;
}
return get_set_int (&p->largeSetLowerBound, interp, argc, argv);
}
if (argc <= 0)
{
p->mediumSetPresentNumber = 0;
- return TCL_OK;
+ return TCL_OK;
}
return get_set_int (&p->mediumSetPresentNumber, interp, argc, argv);
}
* do_referenceId: Set/Get referenceId
*/
static int do_referenceId (void *obj, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetCObj *p = obj;
}
+/*
+ * do_elementSetNames: Set/Get element Set Names
+ */
+static int do_elementSetNames (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetCObj *p = obj;
+
+ if (argc == 0)
+ {
+ p->elementSetNames = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &p->elementSetNames);
+ if (argc == 3)
+ {
+ free (p->elementSetNames);
+ if (ir_tcl_strdup (interp, &p->elementSetNames, argv[2]) == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ Tcl_AppendResult (interp, p->elementSetNames, NULL);
+ return TCL_OK;
+}
+
+/*
+ * do_smallSetElementSetNames: Set/Get small Set Element Set Names
+ */
+static int do_smallSetElementSetNames (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetCObj *p = obj;
+
+ if (argc == 0)
+ {
+ p->smallSetElementSetNames = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &p->smallSetElementSetNames);
+ if (argc == 3)
+ {
+ free (p->smallSetElementSetNames);
+ if (ir_tcl_strdup (interp, &p->smallSetElementSetNames,
+ argv[2]) == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ Tcl_AppendResult (interp, p->smallSetElementSetNames, NULL);
+ return TCL_OK;
+}
+
+/*
+ * do_mediumSetElementSetNames: Set/Get medium Set Element Set Names
+ */
+static int do_mediumSetElementSetNames (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetCObj *p = obj;
+
+ if (argc == 0)
+ {
+ p->mediumSetElementSetNames = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &p->mediumSetElementSetNames);
+ if (argc == 3)
+ {
+ free (p->mediumSetElementSetNames);
+ if (ir_tcl_strdup (interp, &p->mediumSetElementSetNames,
+ argv[2]) == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ Tcl_AppendResult (interp, p->mediumSetElementSetNames, NULL);
+ return TCL_OK;
+}
+
static IrTcl_Method ir_method_tab[] = {
{ 1, "comstack", do_comstack },
{ 1, "protocol", do_protocol },
{ 0, "failback", do_failback },
{ 0, "failInfo", do_failInfo },
+{ 0, "apduInfo", do_apduInfo },
{ 0, "logLevel", do_logLevel },
+{ 0, "eventType", do_eventType },
{ 1, "connect", do_connect },
{ 0, "protocolVersion", do_protocolVersion },
{ 1, "preferredMessageSize", do_preferredMessageSize },
{ 0, "initResult", do_initResult },
{ 0, "disconnect", do_disconnect },
{ 0, "callback", do_callback },
+{ 0, "initResponse", do_initResponse },
{ 0, "triggerResourceControl", do_triggerResourceControl },
+{ 0, "initResponse", do_initResponse },
{ 0, NULL, NULL}
};
{ 0, "largeSetLowerBound", do_largeSetLowerBound},
{ 0, "mediumSetPresentNumber", do_mediumSetPresentNumber},
{ 0, "referenceId", do_referenceId },
+{ 0, "elementSetNames", do_elementSetNames },
+{ 0, "smallSetElementSetNames", do_smallSetElementSetNames },
+{ 0, "mediumSetElementSetNames", do_mediumSetElementSetNames },
{ 0, NULL, NULL}
};
obj->bibset = ccl_qual_mk ();
if ((inf = fopen ("default.bib", "r")))
{
- ccl_qual_file (obj->bibset, inf);
- fclose (inf);
+ ccl_qual_file (obj->bibset, inf);
+ fclose (inf);
}
#endif
obj->odr_out = odr_createmem (ODR_ENCODE);
obj->odr_pr = odr_createmem (ODR_PRINT);
obj->state = IR_TCL_R_Idle;
+ obj->interp = interp;
obj->len_in = 0;
obj->buf_in = NULL;
}
if (!p->cs_link)
{
- interp->result = "not connected";
+ interp->result = "search: not connected";
return TCL_ERROR;
}
apdu = zget_APDU (p->odr_out, Z_APDU_searchRequest);
req = apdu->u.searchRequest;
+ obj->start = 1;
+
bib1.proto = p->protocol_type;
- bib1.class = CLASS_ATTSET;
+ bib1.oclass = CLASS_ATTSET;
bib1.value = VAL_BIB1;
set_referenceId (p->odr_out, &req->referenceId,
req->databaseNames = obj->set_inher.databaseNames;
for (r=0; r < obj->set_inher.num_databaseNames; r++)
logf (LOG_DEBUG, " Database %s", obj->set_inher.databaseNames[r]);
- req->smallSetElementSetNames = 0;
- req->mediumSetElementSetNames = 0;
if (obj->set_inher.preferredRecordSyntax)
{
struct oident ident;
ident.proto = p->protocol_type;
- ident.class = CLASS_RECSYN;
+ ident.oclass = CLASS_RECSYN;
ident.value = *obj->set_inher.preferredRecordSyntax;
logf (LOG_DEBUG, "Preferred record syntax is %d", ident.value);
req->preferredRecordSyntax = odr_oiddup (p->odr_out,
}
else
req->preferredRecordSyntax = 0;
- req->query = &query;
+ if (obj->set_inher.smallSetElementSetNames &&
+ *obj->set_inher.smallSetElementSetNames)
+ {
+ Z_ElementSetNames *esn = odr_malloc (p->odr_out, sizeof(*esn));
+
+ esn->which = Z_ElementSetNames_generic;
+ esn->u.generic = obj->set_inher.smallSetElementSetNames;
+ req->smallSetElementSetNames = esn;
+ }
+ else
+ req->smallSetElementSetNames = NULL;
+
+ if (obj->set_inher.mediumSetElementSetNames &&
+ *obj->set_inher.mediumSetElementSetNames)
+ {
+ Z_ElementSetNames *esn = odr_malloc (p->odr_out, sizeof(*esn));
+
+ esn->which = Z_ElementSetNames_generic;
+ esn->u.generic = obj->set_inher.mediumSetElementSetNames;
+ req->mediumSetElementSetNames = esn;
+ }
+ else
+ req->mediumSetElementSetNames = NULL;
+
+ req->query = &query;
+
if (!strcmp (obj->set_inher.queryType, "rpn"))
{
Z_RPNQuery *RPNquery;
RPNquery = p_query_rpn (p->odr_out, argv[2]);
- if (!RPNquery)
- {
+ if (!RPNquery)
+ {
Tcl_AppendResult (interp, "Syntax error in query", NULL);
return TCL_ERROR;
}
if (error)
{
Tcl_AppendResult (interp, "CCL error: ",
- ccl_err_msg(error), NULL);
+ ccl_err_msg(error), NULL);
return TCL_ERROR;
}
ccl_pr_tree (rpn, stderr);
interp->result = "unknown query method";
return TCL_ERROR;
}
- return ir_tcl_send_APDU (interp, p, apdu, "search", argv[0]);
+ return ir_tcl_send_APDU (interp, p, apdu, "search", *argv);
+}
+
+/*
+ * do_searchResponse: add search response handler
+ */
+static int do_searchResponse (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+
+ if (argc == 0)
+ {
+ obj->searchResponse = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &obj->searchResponse);
+ if (argc == 3)
+ {
+ free (obj->searchResponse);
+ if (argv[2][0])
+ {
+ if (ir_tcl_strdup (interp, &obj->searchResponse, argv[2])
+ == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ obj->searchResponse = NULL;
+ }
+ return TCL_OK;
+}
+
+/*
+ * do_presentResponse: add present response handler
+ */
+static int do_presentResponse (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+
+ if (argc == 0)
+ {
+ obj->presentResponse = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &obj->presentResponse);
+ if (argc == 3)
+ {
+ free (obj->presentResponse);
+ if (argv[2][0])
+ {
+ if (ir_tcl_strdup (interp, &obj->presentResponse, argv[2])
+ == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ obj->presentResponse = NULL;
+ }
+ return TCL_OK;
}
/*
* do_resultCount: Get number of hits
*/
static int do_resultCount (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetObj *obj = o;
* do_searchStatus: Get search status (after search response)
*/
static int do_searchStatus (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetObj *obj = o;
* do_presentStatus: Get search status (after search/present response)
*/
static int do_presentStatus (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetObj *obj = o;
* do_setName: Set result Set name
*/
static int do_setName (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+ int argc, char **argv)
{
IrTcl_SetObj *obj = o;
if (argc == 0)
{
obj->record_list = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
{
delete_IR_records (obj);
- return TCL_OK;
+ return TCL_OK;
}
- if (argc < 3)
+ if (argc != 3)
{
sprintf (interp->result, "wrong # args");
return TCL_ERROR;
return TCL_ERROR;
rl = find_IR_record (obj, offset);
if (!rl)
+ {
+ logf (LOG_DEBUG, "No record at position %d", offset);
return TCL_OK;
+ }
switch (rl->which)
{
case Z_NamePlusRecord_databaseRecord:
if (argc == 0)
{
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
{
- return TCL_OK;
+ return TCL_OK;
}
- if (argc < 3)
+ if (argc != 3)
{
sprintf (interp->result, "wrong # args");
return TCL_ERROR;
}
/*
+ * set record elements (for record extraction)
+ */
+static int do_recordElements (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+
+ if (argc == 0)
+ {
+ obj->recordElements = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (NULL, &obj->recordElements);
+ if (argc > 3)
+ {
+ sprintf (interp->result, "wrong # args");
+ return TCL_ERROR;
+ }
+ if (argc == 3)
+ {
+ free (obj->recordElements);
+ return ir_tcl_strdup (NULL, &obj->recordElements,
+ (*argv[2] ? argv[2] : NULL));
+ }
+ Tcl_AppendResult (interp, obj->recordElements, NULL);
+ return TCL_OK;
+}
+
+/*
* ir_diagResult
*/
static int ir_diagResult (Tcl_Interp *interp, IrTcl_Diagnostic *list, int num)
if (argc <= 0)
return TCL_OK;
- if (argc < 3)
+ if (argc != 3)
{
sprintf (interp->result, "wrong # args");
return TCL_ERROR;
if (argc <= 0)
return TCL_OK;
- if (argc < 3)
+ if (argc != 3)
{
sprintf (interp->result, "wrong # args");
return TCL_ERROR;
/*
+ * do_getGrs: Get a GRS1 Record
+ */
+static int do_getGrs (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)
+ {
+ sprintf (interp->result, "wrong # args");
+ 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.type != VAL_GRS1)
+ return TCL_OK;
+ return ir_tcl_get_grs (interp, rl->u.dbrec.u.grs1, argc, argv);
+}
+
+
+/*
* do_responseStatus: Return response status (present or search)
*/
static int do_responseStatus (void *o, Tcl_Interp *interp,
obj->recordFlag = 0;
obj->nonSurrogateDiagnosticNum = 0;
obj->nonSurrogateDiagnosticList = NULL;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
{
switch (obj->which)
{
case Z_Records_DBOSD:
- Tcl_AppendElement (interp, "DBOSD");
+ Tcl_AppendElement (interp, "DBOSD");
break;
case Z_Records_NSD:
Tcl_AppendElement (interp, "NSD");
* do_present: Perform Present Request
*/
-static int do_present (void *o, Tcl_Interp *interp,
- int argc, char **argv)
+static int do_present (void *o, Tcl_Interp *interp, int argc, char **argv)
{
IrTcl_SetObj *obj = o;
IrTcl_Obj *p;
}
else
number = 10;
+ p = obj->parent;
if (!p->cs_link)
{
- interp->result = "not connected";
+ interp->result = "present: not connected";
return TCL_ERROR;
}
- p = obj->parent;
obj->start = start;
obj->number = number;
struct oident ident;
ident.proto = p->protocol_type;
- ident.class = CLASS_RECSYN;
+ ident.oclass = CLASS_RECSYN;
ident.value = *obj->set_inher.preferredRecordSyntax;
logf (LOG_DEBUG, "Preferred record syntax is %d", ident.value);
req->preferredRecordSyntax = odr_oiddup (p->odr_out,
}
else
req->preferredRecordSyntax = 0;
-
- return ir_tcl_send_APDU (interp, p, apdu, "present", argv[0]);
+
+ if (obj->set_inher.elementSetNames && *obj->set_inher.elementSetNames)
+ {
+ Z_ElementSetNames *esn = odr_malloc (p->odr_out, sizeof(*esn));
+ Z_RecordComposition *compo = odr_malloc (p->odr_out, sizeof(*compo));
+
+ esn->which = Z_ElementSetNames_generic;
+ esn->u.generic = obj->set_inher.elementSetNames;
+
+ req->recordComposition = compo;
+ compo->which = Z_RecordComp_simple;
+ compo->u.simple = esn;
+ }
+ else
+ req->recordComposition = NULL;
+ return ir_tcl_send_APDU (interp, p, apdu, "present", *argv);
}
/*
if (argc <= 0)
return TCL_OK;
- if (argc < 3)
+ if (argc != 3)
{
interp->result = "wrong # args";
return TCL_ERROR;
{
IrTcl_RecordList *rl;
- rl = new_IR_record (setobj, no, Z_NamePlusRecord_databaseRecord);
+ rl = new_IR_record (setobj, no, Z_NamePlusRecord_databaseRecord, "F");
rl->u.dbrec.type = VAL_USMARC;
rl->u.dbrec.buf = buf;
- rl->u.dbrec.size = size;
+ rl->u.dbrec.size = size;
no++;
}
setobj->numberOfRecordsReturned = no-1;
static IrTcl_Method ir_set_method_tab[] = {
{ 0, "search", do_search },
+ { 0, "searchResponse", do_searchResponse },
+ { 0, "presentResponse", do_presentResponse },
{ 0, "searchStatus", do_searchStatus },
{ 0, "presentStatus", do_presentStatus },
{ 0, "nextResultSetPosition", do_nextResultSetPosition },
{ 0, "type", do_type },
{ 0, "getMarc", do_getMarc },
{ 0, "getSutrs", do_getSutrs },
+ { 0, "getGrs", do_getGrs },
{ 0, "recordType", do_recordType },
+ { 0, "recordElements", do_recordElements },
{ 0, "diag", do_diag },
{ 0, "responseStatus", do_responseStatus },
{ 0, "loadFile", do_loadFile },
dst = &obj->set_inher;
src = &obj->parent->set_inher;
- dst->num_databaseNames = src->num_databaseNames;
- dst->databaseNames =
- ir_tcl_malloc (sizeof (*dst->databaseNames)
- * dst->num_databaseNames);
+ if ((dst->num_databaseNames = src->num_databaseNames))
+ dst->databaseNames =
+ ir_tcl_malloc (sizeof (*dst->databaseNames)
+ * dst->num_databaseNames);
+ else
+ dst->databaseNames = NULL;
for (i = 0; i < dst->num_databaseNames; i++)
- {
if (ir_tcl_strdup (interp, &dst->databaseNames[i],
src->databaseNames[i]) == TCL_ERROR)
return TCL_ERROR;
- }
if (ir_tcl_strdup (interp, &dst->queryType, src->queryType)
== TCL_ERROR)
return TCL_ERROR;
== TCL_ERROR)
return TCL_ERROR;
+ if (ir_tcl_strdup (interp, &dst->elementSetNames, src->elementSetNames)
+ == TCL_ERROR)
+ return TCL_ERROR;
+
+ if (ir_tcl_strdup (interp, &dst->smallSetElementSetNames,
+ src->smallSetElementSetNames)
+ == TCL_ERROR)
+ return TCL_ERROR;
+
+ if (ir_tcl_strdup (interp, &dst->mediumSetElementSetNames,
+ src->mediumSetElementSetNames)
+ == TCL_ERROR)
+ return TCL_ERROR;
+
if (src->preferredRecordSyntax &&
(dst->preferredRecordSyntax
= ir_tcl_malloc (sizeof(*dst->preferredRecordSyntax))))
if (!p->set_inher.num_databaseNames)
{
interp->result = "no databaseNames";
- return TCL_ERROR;
+ return TCL_ERROR;
}
if (!p->cs_link)
{
- interp->result = "not connected";
- return TCL_ERROR;
+ interp->result = "scan: not connected";
+ return TCL_ERROR;
}
bib1.proto = p->protocol_type;
- bib1.class = CLASS_ATTSET;
+ bib1.oclass = CLASS_ATTSET;
bib1.value = VAL_BIB1;
apdu = zget_APDU (p->odr_out, Z_APDU_scanRequest);
if (!(req->termListAndStartPoint = p_query_scan (p->odr_out, argv[2])))
{
Tcl_AppendResult (interp, "Syntax error in query", NULL);
- return TCL_ERROR;
+ return TCL_ERROR;
}
#else
rpn = ccl_find_str(p->bibset, argv[2], &r, &pos);
logf (LOG_DEBUG, "preferredPositionInResponse=%d",
*req->preferredPositionInResponse);
- return ir_tcl_send_APDU (interp, p, apdu, "scan", argv[0]);
+ return ir_tcl_send_APDU (interp, p, apdu, "scan", *argv);
+}
+
+/*
+ * do_scanResponse: add scan response handler
+ */
+static int do_scanResponse (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *obj = o;
+
+ if (argc == 0)
+ {
+ obj->scanResponse = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &obj->scanResponse);
+ if (argc == 3)
+ {
+ free (obj->scanResponse);
+ if (argv[2][0])
+ {
+ if (ir_tcl_strdup (interp, &obj->scanResponse, argv[2])
+ == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ obj->scanResponse = NULL;
+ }
+ return TCL_OK;
}
/*
if (argc == 0)
{
p->entries_flag = 0;
- p->entries = NULL;
- p->nonSurrogateDiagnosticNum = 0;
+ p->entries = NULL;
+ p->nonSurrogateDiagnosticNum = 0;
p->nonSurrogateDiagnosticList = 0;
- return TCL_OK;
+ return TCL_OK;
}
else if (argc == -1)
{
p->entries_flag = 0;
- /* release entries */
+ /* release entries */
p->entries = NULL;
ir_deleteDiags (&p->nonSurrogateDiagnosticList,
&p->nonSurrogateDiagnosticNum);
- return TCL_OK;
+ return TCL_OK;
}
if (argc != 3)
{
interp->result = "wrong # args";
- return TCL_ERROR;
+ return TCL_ERROR;
}
if (Tcl_GetInt (interp, argv[2], &i) == TCL_ERROR)
return TCL_ERROR;
{
case Z_Entry_termInfo:
Tcl_AppendElement (interp, "T");
- if (p->entries[i].u.term.buf)
- Tcl_AppendElement (interp, p->entries[i].u.term.buf);
- else
- Tcl_AppendElement (interp, "");
- sprintf (numstr, "%d", p->entries[i].u.term.globalOccurrences);
- Tcl_AppendElement (interp, numstr);
- break;
+ if (p->entries[i].u.term.buf)
+ Tcl_AppendElement (interp, p->entries[i].u.term.buf);
+ else
+ Tcl_AppendElement (interp, "");
+ sprintf (numstr, "%d", p->entries[i].u.term.globalOccurrences);
+ Tcl_AppendElement (interp, numstr);
+ break;
case Z_Entry_surrogateDiagnostic:
Tcl_AppendElement (interp, "SD");
return ir_diagResult (interp, p->entries[i].u.diag.list,
p->entries[i].u.diag.num);
- break;
+ break;
}
return TCL_OK;
}
static IrTcl_Method ir_scan_method_tab[] = {
{ 0, "scan", do_scan },
+ { 0, "scanResponse", do_scanResponse },
{ 0, "stepSize", do_stepSize },
{ 0, "numberOfTermsRequested", do_numberOfTermsRequested },
{ 0, "preferredPositionInResponse", do_preferredPositionInResponse },
if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info))
{
interp->result = "No parent";
- return TCL_ERROR;
+ return TCL_ERROR;
}
obj = ir_tcl_malloc (sizeof(*obj));
obj->parent = (IrTcl_Obj *) parent_info.clientData;
}
}
-static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj)
+static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj,
+ const char *elements)
{
IrTcl_Obj *p = o;
{
rl = new_IR_record (setobj, setobj->start + offset,
zrs->u.databaseOrSurDiagnostics->
- records[offset]->which);
+ records[offset]->which,
+ elements);
if (rl->which == Z_NamePlusRecord_surrogateDiagnostic)
{
ir_handleDiags (&rl->u.surrogateDiagnostics.list,
else
{
Z_DatabaseRecord *zr;
- Odr_external *oe;
+ Z_External *oe;
struct oident *ident;
zr = zrs->u.databaseOrSurDiagnostics->records[offset]
->u.databaseRecord;
- oe = (Odr_external*) zr;
- rl->u.dbrec.size = zr->u.octet_aligned->len;
+ oe = (Z_External*) zr;
+ rl->u.dbrec.size = zr->u.octet_aligned->len;
- rl->u.dbrec.type = VAL_USMARC;
if ((ident = oid_getentbyoid (oe->direct_reference)))
rl->u.dbrec.type = ident->value;
+ else
+ rl->u.dbrec.type = VAL_USMARC;
+
if (oe->which == ODR_EXTERNAL_octet && rl->u.dbrec.size > 0)
{
char *buf = (char*) zr->u.octet_aligned->buf;
if ((rl->u.dbrec.buf = ir_tcl_malloc (rl->u.dbrec.size)))
- memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size);
+ memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size);
}
else if (rl->u.dbrec.type == VAL_SUTRS &&
- oe->which == ODR_EXTERNAL_single)
+ oe->which == Z_External_sutrs)
{
- Odr_oct *rc;
-
- logf (LOG_DEBUG, "Decoding SUTRS");
odr_setbuf (p->odr_in, (char*) oe->u.single_ASN1_type->buf,
oe->u.single_ASN1_type->len, 0);
- if (!z_SUTRS(p->odr_in, &rc, 0))
+ if ((rl->u.dbrec.buf = ir_tcl_malloc (oe->u.sutrs->len+1)))
{
- logf (LOG_WARN, "Cannot decode SUTRS");
- rl->u.dbrec.buf = NULL;
- }
- else
- {
- if ((rl->u.dbrec.buf = ir_tcl_malloc (rc->len+1)))
- {
- memcpy (rl->u.dbrec.buf, rc->buf, rc->len);
- rl->u.dbrec.buf[rc->len] = '\0';
- }
- rl->u.dbrec.size = rc->len;
+ memcpy (rl->u.dbrec.buf, oe->u.sutrs->buf,
+ oe->u.sutrs->len);
+ rl->u.dbrec.buf[oe->u.sutrs->len] = '\0';
}
+ rl->u.dbrec.size = oe->u.sutrs->len;
+ }
+ else if (rl->u.dbrec.type == VAL_GRS1 &&
+ oe->which == Z_External_grs1)
+ {
+ ir_tcl_read_grs (oe->u.grs1, &rl->u.dbrec.u.grs1);
+ rl->u.dbrec.buf = NULL;
}
else
rl->u.dbrec.buf = NULL;
if (!setobj)
{
logf (LOG_DEBUG, "Search response, no object!");
- return;
+ return;
}
setobj->searchStatus = searchrs->searchStatus ? 1 : 0;
get_referenceId (&setobj->set_inher.referenceId, searchrs->referenceId);
logf (LOG_DEBUG, "Search response %d, %d hits",
setobj->searchStatus, setobj->resultCount);
if (zrs)
- ir_handleRecords (o, zrs, setobj);
+ {
+ const char *es;
+ if (setobj->resultCount <= setobj->set_inher.smallSetUpperBound)
+ es = setobj->set_inher.smallSetElementSetNames;
+ else
+ es = setobj->set_inher.mediumSetElementSetNames;
+ ir_handleRecords (o, zrs, setobj, es);
+ }
else
setobj->recordFlag = 0;
}
if (!setobj)
{
logf (LOG_DEBUG, "Present response, no object!");
- return;
+ return;
}
setobj->presentStatus = *presrs->presentStatus;
get_referenceId (&setobj->set_inher.referenceId, presrs->referenceId);
setobj->nextResultSetPosition = *presrs->nextResultSetPosition;
if (zrs)
- ir_handleRecords (o, zrs, setobj);
+ ir_handleRecords (o, zrs, setobj, setobj->set_inher.elementSetNames);
else
{
setobj->recordFlag = 0;
if (scanrs->entries)
{
int i;
- Z_Entry *ze;
+ Z_Entry *ze;
scanobj->entries_flag = 1;
scanobj->which = scanrs->entries->which;
- switch (scanobj->which)
- {
- case Z_ListEntries_entries:
- scanobj->num_entries = scanrs->entries->u.entries->num_entries;
- scanobj->entries = ir_tcl_malloc (scanobj->num_entries *
- sizeof(*scanobj->entries));
+ switch (scanobj->which)
+ {
+ case Z_ListEntries_entries:
+ scanobj->num_entries = scanrs->entries->u.entries->num_entries;
+ scanobj->entries = ir_tcl_malloc (scanobj->num_entries *
+ sizeof(*scanobj->entries));
for (i=0; i<scanobj->num_entries; i++)
- {
- ze = scanrs->entries->u.entries->entries[i];
+ {
+ ze = scanrs->entries->u.entries->entries[i];
scanobj->entries[i].which = ze->which;
- switch (ze->which)
- {
- case Z_Entry_termInfo:
- if (ze->u.termInfo->term->which == Z_Term_general)
- {
+ switch (ze->which)
+ {
+ case Z_Entry_termInfo:
+ if (ze->u.termInfo->term->which == Z_Term_general)
+ {
int l = ze->u.termInfo->term->u.general->len;
scanobj->entries[i].u.term.buf = ir_tcl_malloc (1+l);
- memcpy (scanobj->entries[i].u.term.buf,
- ze->u.termInfo->term->u.general->buf,
+ memcpy (scanobj->entries[i].u.term.buf,
+ ze->u.termInfo->term->u.general->buf,
l);
scanobj->entries[i].u.term.buf[l] = '\0';
- }
- else
+ }
+ else
scanobj->entries[i].u.term.buf = NULL;
- if (ze->u.termInfo->globalOccurrences)
- scanobj->entries[i].u.term.globalOccurrences =
- *ze->u.termInfo->globalOccurrences;
- else
- scanobj->entries[i].u.term.globalOccurrences = 0;
+ if (ze->u.termInfo->globalOccurrences)
+ scanobj->entries[i].u.term.globalOccurrences =
+ *ze->u.termInfo->globalOccurrences;
+ else
+ scanobj->entries[i].u.term.globalOccurrences = 0;
break;
- case Z_Entry_surrogateDiagnostic:
+ case Z_Entry_surrogateDiagnostic:
ir_handleDiags (&scanobj->entries[i].u.diag.list,
&scanobj->entries[i].u.diag.num,
&ze->u.surrogateDiagnostic,
1);
- break;
- }
- }
+ break;
+ }
+ }
break;
- case Z_ListEntries_nonSurrogateDiagnostics:
+ case Z_ListEntries_nonSurrogateDiagnostics:
ir_handleDiags (&scanobj->nonSurrogateDiagnosticList,
&scanobj->nonSurrogateDiagnosticNum,
scanrs->entries->u.nonSurrogateDiagnostics->
scanrs->entries->u.nonSurrogateDiagnostics->
num_diagRecs);
break;
- }
+ }
}
else
scanobj->entries_flag = 0;
IrTcl_Request *rq;
char *object_name;
Tcl_CmdInfo cmd_info;
+ const char *apdu_call;
if (p->state == IR_TCL_R_Connecting)
{
}
p->state = IR_TCL_R_Idle;
if (p->callback)
- IrTcl_eval (p->interp, p->callback);
+ IrTcl_eval (p->interp, p->callback);
if (p->cs_link && p->request_queue && p->state == IR_TCL_R_Idle)
ir_tcl_send_q (p, p->request_queue, "x");
return;
}
do
{
- /* signal one more use of ir object - callbacks must not
- release the ir memory (p pointer) */
+ /* signal one more use of ir object - callbacks must not
+ release the ir memory (p pointer) */
p->state = IR_TCL_R_Reading;
- ++(p->ref_count);
+ ++(p->ref_count);
/* read incoming APDU */
if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) <= 0)
{
logf (LOG_DEBUG, "cs_get failed, code %d", r);
ir_select_remove (cs_fileno (p->cs_link), p);
+ do_disconnect (p, NULL, 2, NULL);
if (p->failback)
{
p->failInfo = IR_TCL_FAIL_READ;
IrTcl_eval (p->interp, p->failback);
}
- do_disconnect (p, NULL, 2, NULL);
-
- /* release ir object now if callback deleted it */
- ir_obj_delete (p);
+ /* release ir object now if callback deleted it */
+ ir_obj_delete (p);
return;
}
if (r == 1)
return ;
/* got complete APDU. Now decode */
+ p->apduLen = r;
+ p->apduOffset = -1;
odr_setbuf (p->odr_in, p->buf_in, r, 0);
logf (LOG_DEBUG, "cs_get ok, got %d", r);
if (!z_APDU (p->odr_in, &apdu, 0))
{
- logf (LOG_DEBUG, "%s", odr_errlist [odr_geterror (p->odr_in)]);
+ logf (LOG_DEBUG, "%s", odr_errmsg (odr_geterror (p->odr_in)));
+ do_disconnect (p, NULL, 2, NULL);
if (p->failback)
{
p->failInfo = IR_TCL_FAIL_IN_APDU;
+ p->apduOffset = odr_offset (p->odr_in);
IrTcl_eval (p->interp, p->failback);
}
- do_disconnect (p, NULL, 2, NULL);
-
- /* release ir object now if failback deleted it */
- ir_obj_delete (p);
+ /* release ir object now if failback deleted it */
+ ir_obj_delete (p);
return;
}
/* handle APDU and invoke callback */
exit (1);
}
object_name = rq->object_name;
+ logf (LOG_DEBUG, "getCommandInfo (%s)", object_name);
+ apdu_call = NULL;
if (Tcl_GetCommandInfo (p->interp, object_name, &cmd_info))
{
switch(apdu->which)
{
case Z_APDU_initResponse:
+ p->eventType = "init";
ir_initResponse (p, apdu->u.initResponse);
+ apdu_call = p->initResponse;
break;
case Z_APDU_searchResponse:
+ p->eventType = "search";
ir_searchResponse (p, apdu->u.searchResponse,
(IrTcl_SetObj *) cmd_info.clientData);
+ apdu_call = ((IrTcl_SetObj *)
+ cmd_info.clientData)->searchResponse;
break;
case Z_APDU_presentResponse:
+ p->eventType = "present";
ir_presentResponse (p, apdu->u.presentResponse,
(IrTcl_SetObj *) cmd_info.clientData);
+ apdu_call = ((IrTcl_SetObj *)
+ cmd_info.clientData)->presentResponse;
break;
case Z_APDU_scanResponse:
+ p->eventType = "scan";
ir_scanResponse (p, apdu->u.scanResponse,
(IrTcl_ScanObj *) cmd_info.clientData);
+ apdu_call = ((IrTcl_ScanObj *)
+ cmd_info.clientData)->scanResponse;
break;
default:
logf (LOG_WARN, "Received unknown APDU type (%d)",
apdu->which);
+ do_disconnect (p, NULL, 2, NULL);
if (p->failback)
{
p->failInfo = IR_TCL_FAIL_UNKNOWN_APDU;
IrTcl_eval (p->interp, p->failback);
}
- do_disconnect (p, NULL, 2, NULL);
return;
}
}
p->request_queue = rq->next;
p->state = IR_TCL_R_Idle;
-
- if (rq->callback)
+
+ if (apdu_call)
+ IrTcl_eval (p->interp, apdu_call);
+ else if (rq->callback)
IrTcl_eval (p->interp, rq->callback);
free (rq->buf_out);
free (rq->callback);
free (rq->object_name);
free (rq);
odr_reset (p->odr_in);
- if (p->ref_count == 1)
- {
- ir_obj_delete (p);
- return;
- }
- --(p->ref_count);
+ if (p->ref_count == 1)
+ {
+ ir_obj_delete (p);
+ return;
+ }
+ --(p->ref_count);
} while (p->cs_link && cs_more (p->cs_link));
if (p->cs_link && p->request_queue && p->state == IR_TCL_R_Idle)
ir_tcl_send_q (p, p->request_queue, "x");
}
ir_select_remove_write (cs_fileno (p->cs_link), p);
if (p->callback)
- IrTcl_eval (p->interp, p->callback);
+ IrTcl_eval (p->interp, p->callback);
return;
}
rq = p->request_queue;
+ if (!rq || !rq->buf_out)
+ return;
assert (rq);
if ((r=cs_put (p->cs_link, rq->buf_out, rq->len_out)) < 0)
{
/* ------------------------------------------------------- */
/*
- * ir_tcl_init: Registration of TCL commands.
+ * Irtcl_init: Registration of TCL commands.
*/
-int ir_tcl_init (Tcl_Interp *interp)
+int Irtcl_Init (Tcl_Interp *interp)
{
Tcl_CreateCommand (interp, "ir", ir_obj_mk, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand (interp, "ir-set", ir_set_obj_mk,
- (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+ (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand (interp, "ir-scan", ir_scan_obj_mk,
- (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
- irTcl_interp = interp;
+ (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
-