/*
* IR toolkit for tcl/tk
- * (c) Index Data 1995-1996
+ * (c) Index Data 1995-1998
* See the file LICENSE for details.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: ir-tcl.c,v $
- * Revision 1.98 1997-04-13 18:57:20 adam
+ * Revision 1.111 1999-02-11 11:30:09 adam
+ * Updated for WIN32.
+ *
+ * Revision 1.110 1998/10/20 15:15:31 adam
+ * Changed scan response handler.
+ *
+ * Revision 1.109 1998/10/13 21:23:26 adam
+ * Fixed searchStatus method.
+ *
+ * Revision 1.108 1998/10/12 11:48:08 adam
+ * Removed printf call.
+ *
+ * Revision 1.107 1998/06/10 13:00:46 adam
+ * Added ir-version command.
+ *
+ * Revision 1.106 1998/05/20 12:25:35 adam
+ * Fixed bug that occurred in rare cases when encoding of incoming
+ * records failed.
+ *
+ * Revision 1.105 1998/04/02 14:31:08 adam
+ * This version works with compiled ASN.1 code.
+ *
+ * Revision 1.104 1998/02/27 14:26:07 adam
+ * Changed client so that it still works if target sets numberOfRecords
+ * in response to an illegal value.
+ *
+ * Revision 1.103 1997/11/19 11:22:10 adam
+ * Object identifiers can be accessed in GRS-1 records.
+ *
+ * Revision 1.102 1997/09/17 12:22:40 adam
+ * Changed to use YAZ version 1.4. The new comstack utility, cs_straddr,
+ * is used.
+ *
+ * Revision 1.101 1997/09/09 10:19:53 adam
+ * New MSV5.0 port with fewer warnings.
+ *
+ * Revision 1.100 1997/05/01 15:04:05 adam
+ * Added ir-log command.
+ *
+ * Revision 1.99 1997/04/30 07:24:47 adam
+ * Spell fix of an error message.
+ *
+ * Revision 1.98 1997/04/13 18:57:20 adam
* Better error reporting and aligned with Tcl/Tk style.
* Rework of notifier code with Tcl_File handles.
*
#include <stdlib.h>
#include <stdio.h>
-#ifdef WINDOWS
+#ifdef WIN32
#else
#include <unistd.h>
r = Tcl_Eval (interp, tmp);
if (r == TCL_ERROR)
{
- logf (LOG_WARN, "Tcl error in line %d: %s", interp->errorLine,
- interp->result);
+ const char *errorInfo = Tcl_GetVar (interp, "errorInfo", 0);
+ logf (LOG_WARN, "Tcl error in line %d: %s\n%s", interp->errorLine,
+ interp->result, errorInfo ? errorInfo : "<null>");
}
Tcl_FreeResult (interp);
xfree (tmp);
ODR_MASK_ZERO (ob);
for (no = 0; no < argc; no++)
{
+ int ok = 0;
for (ti = tab; ti->name; ti++)
- if (!strcmp (argv[no], ti->name))
+ if (!strcmp(argv[no], "@all") || !strcmp (argv[no], ti->name))
{
ODR_MASK_SET (ob, ti->pos);
- break;
+ ok = 1;
}
- if (!ti->name)
+ if (!ok)
{
Tcl_AppendResult (interp, "bad bit mask ", argv[no], NULL);
return ir_tcl_error_exec (interp, argc, argv);
if (!strcmp (p->comstackType, "tcpip"))
{
p->cs_link = cs_create (tcpip_type, CS_BLOCK, p->protocol_type);
- addr = tcpip_strtoaddr (argv[2]);
- if (!addr)
- {
- Tcl_AppendResult (interp, "tcpip_strtoaddr fail", NULL);
- return ir_tcl_error_exec (interp, argc, argv);
- }
logf (LOG_DEBUG, "tcp/ip connect %s", argv[2]);
}
else if (!strcmp (p->comstackType, "mosi"))
{
#if MOSI
p->cs_link = cs_create (mosi_type, CS_BLOCK, p->protocol_type);
- addr = mosi_strtoaddr (argv[2]);
- if (!addr)
- {
- Tcl_AppendResult (interp, "mosi_strtoaddr fail", NULL);
- return ir_tcl_error_exec (interp, argc, argv);
- }
logf (LOG_DEBUG, "mosi connect %s", argv[2]);
#else
Tcl_AppendResult (interp, "mosi not supported", NULL);
if (ir_tcl_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR)
return TCL_ERROR;
p->eventType = "connect";
+ addr = cs_straddr (p->cs_link, argv[2]);
+ if (!addr)
+ {
+ ir_tcl_disconnect (p);
+ Tcl_AppendResult (interp, "cs_straddr fail", NULL);
+ return ir_tcl_error_exec (interp, argc, argv);
+ }
if ((r=cs_connect (p->cs_link, addr)) < 0)
{
ir_tcl_disconnect (p);
- Tcl_AppendResult (interp, "conncet fail", NULL);
+ Tcl_AppendResult (interp, "connect fail", NULL);
return ir_tcl_error_exec (interp, argc, argv);
}
ir_select_add (cs_fileno (p->cs_link), p);
odr_reset (p->odr_in);
+#if TCL_MAJOR_VERSION == 8
+ cs_fileno(p->cs_link) = -1;
+#endif
cs_close (p->cs_link);
p->cs_link = NULL;
int argc, char **argv)
{
IrTcl_Methods tab[3];
- IrTcl_Obj *p = clientData;
+ IrTcl_Obj *p = (IrTcl_Obj *) clientData;
int r;
if (argc < 2)
*/
static void ir_obj_delete (ClientData clientData)
{
- IrTcl_Obj *obj = clientData;
+ IrTcl_Obj *obj = (IrTcl_Obj *) clientData;
IrTcl_Methods tab[3];
--(obj->ref_count);
Tcl_AppendResult (interp, "Failed to initialize ", argv[1], NULL);
return TCL_ERROR;
}
- *subData = obj;
+ *subData = (ClientData) obj;
return TCL_OK;
}
Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL);
return TCL_ERROR;
}
- if (rl->u.dbrec.type != VAL_SUTRS)
+ if (!rl->u.dbrec.buf || rl->u.dbrec.type != VAL_SUTRS)
return TCL_OK;
Tcl_AppendElement (interp, rl->u.dbrec.buf);
return TCL_OK;
Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL);
return TCL_ERROR;
}
- if (rl->u.dbrec.type != VAL_EXPLAIN)
+ if (!rl->u.dbrec.buf || rl->u.dbrec.type != VAL_EXPLAIN)
return TCL_OK;
if (!(etype = z_ext_getentbyref (VAL_EXPLAIN)))
return TCL_OK;
-
+ assert (rl->u.dbrec.buf);
odr_setbuf (p->odr_in, rl->u.dbrec.buf, rl->u.dbrec.size, 0);
- if (!(*etype->fun)(p->odr_in, &rr, 0))
+ if (!(*etype->fun)(p->odr_in, (char **) &rr, 0))
return TCL_OK;
if (etype->what != Z_External_explainRecord)
typedef struct {
int encoding;
int syntax;
- int size;
+ size_t size;
} IrTcl_FileRecordHead;
/*
int argc, char **argv)
{
IrTcl_Methods tabs[3];
- IrTcl_SetObj *p = clientData;
+ IrTcl_SetObj *p = (IrTcl_SetObj *) clientData;
int r;
if (argc < 2)
static void ir_set_obj_delete (ClientData clientData)
{
IrTcl_Methods tabs[3];
- IrTcl_SetObj *p = clientData;
+ IrTcl_SetObj *p = (IrTcl_SetObj *) clientData;
logf (LOG_DEBUG, "ir set delete");
if (ir_tcl_method (interp, 0, NULL, tabs, NULL) == TCL_ERROR)
return TCL_ERROR;
- *subData = obj;
+ *subData = (ClientData) obj;
return TCL_OK;
}
}
if (Tcl_GetInt (interp, argv[2], &i) == TCL_ERROR)
return TCL_ERROR;
- if (!p->entries_flag || p->which != Z_ListEntries_entries || !p->entries
- || i >= p->num_entries || i < 0)
+ if (!p->entries_flag || !p->entries || i >= p->num_entries || i < 0)
return TCL_OK;
switch (p->entries[i].which)
{
static void ir_scan_obj_delete (ClientData clientData)
{
IrTcl_Methods tabs[2];
- IrTcl_ScanObj *obj = clientData;
+ IrTcl_ScanObj *obj = (IrTcl_ScanObj *) clientData;
tabs[0].tab = ir_scan_method_tab;
tabs[0].obj = obj;
/* ------------------------------------------------------- */
/*
- * ir_log_proc: set yaz log level
+ * ir_log_init_proc: set yaz log level
*/
static int ir_log_init_proc (ClientData clientData, Tcl_Interp *interp,
int argc, char **argv)
return TCL_OK;
}
+/*
+ * ir_log_proc: log yaz message
+ */
+static int ir_log_proc (ClientData clientData, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ int mask;
+ if (argc != 3)
+ {
+ Tcl_AppendResult (interp, wrongArgs, *argv,
+ " level string\"", NULL);
+ return TCL_OK;
+ }
+ mask = log_mask_str_x (argv[1], 0);
+ logf (LOG_DEBUG, "%s", argv[2]);
+ return TCL_OK;
+}
+
+
+/*
+ * ir_version: log ir version
+ */
+static int ir_version (ClientData clientData, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ Tcl_AppendElement (interp, IR_TCL_VERSION);
+ Tcl_AppendElement (interp, YAZ_VERSION);
+ return TCL_OK;
+}
+
+
/* ------------------------------------------------------- */
static void ir_initResponse (void *obj, Z_InitResponse *initrs)
{
Z_DiagRec **list, int num)
{
int i;
- char *addinfo;
+ char *addinfo = NULL;
*dst_num = num;
*dst_list = ir_tcl_malloc (sizeof(**dst_list) * num);
{
case Z_DiagRec_defaultFormat:
(*dst_list)[i].condition = *list[i]->u.defaultFormat->condition;
+#ifdef ASN_COMPILED
+ switch (list[i]->u.defaultFormat->which)
+ {
+ case Z_DefaultDiagFormat_v2Addinfo:
+ addinfo = list[i]->u.defaultFormat->u.v2Addinfo;
+ break;
+ case Z_DefaultDiagFormat_v3Addinfo:
+ addinfo = list[i]->u.defaultFormat->u.v3Addinfo;
+ break;
+ }
+#else
addinfo = list[i]->u.defaultFormat->addinfo;
+#endif
if (addinfo &&
((*dst_list)[i].addinfo = ir_tcl_malloc (strlen(addinfo)+1)))
strcpy ((*dst_list)[i].addinfo, addinfo);
{
struct oident *ident;
Z_ext_typeent *etype;
-
+
+ logf (LOG_DEBUG, "handleDBRecord size=%d", oe->u.octet_aligned->len);
rl->u.dbrec.size = oe->u.octet_aligned->len;
rl->u.dbrec.buf = NULL;
odr_setbuf (p->odr_in, (char*) oe->u.octet_aligned->buf,
oe->u.octet_aligned->len, 0);
- if (!(*etype->fun)(p->odr_in, &rr, 0))
+ if (!(*etype->fun)(p->odr_in, (char **) &rr, 0))
+ {
+ rl->u.dbrec.type = VAL_NONE;
return;
+ }
switch (etype->what)
{
case Z_External_sutrs:
&setobj->nonSurrogateDiagnosticNum);
if (zrs->which == Z_Records_DBOSD)
{
- setobj->numberOfRecordsReturned =
- zrs->u.databaseOrSurDiagnostics->num_records;
- logf (LOG_DEBUG, "Got %d records", setobj->numberOfRecordsReturned);
- for (offset = 0; offset < setobj->numberOfRecordsReturned; offset++)
+ int num_rec = zrs->u.databaseOrSurDiagnostics->num_records;
+
+ if (num_rec != setobj->numberOfRecordsReturned)
+ {
+ logf (LOG_WARN, "numberOfRecordsReturned=%d but num records=%d",
+ setobj->numberOfRecordsReturned, num_rec);
+ setobj->numberOfRecordsReturned = num_rec;
+ }
+
+ for (offset = 0; offset < num_rec; offset++)
{
Z_NamePlusRecord *znpr = zrs->u.databaseOrSurDiagnostics->
records[offset];
}
else
{
+#ifdef ASN_COMPILED
+ Z_DiagRec dr, *dr_p = &dr;
+ dr.which = Z_DiagRec_defaultFormat;
+ dr.u.defaultFormat = zrs->u.nonSurrogateDiagnostic;
+#else
+ Z_DiagRec *dr_p = zrs->u.nonSurrogateDiagnostic;
+#endif
logf (LOG_DEBUG, "NonSurrogateDiagnostic");
+
setobj->numberOfRecordsReturned = 0;
ir_handleDiags (&setobj->nonSurrogateDiagnosticList,
&setobj->nonSurrogateDiagnosticNum,
- &zrs->u.nonSurrogateDiagnostic,
- 1);
+ &dr_p, 1);
}
}
logf (LOG_DEBUG, "Search response, no object!");
return;
}
- setobj->searchStatus = searchrs->searchStatus ? 1 : 0;
+ setobj->searchStatus = *searchrs->searchStatus;
get_referenceId (&setobj->set_inher.referenceId, searchrs->referenceId);
setobj->resultCount = *searchrs->resultCount;
if (searchrs->presentStatus)
setobj->presentStatus = *searchrs->presentStatus;
+ else
+ setobj->presentStatus = Z_RES_NONE;
if (searchrs->nextResultSetPosition)
setobj->nextResultSetPosition = *searchrs->nextResultSetPosition;
es = setobj->set_inher.smallSetElementSetNames;
else
es = setobj->set_inher.mediumSetElementSetNames;
+ setobj->numberOfRecordsReturned = *searchrs->numberOfRecordsReturned;
ir_handleZRecords (o, zrs, setobj, es);
}
else
+ {
+ setobj->numberOfRecordsReturned = 0;
setobj->recordFlag = 0;
+ }
}
get_referenceId (&setobj->set_inher.referenceId, presrs->referenceId);
setobj->nextResultSetPosition = *presrs->nextResultSetPosition;
if (zrs)
+ {
+ setobj->numberOfRecordsReturned = *presrs->numberOfRecordsReturned;
ir_handleZRecords (o, zrs, setobj, setobj->set_inher.elementSetNames);
+ }
else
{
+ setobj->numberOfRecordsReturned = 0;
setobj->recordFlag = 0;
logf (LOG_DEBUG, "No records!");
}
xfree (scanobj->entries);
scanobj->entries = NULL;
-
+ scanobj->num_entries = 0;
+ scanobj->entries_flag = 0;
+
ir_deleteDiags (&scanobj->nonSurrogateDiagnosticList,
&scanobj->nonSurrogateDiagnosticNum);
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;
+ if (scanrs->entries)
+ {
+ scanobj->num_entries = scanrs->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];
- scanobj->entries[i].which = ze->which;
- 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,
- l);
- scanobj->entries[i].u.term.buf[l] = '\0';
- }
- 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;
- break;
- case Z_Entry_surrogateDiagnostic:
- ir_handleDiags (&scanobj->entries[i].u.diag.list,
- &scanobj->entries[i].u.diag.num,
- &ze->u.surrogateDiagnostic,
- 1);
- break;
- }
- }
- break;
- case Z_ListEntries_nonSurrogateDiagnostics:
- ir_handleDiags (&scanobj->nonSurrogateDiagnosticList,
+ sizeof(*scanobj->entries));
+ ze = scanrs->entries->entries;
+ }
+ for (i=0; i<scanobj->num_entries; i++, ze++)
+ {
+ scanobj->entries[i].which = (*ze)->which;
+ 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,
+ l);
+ scanobj->entries[i].u.term.buf[l] = '\0';
+ }
+ 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;
+ break;
+ case Z_Entry_surrogateDiagnostic:
+ ir_handleDiags (&scanobj->entries[i].u.diag.list,
+ &scanobj->entries[i].u.diag.num,
+ &(*ze)->u.surrogateDiagnostic,
+ 1);
+ break;
+ }
+ }
+ if (scanrs->entries->nonsurrogateDiagnostics)
+ ir_handleDiags (&scanobj->nonSurrogateDiagnosticList,
&scanobj->nonSurrogateDiagnosticNum,
- scanrs->entries->u.nonSurrogateDiagnostics->
- diagRecs,
- scanrs->entries->u.nonSurrogateDiagnostics->
- num_diagRecs);
- break;
- }
+ scanrs->entries->nonsurrogateDiagnostics,
+ scanrs->entries->num_nonsurrogateDiagnostics);
}
- else
- scanobj->entries_flag = 0;
}
/*
*/
static void ir_select_read (ClientData clientData)
{
- IrTcl_Obj *p = clientData;
+ IrTcl_Obj *p = (IrTcl_Obj *) clientData;
Z_APDU *apdu;
int r;
IrTcl_Request *rq;
p->failInfo = IR_TCL_FAIL_CONNECT;
ir_tcl_eval (p->interp, p->failback);
}
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return;
}
if (p->callback)
if (p->ref_count == 2 && p->cs_link && p->request_queue
&& p->state == IR_TCL_R_Idle)
ir_tcl_send_q (p, p->request_queue, "x");
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return;
}
do
if (r <= 0)
{
logf (LOG_DEBUG, "cs_get failed, code %d", r);
- ir_select_remove (cs_fileno (p->cs_link), p);
ir_tcl_disconnect (p);
if (p->failback)
{
ir_tcl_eval (p->interp, p->failback);
}
/* release ir object now if callback deleted it */
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return;
}
/* got complete APDU. Now decode */
ir_tcl_eval (p->interp, p->failback);
}
/* release ir object now if failback deleted it */
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return;
}
/* handle APDU and invoke callback */
odr_reset (p->odr_in);
if (p->ref_count == 1)
{
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return;
}
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
} 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");
*/
static int ir_select_write (ClientData clientData)
{
- IrTcl_Obj *p = clientData;
+ IrTcl_Obj *p = (IrTcl_Obj *) clientData;
int r;
IrTcl_Request *rq;
p->failInfo = IR_TCL_FAIL_CONNECT;
ir_tcl_eval (p->interp, p->failback);
}
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return 2;
}
if (p->callback)
ir_tcl_eval (p->interp, p->callback);
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
return 2;
}
rq = p->request_queue;
p->failInfo = IR_TCL_FAIL_WRITE;
ir_tcl_eval (p->interp, p->failback);
}
- ir_obj_delete (p);
+ ir_obj_delete ((ClientData) p);
}
else if (r == 0) /* remove select bit */
{
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand (interp, "ir-log-init", ir_log_init_proc,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand (interp, "ir-log", ir_log_proc,
+ (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand (interp, "ir-version", ir_version, (ClientData) NULL,
+ (Tcl_CmdDeleteProc *) NULL);
+ nmem_init ();
return TCL_OK;
}