* Sebastian Hammer, Adam Dickmeiss
*
* $Log: ir-tcl.c,v $
- * Revision 1.52 1995-08-04 11:32:38 adam
+ * 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
*
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);
{ VAL_AUSMARC, "AUSMARC" },
{ VAL_IBERMARC, "IBERMARC" },
{ VAL_SUTRS, "SUTRS" },
+{ VAL_GRS1, "GRS1" },
{ 0, NULL }
};
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);
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";
IrTcl_eval (p->interp, p->callback);
}
}
+ else
+ Tcl_AppendResult (interp, p->hostname, NULL);
return TCL_OK;
}
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;
}
else
p->callback = NULL;
- p->interp = interp;
}
return TCL_OK;
}
}
else
p->failback = NULL;
- p->interp = interp;
}
return TCL_OK;
}
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);
}
+/*
+ * 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, "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->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.value = VAL_BIB1;
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;
}
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.elementSetNames;
+ 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.elementSetNames;
+ req->mediumSetElementSetNames = esn;
+ }
+ else
+ req->mediumSetElementSetNames = NULL;
+
+ req->query = &query;
+
if (!strcmp (obj->set_inher.queryType, "rpn"))
{
Z_RPNQuery *RPNquery;
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:
/*
+ * 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,
* 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;
}
else
req->preferredRecordSyntax = 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[0]);
}
{ 0, "type", do_type },
{ 0, "getMarc", do_getMarc },
{ 0, "getSutrs", do_getSutrs },
+ { 0, "getGrs", do_getGrs },
{ 0, "recordType", do_recordType },
{ 0, "diag", do_diag },
{ 0, "responseStatus", do_responseStatus },
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->cs_link)
{
- interp->result = "not connected";
+ interp->result = "scan: not connected";
return TCL_ERROR;
}
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;
+ 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;
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;
{
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);
return;
if (!z_APDU (p->odr_in, &apdu, 0))
{
logf (LOG_DEBUG, "%s", odr_errlist [odr_geterror (p->odr_in)]);
+ do_disconnect (p, NULL, 2, NULL);
if (p->failback)
{
p->failInfo = IR_TCL_FAIL_IN_APDU;
IrTcl_eval (p->interp, p->failback);
}
- do_disconnect (p, NULL, 2, NULL);
-
/* release ir object now if failback deleted it */
ir_obj_delete (p);
return;
exit (1);
}
object_name = rq->object_name;
+ logf (LOG_DEBUG, "getCommandInfo (%s)", object_name);
if (Tcl_GetCommandInfo (p->interp, object_name, &cmd_info))
{
switch(apdu->which)
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;
}
}
/* ------------------------------------------------------- */
/*
- * 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);
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand (interp, "ir-scan", ir_scan_obj_mk,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
- irTcl_interp = interp;
return TCL_OK;
}
-