Bug fix: when target connection closed, the connection was not
[ir-tcl-moved-to-github.git] / queue.c
1
2 /*
3  * IR toolkit for tcl/tk
4  * (c) Index Data 1995
5  * See the file LICENSE for details.
6  * Sebastian Hammer, Adam Dickmeiss
7  *
8  * $Log: queue.c,v $
9  * Revision 1.4  1995-10-17 12:18:59  adam
10  * Bug fix: when target connection closed, the connection was not
11  * properly reestablished.
12  *
13  * Revision 1.3  1995/08/04  11:32:40  adam
14  * More work on output queue. Memory related routines moved
15  * to mem.c
16  *
17  * Revision 1.2  1995/08/03  13:23:01  adam
18  * Request queue.
19  *
20  * Revision 1.1  1995/07/28  10:28:39  adam
21  * First work on request queue.
22  *
23  */
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <ctype.h>
28 #include <assert.h>
29
30 #include "ir-tclp.h"
31
32 int ir_tcl_send_APDU (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu,
33                       const char *msg, const char *object_name)
34 {
35     IrTcl_Request **rp;
36
37     if (!z_APDU (p->odr_out, &apdu, 0))
38     {
39         Tcl_AppendResult (interp, odr_errlist [odr_geterror (p->odr_out)],
40                           NULL);
41         odr_reset (p->odr_out);
42         return TCL_ERROR;
43     }
44     rp = &p->request_queue;
45     while (*rp)
46         rp = &(*rp)->next;
47     *rp = ir_tcl_malloc (sizeof(**rp));
48     (*rp)->next = NULL;
49     
50     if (ir_tcl_strdup (interp, &(*rp)->object_name, object_name) == TCL_ERROR)
51         return TCL_ERROR;
52     if (ir_tcl_strdup (interp, &(*rp)->callback, p->callback) == TCL_ERROR)
53         return TCL_ERROR;
54     
55     (*rp)->buf_out = odr_getbuf (p->odr_out, &(*rp)->len_out, NULL);
56     odr_setbuf (p->odr_out, NULL, 0, 1);
57     odr_reset (p->odr_out);
58     if (p->state == IR_TCL_R_Idle)
59     {
60         logf (LOG_DEBUG, "send_apdu. Sending %s", msg);
61         if (ir_tcl_send_q (p, p->request_queue, msg) == TCL_ERROR)
62         {
63             sprintf (interp->result, "cs_put failed in %s", msg);
64             return TCL_ERROR;
65         } 
66     }
67     else
68         logf (LOG_DEBUG, "send_apdu. Not idle (%s)", msg);
69     return TCL_OK;
70 }
71
72 int ir_tcl_send_q (IrTcl_Obj *p, IrTcl_Request *rp, const char *msg)
73 {
74     int r;
75
76     assert (rp);
77     r = cs_put (p->cs_link, rp->buf_out, rp->len_out);
78     if (r < 0)
79         return TCL_ERROR;
80     else if (r == 1)
81     {
82         ir_select_add_write (cs_fileno (p->cs_link), p);
83         logf (LOG_DEBUG, "Send part of %s", msg);
84         p->state = IR_TCL_R_Writing;
85     }
86     else
87     {
88         logf (LOG_DEBUG, "Send %s (%d bytes)", msg, rp->len_out);
89         p->state = IR_TCL_R_Waiting;
90         free (rp->buf_out);
91         rp->buf_out = NULL;
92     }
93     return TCL_OK;
94 }
95
96 void ir_tcl_del_q (IrTcl_Obj *p)
97 {
98     IrTcl_Request *rp, *rp1;
99
100     for (rp = p->request_queue; rp; rp = rp1)
101     {
102         free (rp->object_name);
103         free (rp->callback);
104         free (rp->buf_out);
105         rp1 = rp->next;
106         free (rp);
107     }
108     p->request_queue = NULL;
109 }
110
111
112