X-Git-Url: http://lists.indexdata.dk/cgi-bin?a=blobdiff_plain;f=ir-tcl.c;h=30a3b5b706fb2abb7cd419e15990a00d24914c85;hb=1b15670e090677122c83f162a446efa5495e6235;hp=468bf3aba372ca2737d4c15e706facf8027b9733;hpb=9d133cf6537db3aa9b09fd5d215e72dfa92b9cf4;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index 468bf3a..30a3b5b 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -5,7 +5,16 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.44 1995-06-19 17:01:20 adam + * Revision 1.46 1995-06-22 13:15:06 adam + * Feature: SUTRS. Setting getSutrs implemented. + * Work on display formats. + * Preferred record syntax can be set by the user. + * + * Revision 1.45 1995/06/20 08:07:30 adam + * New setting: failInfo. + * Working on better cancel mechanism. + * + * Revision 1.44 1995/06/19 17:01:20 adam * Minor changes. * * Revision 1.43 1995/06/19 13:06:08 adam @@ -646,6 +655,48 @@ static int do_options (void *obj, Tcl_Interp *interp, } /* + * do_failInfo: Get fail information + */ +static int do_failInfo (void *obj, Tcl_Interp *interp, int argc, char **argv) +{ + char buf[16], *cp; + IrTcl_Obj *p = obj; + + if (argc <= 0) + { + p->failInfo = 0; + return TCL_OK; + } + sprintf (buf, "%d", p->failInfo); + switch (p->failInfo) + { + case 0: + cp = "ok"; + break; + case IR_TCL_FAIL_CONNECT: + cp = "connect failed"; + break; + case IR_TCL_FAIL_READ: + cp = "connection closed"; + break; + case IR_TCL_FAIL_WRITE: + cp = "connection closed"; + break; + case IR_TCL_FAIL_IN_APDU: + cp = "failed to decode incoming APDU"; + break; + case IR_TCL_FAIL_UNKNOWN_APDU: + cp = "unknown APDU"; + break; + default: + cp = ""; + } + Tcl_AppendElement (interp, buf); + Tcl_AppendElement (interp, cp); + return TCL_OK; +} + +/* * do_preferredMessageSize: Set/get preferred message size */ static int do_preferredMessageSize (void *obj, Tcl_Interp *interp, @@ -755,7 +806,7 @@ static int do_targetImplementationName (void *obj, Tcl_Interp *interp, int argc, char **argv) { IrTcl_Obj *p = obj; - + if (argc == 0) { p->targetImplementationName = NULL; @@ -1309,6 +1360,7 @@ static IrTcl_Method ir_method_tab[] = { { 1, "comstack", do_comstack }, { 1, "protocol", do_protocol }, { 0, "failback", do_failback }, +{ 0, "failInfo", do_failInfo }, { 1, "connect", do_connect }, { 0, "protocolVersion", do_protocolVersion }, @@ -1510,6 +1562,7 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) ident.proto = p->protocol_type; ident.class = 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, oid_getoidbyent (&ident)); } @@ -1856,6 +1909,41 @@ static int do_getMarc (void *o, Tcl_Interp *interp, int argc, char **argv) return ir_tcl_get_marc (interp, rl->u.dbrec.buf, argc, argv); } +/* + * do_getSutrs: Get SUTRS Record + */ +static int do_getSutrs (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_SUTRS) + return TCL_OK; + Tcl_AppendElement (interp, rl->u.dbrec.buf); + return TCL_OK; +} + /* * do_responseStatus: Return response status (present or search) @@ -1946,7 +2034,19 @@ static int do_present (void *o, Tcl_Interp *interp, req->resultSetStartPoint = &start; req->numberOfRecordsRequested = &number; - req->preferredRecordSyntax = 0; + if (obj->set_inher.preferredRecordSyntax) + { + struct oident ident; + + ident.proto = p->protocol_type; + ident.class = 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, + oid_getoidbyent (&ident)); + } + else + req->preferredRecordSyntax = 0; if (!z_APDU (p->odr_out, &apdu, 0)) { @@ -2025,6 +2125,7 @@ static IrTcl_Method ir_set_method_tab[] = { { 0, "present", do_present }, { 0, "type", do_type }, { 0, "getMarc", do_getMarc }, + { 0, "getSutrs", do_getSutrs }, { 0, "recordType", do_recordType }, { 0, "diag", do_diag }, { 0, "responseStatus", do_responseStatus }, @@ -2607,22 +2708,44 @@ static void ir_handleRecords (void *o, Z_Records *zrs) { Z_DatabaseRecord *zr; Odr_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; + rl->u.dbrec.type = VAL_USMARC; + ident = oid_getentbyoid (oe->direct_reference); + rl->u.dbrec.type = ident->value; + if (oe->which == ODR_EXTERNAL_octet && rl->u.dbrec.size > 0) { - const char *buf = (char*) zr->u.octet_aligned->buf; + char *buf = (char*) zr->u.octet_aligned->buf; if ((rl->u.dbrec.buf = malloc (rl->u.dbrec.size))) memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size); - if (oe->direct_reference) + } + else if (rl->u.dbrec.type == VAL_SUTRS && + oe->which == ODR_EXTERNAL_single) + { + 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)) + { + logf (LOG_WARN, "Cannot decode SUTRS"); + rl->u.dbrec.buf = NULL; + } + else { - struct oident *ident = - oid_getentbyoid (oe->direct_reference); - rl->u.dbrec.type = ident->value; + if ((rl->u.dbrec.buf = 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; } } else @@ -2817,7 +2940,10 @@ void ir_select_read (ClientData clientData) { logf (LOG_DEBUG, "cs_rcvconnect error"); if (p->failback) + { + p->failInfo = IR_TCL_FAIL_CONNECT; IrTcl_eval (p->interp, p->failback); + } do_disconnect (p, NULL, 2, NULL); return; } @@ -2835,7 +2961,10 @@ void ir_select_read (ClientData clientData) logf (LOG_DEBUG, "cs_get failed, code %d", r); ir_select_remove (cs_fileno (p->cs_link), p); if (p->failback) + { + p->failInfo = IR_TCL_FAIL_READ; IrTcl_eval (p->interp, p->failback); + } do_disconnect (p, NULL, 2, NULL); /* relase ir object now if callback deleted it */ @@ -2850,7 +2979,10 @@ void ir_select_read (ClientData clientData) { logf (LOG_DEBUG, "%s", odr_errlist [odr_geterror (p->odr_in)]); 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 */ @@ -2874,7 +3006,10 @@ void ir_select_read (ClientData clientData) default: logf (LOG_WARN, "Received unknown APDU type (%d)", apdu->which); if (p->failback) + { + p->failInfo = IR_TCL_FAIL_UNKNOWN_APDU; IrTcl_eval (p->interp, p->failback); + } do_disconnect (p, NULL, 2, NULL); } odr_reset (p->odr_in); @@ -2909,7 +3044,10 @@ void ir_select_write (ClientData clientData) logf (LOG_DEBUG, "cs_rcvconnect error"); ir_select_remove_write (cs_fileno (p->cs_link), p); if (p->failback) + { + p->failInfo = IR_TCL_FAIL_CONNECT; IrTcl_eval (p->interp, p->failback); + } do_disconnect (p, NULL, 2, NULL); return; } @@ -2922,7 +3060,10 @@ void ir_select_write (ClientData clientData) { logf (LOG_DEBUG, "select write fail"); if (p->failback) + { + p->failInfo = IR_TCL_FAIL_WRITE; IrTcl_eval (p->interp, p->failback); + } do_disconnect (p, NULL, 2, NULL); } else if (r == 0) /* remove select bit */