X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=ir-tcl.c;h=9c155e37439725bf51fd390dbd3079ccfaa297f7;hb=00c3f4aa3544517faf05260bf5f3e8d676229d83;hp=f397668e54b447f089a238849e26bc2a641a153b;hpb=fdc81f8a51fab1968b43efabab47d367e33ead32;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index f397668..9c155e3 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -5,7 +5,26 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.80 1996-02-23 17:31:39 adam + * Revision 1.84 1996-03-07 12:42:49 adam + * Better logging when callback is invoked. + * + * Revision 1.83 1996/03/05 09:21:09 adam + * Bug fix: memory used by GRS records wasn't freed. + * Rewrote some of the error handling code - the connection is always + * closed before failback is called. + * If failback is defined the send APDU methods (init, search, ...) will + * return OK but invoke failback (as is the case if the write operation + * fails). + * Bug fix: ref_count in assoc object could grow if fraction of PDU was + * read. + * + * Revision 1.82 1996/02/29 15:30:21 adam + * Export of IrTcl functionality to extensions. + * + * Revision 1.81 1996/02/26 18:38:32 adam + * Work on export of set methods. + * + * Revision 1.80 1996/02/23 17:31:39 adam * More functions made available to the wais tcl extension. * * Revision 1.79 1996/02/23 13:41:38 adam @@ -296,8 +315,6 @@ #include "ir-tclp.h" 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 void ir_select_notify (ClientData clientData, int r, int w, int e); @@ -321,6 +338,29 @@ void ir_select_remove_write (int fd, void *obj) ir_tcl_select_set (ir_select_notify, fd, obj, 1, 0, 0); } +static void delete_IR_record (IrTcl_RecordList *rl) +{ + switch (rl->which) + { + case Z_NamePlusRecord_databaseRecord: + switch (rl->u.dbrec.type) + { + case VAL_GRS1: + ir_tcl_grs_del (&rl->u.dbrec.u.grs1); + break; + default: + break; + } + free (rl->u.dbrec.buf); + break; + case Z_NamePlusRecord_surrogateDiagnostic: + ir_deleteDiags (&rl->u.surrogateDiagnostics.list, + &rl->u.surrogateDiagnostics.num); + break; + } + free (rl->elements); +} + static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, int no, int which, const char *elements) @@ -334,18 +374,7 @@ static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, 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; - break; - case Z_NamePlusRecord_surrogateDiagnostic: - ir_deleteDiags (&rl->u.surrogateDiagnostics.list, - &rl->u.surrogateDiagnostics.num); - break; - } + delete_IR_record (rl); break; } } @@ -369,6 +398,7 @@ int ir_tcl_eval (Tcl_Interp *interp, const char *command) char *tmp = ir_tcl_malloc (strlen(command)+1); int r; + logf (LOG_DEBUG, "Invoking %.23s ...", command); strcpy (tmp, command); r = Tcl_Eval (interp, tmp); if (r == TCL_ERROR) @@ -425,16 +455,7 @@ static void delete_IR_records (IrTcl_SetObj *setobj) for (rl = setobj->record_list; rl; rl = rl1) { - switch (rl->which) - { - case Z_NamePlusRecord_databaseRecord: - free (rl->u.dbrec.buf); - break; - case Z_NamePlusRecord_surrogateDiagnostic: - ir_deleteDiags (&rl->u.surrogateDiagnostics.list, - &rl->u.surrogateDiagnostics.num); - break; - } + delete_IR_record (rl); rl1 = rl->next; free (rl); } @@ -442,9 +463,9 @@ static void delete_IR_records (IrTcl_SetObj *setobj) } /* - * get_set_int: Set/get integer value + * ir_tcl_get_set_int: Set/get integer value */ -static int get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv) +int ir_tcl_get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv) { char buf[20]; @@ -461,7 +482,8 @@ static int get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv) /* * ir_tcl_method: Search for method in table and invoke method handler */ -int ir_tcl_method (Tcl_Interp *interp, int argc, char **argv, IrTcl_Methods *tab) +int ir_tcl_method (Tcl_Interp *interp, int argc, char **argv, + IrTcl_Methods *tab, int *ret) { IrTcl_Methods *tab_i = tab; IrTcl_Method *t; @@ -475,7 +497,10 @@ int ir_tcl_method (Tcl_Interp *interp, int argc, char **argv, IrTcl_Methods *tab } else if (!strcmp (t->name, argv[1])) - return (*t->method)(tab_i->obj, interp, argc, argv); + { + *ret = (*t->method)(tab_i->obj, interp, argc, argv); + return TCL_OK; + } if (argc <= 0) return TCL_OK; @@ -486,14 +511,15 @@ int ir_tcl_method (Tcl_Interp *interp, int argc, char **argv, IrTcl_Methods *tab for (t = tab_i->tab; t->name; t++) Tcl_AppendResult (interp, " ", t->name, NULL); #endif + *ret = TCL_ERROR; return TCL_ERROR; } /* - * ir_named_bits: get/set named bits + * ir_tcl_named_bits: get/set named bits */ -int ir_named_bits (struct ir_named_entry *tab, Odr_bitmask *ob, - Tcl_Interp *interp, int argc, char **argv) +int ir_tcl_named_bits (struct ir_named_entry *tab, Odr_bitmask *ob, + Tcl_Interp *interp, int argc, char **argv) { struct ir_named_entry *ti; if (argc > 0) @@ -686,7 +712,7 @@ static int do_options (void *obj, Tcl_Interp *interp, ODR_MASK_SET (&p->options, 14); return TCL_OK; } - return ir_named_bits (options_tab, &p->options, interp, argc-2, argv+2); + return ir_tcl_named_bits (options_tab, &p->options, interp, argc-2, argv+2); } /* @@ -792,7 +818,7 @@ static int do_preferredMessageSize (void *obj, Tcl_Interp *interp, p->preferredMessageSize = 30000; return TCL_OK; } - return get_set_int (&p->preferredMessageSize, interp, argc, argv); + return ir_tcl_get_set_int (&p->preferredMessageSize, interp, argc, argv); } /* @@ -808,7 +834,7 @@ static int do_maximumRecordSize (void *obj, Tcl_Interp *interp, p->maximumRecordSize = 30000; return TCL_OK; } - return get_set_int (&p->maximumRecordSize, interp, argc, argv); + return ir_tcl_get_set_int (&p->maximumRecordSize, interp, argc, argv); } /* @@ -821,7 +847,7 @@ static int do_initResult (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->initResult, interp, argc, argv); + return ir_tcl_get_set_int (&p->initResult, interp, argc, argv); } @@ -1063,7 +1089,7 @@ static int do_connect (void *obj, Tcl_Interp *interp, if ((r=cs_connect (p->cs_link, addr)) < 0) { interp->result = "connect fail"; - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); return TCL_ERROR; } logf(LOG_DEBUG, "cs_connect() returned %d fd=%d", r, @@ -1095,25 +1121,11 @@ static int do_connect (void *obj, Tcl_Interp *interp, return TCL_OK; } -/* - * do_disconnect: disconnect method on IR object +/* + * ir_tcl_disconnect: close connection */ -static int do_disconnect (void *obj, Tcl_Interp *interp, - int argc, char **argv) +void ir_tcl_disconnect (IrTcl_Obj *p) { - IrTcl_Obj *p = obj; - - if (argc == 0) - { - p->state = IR_TCL_R_Idle; - p->eventType = NULL; - p->hostname = NULL; - p->cs_link = NULL; -#if IRTCL_GENERIC_FILES - p->csFile = 0; -#endif - return TCL_OK; - } if (p->hostname) { logf(LOG_DEBUG, "Closing connection to %s", p->hostname); @@ -1150,6 +1162,28 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, ir_tcl_del_q (p); } assert (!p->cs_link); +} + +/* + * do_disconnect: disconnect method on IR object + */ +static int do_disconnect (void *obj, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_Obj *p = obj; + + if (argc == 0) + { + p->state = IR_TCL_R_Idle; + p->eventType = NULL; + p->hostname = NULL; + p->cs_link = NULL; +#if IRTCL_GENERIC_FILES + p->csFile = 0; +#endif + return TCL_OK; + } + ir_tcl_disconnect (p); return TCL_OK; } @@ -1396,13 +1430,14 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp, } p->num_databaseNames = argc - 2; p->databaseNames = - ir_tcl_malloc (sizeof(*p->databaseNames) * p->num_databaseNames); + ir_tcl_malloc (sizeof(*p->databaseNames) * (1+p->num_databaseNames)); for (i=0; inum_databaseNames; i++) { if (ir_tcl_strdup (interp, &p->databaseNames[i], argv[2+i]) == TCL_ERROR) return TCL_ERROR; } + p->databaseNames[i] = NULL; return TCL_OK; } @@ -1419,7 +1454,7 @@ static int do_replaceIndicator (void *obj, Tcl_Interp *interp, p->replaceIndicator = 1; return TCL_OK; } - return get_set_int (&p->replaceIndicator, interp, argc, argv); + return ir_tcl_get_set_int (&p->replaceIndicator, interp, argc, argv); } /* @@ -1476,7 +1511,7 @@ static int do_smallSetUpperBound (void *o, Tcl_Interp *interp, p->smallSetUpperBound = 0; return TCL_OK; } - return get_set_int (&p->smallSetUpperBound, interp, argc, argv); + return ir_tcl_get_set_int (&p->smallSetUpperBound, interp, argc, argv); } /* @@ -1492,7 +1527,7 @@ static int do_largeSetLowerBound (void *o, Tcl_Interp *interp, p->largeSetLowerBound = 2; return TCL_OK; } - return get_set_int (&p->largeSetLowerBound, interp, argc, argv); + return ir_tcl_get_set_int (&p->largeSetLowerBound, interp, argc, argv); } /* @@ -1508,7 +1543,7 @@ static int do_mediumSetPresentNumber (void *o, Tcl_Interp *interp, p->mediumSetPresentNumber = 0; return TCL_OK; } - return get_set_int (&p->mediumSetPresentNumber, interp, argc, argv); + return ir_tcl_get_set_int (&p->mediumSetPresentNumber, interp, argc, argv); } /* @@ -1704,6 +1739,7 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp, { IrTcl_Methods tab[3]; IrTcl_Obj *p = clientData; + int r; if (argc < 2) return TCL_ERROR; @@ -1714,7 +1750,8 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp, tab[1].obj = &p->set_inher; tab[2].tab = NULL; - return ir_tcl_method (interp, argc, argv, tab); + ir_tcl_method (interp, argc, argv, tab, &r); + return r; } /* @@ -1737,7 +1774,7 @@ static void ir_obj_delete (ClientData clientData) tab[1].obj = &obj->set_inher; tab[2].tab = NULL; - ir_tcl_method (NULL, -1, NULL, tab); + ir_tcl_method (NULL, -1, NULL, tab, NULL); ir_tcl_del_q (obj); odr_destroy (obj->odr_in); @@ -1750,7 +1787,8 @@ static void ir_obj_delete (ClientData clientData) * ir_obj_init: IR Object initialization */ int ir_obj_init (ClientData clientData, Tcl_Interp *interp, - int argc, char **argv, ClientData *subData) + int argc, char **argv, ClientData *subData, + ClientData parentData) { IrTcl_Methods tab[3]; IrTcl_Obj *obj; @@ -1791,7 +1829,7 @@ int ir_obj_init (ClientData clientData, Tcl_Interp *interp, tab[1].obj = &obj->set_inher; tab[2].tab = NULL; - if (ir_tcl_method (interp, 0, NULL, tab) == TCL_ERROR) + if (ir_tcl_method (interp, 0, NULL, tab, NULL) == TCL_ERROR) { Tcl_AppendResult (interp, "Failed to initialize ", argv[1], NULL); return TCL_ERROR; @@ -1808,7 +1846,7 @@ static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { ClientData subData; - int r = ir_obj_init (clientData, interp, argc, argv, &subData); + int r = ir_obj_init (clientData, interp, argc, argv, &subData, 0); if (r == TCL_ERROR) return TCL_ERROR; @@ -2049,7 +2087,7 @@ static int do_resultCount (void *o, Tcl_Interp *interp, obj->resultCount = 0; return TCL_OK; } - return get_set_int (&obj->resultCount, interp, argc, argv); + return ir_tcl_get_set_int (&obj->resultCount, interp, argc, argv); } /* @@ -2062,7 +2100,7 @@ static int do_searchStatus (void *o, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&obj->searchStatus, interp, argc, argv); + return ir_tcl_get_set_int (&obj->searchStatus, interp, argc, argv); } /* @@ -2075,7 +2113,7 @@ static int do_presentStatus (void *o, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&obj->presentStatus, interp, argc, argv); + return ir_tcl_get_set_int (&obj->presentStatus, interp, argc, argv); } /* @@ -2092,7 +2130,8 @@ static int do_nextResultSetPosition (void *o, Tcl_Interp *interp, obj->nextResultSetPosition = 0; return TCL_OK; } - return get_set_int (&obj->nextResultSetPosition, interp, argc, argv); + return ir_tcl_get_set_int (&obj->nextResultSetPosition, interp, + argc, argv); } /* @@ -2131,7 +2170,8 @@ static int do_numberOfRecordsReturned (void *o, Tcl_Interp *interp, obj->numberOfRecordsReturned = 0; return TCL_OK; } - return get_set_int (&obj->numberOfRecordsReturned, interp, argc, argv); + return ir_tcl_get_set_int (&obj->numberOfRecordsReturned, interp, + argc, argv); } /* @@ -2600,6 +2640,7 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, { IrTcl_Methods tabs[3]; IrTcl_SetObj *p = clientData; + int r; if (argc < 2) { @@ -2612,7 +2653,8 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, tabs[1].obj = &p->set_inher; tabs[2].tab = NULL; - return ir_tcl_method (interp, argc, argv, tabs); + ir_tcl_method (interp, argc, argv, tabs, &r); + return r; } /* @@ -2631,16 +2673,17 @@ static void ir_set_obj_delete (ClientData clientData) tabs[1].obj = &p->set_inher; tabs[2].tab = NULL; - ir_tcl_method (NULL, -1, NULL, tabs); + ir_tcl_method (NULL, -1, NULL, tabs, NULL); free (p); } /* - * ir_set_obj_mk: IR Set Object creation + * ir_set_obj_init: IR Set Object initialization */ -static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, - int argc, char **argv) +static int ir_set_obj_init (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv, ClientData *subData, + ClientData parentData) { IrTcl_Methods tabs[3]; IrTcl_SetObj *obj; @@ -2652,33 +2695,30 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, } obj = ir_tcl_malloc (sizeof(*obj)); logf (LOG_DEBUG, "ir set create"); - if (argc == 3) + if (parentData) { - Tcl_CmdInfo parent_info; int i; IrTcl_SetCObj *dst; IrTcl_SetCObj *src; - if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info)) - { - interp->result = "No parent"; - return TCL_ERROR; - } - obj->parent = (IrTcl_Obj *) parent_info.clientData; + obj->parent = (IrTcl_Obj *) parentData; dst = &obj->set_inher; src = &obj->parent->set_inher; if ((dst->num_databaseNames = src->num_databaseNames)) + { dst->databaseNames = ir_tcl_malloc (sizeof (*dst->databaseNames) - * dst->num_databaseNames); + * (1+dst->num_databaseNames)); + for (i = 0; i < dst->num_databaseNames; i++) + if (ir_tcl_strdup (interp, &dst->databaseNames[i], + src->databaseNames[i]) == TCL_ERROR) + return TCL_ERROR; + dst->databaseNames[i] = NULL; + } 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; @@ -2719,14 +2759,48 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, tabs[0].obj = obj; tabs[1].tab = NULL; - if (ir_tcl_method (interp, 0, NULL, tabs) == TCL_ERROR) + if (ir_tcl_method (interp, 0, NULL, tabs, NULL) == TCL_ERROR) return TCL_ERROR; + *subData = obj; + return TCL_OK; +} + +/* + * ir_set_obj_mk: IR Set Object creation + */ +static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv) +{ + ClientData subData; + ClientData parentData = 0; + int r; + + if (argc == 3) + { + Tcl_CmdInfo parent_info; + if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info)) + { + interp->result = "No parent"; + return TCL_ERROR; + } + parentData = parent_info.clientData; + } + r = ir_set_obj_init (clientData, interp, argc, argv, &subData, parentData); + if (r == TCL_ERROR) + return TCL_ERROR; Tcl_CreateCommand (interp, argv[1], ir_set_obj_method, - (ClientData) obj, ir_set_obj_delete); + subData, ir_set_obj_delete); return TCL_OK; } +IrTcl_Class ir_set_obj_class = { + "ir-set", + ir_set_obj_init, + ir_set_obj_method, + ir_set_obj_delete +}; + /* ------------------------------------------------------- */ /* @@ -2846,7 +2920,7 @@ static int do_stepSize (void *obj, Tcl_Interp *interp, p->stepSize = 0; return TCL_OK; } - return get_set_int (&p->stepSize, interp, argc, argv); + return ir_tcl_get_set_int (&p->stepSize, interp, argc, argv); } /* @@ -2862,7 +2936,7 @@ static int do_numberOfTermsRequested (void *obj, Tcl_Interp *interp, p->numberOfTermsRequested = 20; return TCL_OK; } - return get_set_int (&p->numberOfTermsRequested, interp, argc, argv); + return ir_tcl_get_set_int (&p->numberOfTermsRequested, interp, argc, argv); } @@ -2879,7 +2953,8 @@ static int do_preferredPositionInResponse (void *obj, Tcl_Interp *interp, p->preferredPositionInResponse = 1; return TCL_OK; } - return get_set_int (&p->preferredPositionInResponse, interp, argc, argv); + return ir_tcl_get_set_int (&p->preferredPositionInResponse, interp, + argc, argv); } /* @@ -2892,7 +2967,7 @@ static int do_scanStatus (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->scanStatus, interp, argc, argv); + return ir_tcl_get_set_int (&p->scanStatus, interp, argc, argv); } /* @@ -2905,7 +2980,8 @@ static int do_numberOfEntriesReturned (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->numberOfEntriesReturned, interp, argc, argv); + return ir_tcl_get_set_int (&p->numberOfEntriesReturned, interp, + argc, argv); } /* @@ -2918,7 +2994,7 @@ static int do_positionOfTerm (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->positionOfTerm, interp, argc, argv); + return ir_tcl_get_set_int (&p->positionOfTerm, interp, argc, argv); } /* @@ -2998,6 +3074,7 @@ static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { IrTcl_Methods tabs[2]; + int r; if (argc < 2) { @@ -3008,7 +3085,8 @@ static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp, tabs[0].obj = clientData; tabs[1].tab = NULL; - return ir_tcl_method (interp, argc, argv, tabs); + ir_tcl_method (interp, argc, argv, tabs, &r); + return r; } /* @@ -3023,7 +3101,7 @@ static void ir_scan_obj_delete (ClientData clientData) tabs[0].obj = obj; tabs[1].tab = NULL; - ir_tcl_method (NULL, -1, NULL, tabs); + ir_tcl_method (NULL, -1, NULL, tabs, NULL); free (obj); } @@ -3054,7 +3132,7 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp, tabs[0].obj = obj; tabs[1].tab = NULL; - if (ir_tcl_method (interp, 0, NULL, tabs) == TCL_ERROR) + if (ir_tcl_method (interp, 0, NULL, tabs, NULL) == TCL_ERROR) return TCL_ERROR; Tcl_CreateCommand (interp, argv[1], ir_scan_obj_method, (ClientData) obj, ir_scan_obj_delete); @@ -3217,7 +3295,7 @@ static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, 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); + ir_tcl_grs_mk (oe->u.grs1, &rl->u.dbrec.u.grs1); rl->u.dbrec.buf = NULL; } else @@ -3410,7 +3488,7 @@ static void ir_select_read (ClientData clientData) logf(LOG_DEBUG, "Read handler fd=%d", cs_fileno(p->cs_link)); if (p->state == IR_TCL_R_Connecting) { - logf(LOG_DEBUG, "Connect handler"); + logf(LOG_DEBUG, "read: connect"); r = cs_rcvconnect (p->cs_link); if (r == 1) { @@ -3418,6 +3496,7 @@ static void ir_select_read (ClientData clientData) return; } p->state = IR_TCL_R_Idle; + p->ref_count = 2; #if IRTCL_GENERIC_FILES ir_select_remove_write (p->csFile, p); #else @@ -3426,30 +3505,37 @@ static void ir_select_read (ClientData clientData) if (r < 0) { logf (LOG_DEBUG, "cs_rcvconnect error"); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_CONNECT; ir_tcl_eval (p->interp, p->failback); } - do_disconnect (p, NULL, 2, NULL); + ir_obj_delete (p); return; } - p->state = IR_TCL_R_Idle; if (p->callback) ir_tcl_eval (p->interp, p->callback); - if (p->cs_link && p->request_queue && p->state == IR_TCL_R_Idle) + 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); return; } do { - /* 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); /* read incoming APDU */ - if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) <= 0) + if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) == 1) + { + logf(LOG_DEBUG, "PDU Fraction read"); + return ; + } + /* signal one more use of ir object - callbacks must not + release the ir memory (p pointer) */ + p->ref_count = 2; + if (r <= 0) { logf (LOG_DEBUG, "cs_get failed, code %d", r); #if IRTCL_GENERIC_FILES @@ -3457,7 +3543,7 @@ static void ir_select_read (ClientData clientData) #else ir_select_remove (cs_fileno (p->cs_link), p); #endif - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_READ; @@ -3467,11 +3553,6 @@ static void ir_select_read (ClientData clientData) ir_obj_delete (p); return; } - if (r == 1) - { - logf(LOG_DEBUG, "PDU Fraction read"); - return ; - } /* got complete APDU. Now decode */ p->apduLen = r; p->apduOffset = -1; @@ -3481,7 +3562,7 @@ static void ir_select_read (ClientData clientData) { logf (LOG_DEBUG, "cs_get failed: %s", odr_errmsg (odr_geterror (p->odr_in))); - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_IN_APDU; @@ -3536,7 +3617,7 @@ static void ir_select_read (ClientData clientData) default: logf (LOG_WARN, "Received unknown APDU type (%d)", apdu->which); - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_UNKNOWN_APDU; @@ -3562,7 +3643,7 @@ static void ir_select_read (ClientData clientData) ir_obj_delete (p); return; } - --(p->ref_count); + ir_obj_delete (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"); @@ -3580,34 +3661,35 @@ static void ir_select_write (ClientData clientData) logf (LOG_DEBUG, "Write handler fd=%d", cs_fileno(p->cs_link)); if (p->state == IR_TCL_R_Connecting) { - logf(LOG_DEBUG, "Connect handler"); + logf(LOG_DEBUG, "write: connect"); r = cs_rcvconnect (p->cs_link); if (r == 1) + { + logf (LOG_DEBUG, "cs_rcvconnect returned 1"); return; + } p->state = IR_TCL_R_Idle; - if (r < 0) - { - logf (LOG_DEBUG, "cs_rcvconnect error"); + p->ref_count = 2; #if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); + ir_select_remove_write (p->csFile, p); #else - ir_select_remove_write (cs_fileno (p->cs_link), p); + ir_select_remove_write (cs_fileno (p->cs_link), p); #endif + if (r < 0) + { + logf (LOG_DEBUG, "cs_rcvconnect error"); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_CONNECT; ir_tcl_eval (p->interp, p->failback); } - do_disconnect (p, NULL, 2, NULL); + ir_obj_delete (p); return; } -#if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); -#else - ir_select_remove_write (cs_fileno (p->cs_link), p); -#endif if (p->callback) ir_tcl_eval (p->interp, p->callback); + ir_obj_delete (p); return; } rq = p->request_queue; @@ -3617,18 +3699,20 @@ static void ir_select_write (ClientData clientData) if ((r=cs_put (p->cs_link, rq->buf_out, rq->len_out)) < 0) { logf (LOG_DEBUG, "cs_put write fail"); + p->ref_count = 2; + free (rq->buf_out); + rq->buf_out = NULL; + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_WRITE; ir_tcl_eval (p->interp, p->failback); } - free (rq->buf_out); - rq->buf_out = NULL; - do_disconnect (p, NULL, 2, NULL); + ir_obj_delete (p); } else if (r == 0) /* remove select bit */ { - logf(LOG_DEBUG, "Write completed"); + logf (LOG_DEBUG, "Write completed"); p->state = IR_TCL_R_Waiting; #if IRTCL_GENERIC_FILES ir_select_remove_write (p->csFile, p);