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