The xmalloc/xfree functions from YAZ are used to manage memory.
[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.11  1996-07-03 13:31:14  adam
10  * The xmalloc/xfree functions from YAZ are used to manage memory.
11  *
12  * Revision 1.10  1996/06/03  09:04:24  adam
13  * Changed a few logf calls.
14  *
15  * Revision 1.9  1996/03/20  13:54:05  adam
16  * The Tcl_File structure is only manipulated in the Tk-event interface
17  * in tkinit.c.
18  *
19  * Revision 1.8  1996/03/05  09:21:20  adam
20  * Bug fix: memory used by GRS records wasn't freed.
21  * Rewrote some of the error handling code - the connection is always
22  * closed before failback is called.
23  * If failback is defined the send APDU methods (init, search, ...) will
24  * return OK but invoke failback (as is the case if the write operation
25  * fails).
26  * Bug fix: ref_count in assoc object could grow if fraction of PDU was
27  * read.
28  *
29  * Revision 1.7  1996/02/19  15:41:55  adam
30  * Better log messages.
31  * Minor improvement of connect method.
32  *
33  * Revision 1.6  1996/02/06  09:22:54  adam
34  * Ported ir-tcl to use beta releases of tcl7.5/tk4.1.
35  *
36  * Revision 1.5  1995/11/28  13:53:40  quinn
37  * Windows port.
38  *
39  * Revision 1.4  1995/10/17  12:18:59  adam
40  * Bug fix: when target connection closed, the connection was not
41  * properly reestablished.
42  *
43  * Revision 1.3  1995/08/04  11:32:40  adam
44  * More work on output queue. Memory related routines moved
45  * to mem.c
46  *
47  * Revision 1.2  1995/08/03  13:23:01  adam
48  * Request queue.
49  *
50  * Revision 1.1  1995/07/28  10:28:39  adam
51  * First work on request queue.
52  *
53  */
54
55 #include <stdlib.h>
56 #include <stdio.h>
57 #include <ctype.h>
58 #include <assert.h>
59
60 #include "ir-tclp.h"
61
62 int ir_tcl_send_APDU (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu,
63                       const char *msg, const char *object_name)
64 {
65     IrTcl_Request **rp;
66
67     if (!z_APDU (p->odr_out, &apdu, 0))
68     {
69         Tcl_AppendResult (interp, odr_errmsg (odr_geterror (p->odr_out)),
70                           NULL);
71         odr_reset (p->odr_out);
72         return TCL_ERROR;
73     }
74     rp = &p->request_queue;
75     while (*rp)
76         rp = &(*rp)->next;
77     *rp = ir_tcl_malloc (sizeof(**rp));
78     (*rp)->next = NULL;
79     
80     if (ir_tcl_strdup (interp, &(*rp)->object_name, object_name) == TCL_ERROR)
81         return TCL_ERROR;
82     if (ir_tcl_strdup (interp, &(*rp)->callback, p->callback) == TCL_ERROR)
83         return TCL_ERROR;
84     
85     (*rp)->buf_out = odr_getbuf (p->odr_out, &(*rp)->len_out, NULL);
86     odr_setbuf (p->odr_out, NULL, 0, 1);
87     odr_reset (p->odr_out);
88     if (p->state == IR_TCL_R_Idle)
89     {
90         logf (LOG_DEBUG, "APDU send %s", msg);
91         if (ir_tcl_send_q (p, p->request_queue, msg) == TCL_ERROR)
92         {
93             if (p->failback)
94             {
95                 ir_tcl_disconnect (p);
96                 p->failInfo = IR_TCL_FAIL_WRITE;
97                 ir_tcl_eval (interp, p->failback);
98                 return TCL_OK;
99             }
100             else 
101             {
102                 sprintf (interp->result, "cs_put failed in %s", msg);
103                 return TCL_ERROR;
104             }
105         } 
106     }
107     else
108         logf (LOG_DEBUG, "APDU pending %s", msg);
109     return TCL_OK;
110 }
111
112 int ir_tcl_send_q (IrTcl_Obj *p, IrTcl_Request *rp, const char *msg)
113 {
114     int r;
115
116     assert (rp);
117     r = cs_put (p->cs_link, rp->buf_out, rp->len_out);
118     if (r < 0)
119         return TCL_ERROR;
120     else if (r == 1)
121     {
122         ir_select_add_write (cs_fileno (p->cs_link), p);
123         logf (LOG_DEBUG, "Send part of %s", msg);
124         p->state = IR_TCL_R_Writing;
125     }
126     else
127     {
128         logf (LOG_DEBUG, "Send %s (%d bytes) fd=%d", msg, rp->len_out,
129               cs_fileno(p->cs_link));
130         p->state = IR_TCL_R_Waiting;
131         xfree (rp->buf_out);
132         rp->buf_out = NULL;
133     }
134     return TCL_OK;
135 }
136
137 void ir_tcl_del_q (IrTcl_Obj *p)
138 {
139     IrTcl_Request *rp, *rp1;
140
141     p->state = IR_TCL_R_Idle;
142     for (rp = p->request_queue; rp; rp = rp1)
143     {
144         xfree (rp->object_name);
145         xfree (rp->callback);
146         xfree (rp->buf_out);
147         rp1 = rp->next;
148         xfree (rp);
149     }
150     p->request_queue = NULL;
151 }
152
153
154