X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=ir-tcl.c;h=07844611cb346ede177dca949a31cff6db59cd7a;hb=3d7011401ecf4caad2d95d31d184aeebb43ed2c8;hp=efccf01a949c85bcb73f745a5061af81cfb72e38;hpb=de8b921d9c8c3757f8c166582c76315c53122d37;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index efccf01..0784461 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -1,11 +1,44 @@ /* * 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.100 1997-05-01 15:04:05 adam + * 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 @@ -497,8 +530,9 @@ int ir_tcl_eval (Tcl_Interp *interp, const char *command) 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 : ""); } Tcl_FreeResult (interp); xfree (tmp); @@ -635,13 +669,14 @@ int ir_tcl_named_bits (struct ir_named_entry *tab, Odr_bitmask *ob, 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); @@ -1170,24 +1205,12 @@ static int do_connect (void *obj, Tcl_Interp *interp, 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); @@ -1203,6 +1226,13 @@ static int do_connect (void *obj, Tcl_Interp *interp, 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); @@ -1242,6 +1272,9 @@ void ir_tcl_disconnect (IrTcl_Obj *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; @@ -1832,7 +1865,7 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { IrTcl_Methods tab[3]; - IrTcl_Obj *p = clientData; + IrTcl_Obj *p = (IrTcl_Obj *) clientData; int r; if (argc < 2) @@ -1857,7 +1890,7 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp, */ static void ir_obj_delete (ClientData clientData) { - IrTcl_Obj *obj = clientData; + IrTcl_Obj *obj = (IrTcl_Obj *) clientData; IrTcl_Methods tab[3]; --(obj->ref_count); @@ -1933,7 +1966,7 @@ int ir_obj_init (ClientData clientData, Tcl_Interp *interp, Tcl_AppendResult (interp, "Failed to initialize ", argv[1], NULL); return TCL_ERROR; } - *subData = obj; + *subData = (ClientData) obj; return TCL_OK; } @@ -2517,7 +2550,7 @@ static int do_getSutrs (void *o, Tcl_Interp *interp, int argc, char **argv) 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; @@ -2593,14 +2626,14 @@ static int do_getExplain (void *o, Tcl_Interp *interp, int argc, char **argv) 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) @@ -2734,7 +2767,7 @@ static int do_present (void *o, Tcl_Interp *interp, int argc, char **argv) typedef struct { int encoding; int syntax; - int size; + size_t size; } IrTcl_FileRecordHead; /* @@ -2919,7 +2952,7 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { IrTcl_Methods tabs[3]; - IrTcl_SetObj *p = clientData; + IrTcl_SetObj *p = (IrTcl_SetObj *) clientData; int r; if (argc < 2) @@ -2944,7 +2977,7 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, 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"); @@ -3044,7 +3077,7 @@ static int ir_set_obj_init (ClientData clientData, Tcl_Interp *interp, if (ir_tcl_method (interp, 0, NULL, tabs, NULL) == TCL_ERROR) return TCL_ERROR; - *subData = obj; + *subData = (ClientData) obj; return TCL_OK; } @@ -3316,8 +3349,7 @@ static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv) } 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) { @@ -3381,7 +3413,7 @@ static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp, 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; @@ -3464,7 +3496,19 @@ static int ir_log_proc (ClientData clientData, Tcl_Interp *interp, return TCL_OK; } mask = log_mask_str_x (argv[1], 0); - logf (mask, "%s", argv[1], mask, argv[2]); + 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; } @@ -3532,7 +3576,7 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num, Z_DiagRec **list, int num) { int i; - char *addinfo; + char *addinfo = NULL; *dst_num = num; *dst_list = ir_tcl_malloc (sizeof(**dst_list) * num); @@ -3543,7 +3587,19 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_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); @@ -3563,7 +3619,8 @@ static void ir_handleDBRecord (IrTcl_Obj *p, IrTcl_RecordList *rl, { 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; @@ -3580,8 +3637,11 @@ static void ir_handleDBRecord (IrTcl_Obj *p, IrTcl_RecordList *rl, 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: @@ -3652,10 +3712,16 @@ static void ir_handleZRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, &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]; @@ -3684,12 +3750,19 @@ static void ir_handleZRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, } 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); } } @@ -3704,11 +3777,13 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, 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; @@ -3721,10 +3796,14 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, 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; + } } @@ -3743,9 +3822,13 @@ static void ir_presentResponse (void *o, Z_PresentResponse *presrs, 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!"); } @@ -3778,67 +3861,61 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs, 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; inum_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; inum_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; } /* @@ -3846,7 +3923,7 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs, */ 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; @@ -3876,7 +3953,7 @@ static void ir_select_read (ClientData clientData) 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) @@ -3884,7 +3961,7 @@ static void ir_select_read (ClientData clientData) 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 @@ -3903,7 +3980,6 @@ static void ir_select_read (ClientData clientData) 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) { @@ -3911,7 +3987,7 @@ static void ir_select_read (ClientData clientData) 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 */ @@ -3931,7 +4007,7 @@ static void ir_select_read (ClientData clientData) 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 */ @@ -4000,10 +4076,10 @@ static void ir_select_read (ClientData clientData) 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"); @@ -4014,7 +4090,7 @@ static void ir_select_read (ClientData clientData) */ static int ir_select_write (ClientData clientData) { - IrTcl_Obj *p = clientData; + IrTcl_Obj *p = (IrTcl_Obj *) clientData; int r; IrTcl_Request *rq; @@ -4040,12 +4116,12 @@ static int ir_select_write (ClientData clientData) 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; @@ -4064,7 +4140,7 @@ static int ir_select_write (ClientData clientData) 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 */ { @@ -4133,6 +4209,9 @@ EXPORT (int,Irtcl_Init) (Tcl_Interp *interp) (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; }