~ubuntu-branches/ubuntu/hardy/tcltls/hardy

« back to all changes in this revision

Viewing changes to tlsBIO.c

  • Committer: Bazaar Package Importer
  • Author(s): Søren Boll Overgaard
  • Date: 2004-06-16 19:22:30 UTC
  • Revision ID: james.westby@ubuntu.com-20040616192230-tv159811lsnerauf
Tags: upstream-1.5.0
Import upstream version 1.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1997-2000 Matt Newman <matt@novadigm.com>
 
3
 *
 
4
 * $Header: /cvsroot/tls/tls/tlsBIO.c,v 1.7 2004/02/04 04:02:19 razzell Exp $
 
5
 *
 
6
 * Provides BIO layer to interface openssl to Tcl.
 
7
 */
 
8
 
 
9
#include "tlsInt.h"
 
10
 
 
11
/*
 
12
 * Forward declarations
 
13
 */
 
14
 
 
15
static int BioWrite     _ANSI_ARGS_ ((BIO *h, CONST char *buf, int num));
 
16
static int BioRead      _ANSI_ARGS_ ((BIO *h, char *buf, int num));
 
17
static int BioPuts      _ANSI_ARGS_ ((BIO *h, CONST char *str));
 
18
static long BioCtrl     _ANSI_ARGS_ ((BIO *h, int cmd, long arg1, void *ptr));
 
19
static int BioNew       _ANSI_ARGS_ ((BIO *h));
 
20
static int BioFree      _ANSI_ARGS_ ((BIO *h));
 
21
 
 
22
 
 
23
static BIO_METHOD BioMethods = {
 
24
    BIO_TYPE_TCL, "tcl",
 
25
    BioWrite,
 
26
    BioRead,
 
27
    BioPuts,
 
28
    NULL,       /* BioGets */
 
29
    BioCtrl,
 
30
    BioNew,
 
31
    BioFree,
 
32
};
 
33
 
 
34
BIO *
 
35
BIO_new_tcl(statePtr, flags)
 
36
    State *statePtr;
 
37
    int flags;
 
38
{
 
39
    BIO *bio;
 
40
 
 
41
    bio                 = BIO_new(&BioMethods);
 
42
    bio->ptr            = (char*)statePtr;
 
43
    bio->init           = 1;
 
44
    bio->shutdown       = flags;
 
45
 
 
46
    return bio;
 
47
}
 
48
 
 
49
BIO_METHOD *
 
50
BIO_s_tcl()
 
51
{
 
52
    return &BioMethods;
 
53
}
 
54
 
 
55
static int
 
56
BioWrite (bio, buf, bufLen)
 
57
    BIO *bio;
 
58
    CONST char *buf;
 
59
    int bufLen;
 
60
{
 
61
    Tcl_Channel chan = Tls_GetParent((State*)(bio->ptr));
 
62
    int ret;
 
63
 
 
64
    dprintf(stderr,"\nBioWrite(0x%x, <buf>, %d) [0x%x]",
 
65
            (unsigned int) bio, bufLen, (unsigned int) chan);
 
66
 
 
67
    if (channelTypeVersion == TLS_CHANNEL_VERSION_2) {
 
68
        ret = Tcl_WriteRaw(chan, buf, bufLen);
 
69
    } else {
 
70
        ret = Tcl_Write(chan, buf, bufLen);
 
71
    }
 
72
 
 
73
    dprintf(stderr,"\n[0x%x] BioWrite(%d) -> %d [%d.%d]",
 
74
            (unsigned int) chan, bufLen, ret, Tcl_Eof(chan), Tcl_GetErrno());
 
75
 
 
76
    BIO_clear_flags(bio, BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
 
77
 
 
78
    if (ret == 0) {
 
79
        if (!Tcl_Eof(chan)) {
 
80
            BIO_set_retry_write(bio);
 
81
            ret = -1;
 
82
        }
 
83
    }
 
84
    if (BIO_should_read(bio)) {
 
85
        BIO_set_retry_read(bio);
 
86
    }
 
87
    return ret;
 
88
}
 
89
 
 
90
static int
 
91
BioRead (bio, buf, bufLen)
 
92
    BIO *bio;
 
93
    char *buf;
 
94
    int bufLen;
 
95
{
 
96
    Tcl_Channel chan = Tls_GetParent((State*)bio->ptr);
 
97
    int ret = 0;
 
98
 
 
99
    dprintf(stderr,"\nBioRead(0x%x, <buf>, %d) [0x%x]",
 
100
            (unsigned int) bio, bufLen, (unsigned int) chan);
 
101
 
 
102
    if (buf == NULL) return 0;
 
103
 
 
104
    if (channelTypeVersion == TLS_CHANNEL_VERSION_2) {
 
105
        ret = Tcl_ReadRaw(chan, buf, bufLen);
 
106
    } else {
 
107
        ret = Tcl_Read(chan, buf, bufLen);
 
108
    }
 
109
 
 
110
    dprintf(stderr,"\n[0x%x] BioRead(%d) -> %d [%d.%d]",
 
111
            (unsigned int) chan, bufLen, ret, Tcl_Eof(chan), Tcl_GetErrno());
 
112
 
 
113
    BIO_clear_flags(bio, BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
 
114
 
 
115
    if (ret == 0) {
 
116
        if (!Tcl_Eof(chan)) {
 
117
            BIO_set_retry_read(bio);
 
118
            ret = -1;
 
119
        }
 
120
    }
 
121
    if (BIO_should_write(bio)) {
 
122
        BIO_set_retry_write(bio);
 
123
    }
 
124
    return ret;
 
125
}
 
126
 
 
127
static int
 
128
BioPuts (bio, str)
 
129
    BIO *bio;
 
130
    CONST char *str;
 
131
{
 
132
    return BioWrite(bio, str, strlen(str));
 
133
}
 
134
 
 
135
static long
 
136
BioCtrl (bio, cmd, num, ptr)
 
137
    BIO *bio;
 
138
    int cmd;
 
139
    long num;
 
140
    void *ptr;
 
141
{
 
142
    Tcl_Channel chan = Tls_GetParent((State*)bio->ptr);
 
143
    long ret = 1;
 
144
    int *ip;
 
145
 
 
146
    dprintf(stderr,"\nBioCtrl(0x%x, 0x%x, 0x%x, 0x%x)",
 
147
            (unsigned int) bio, (unsigned int) cmd, (unsigned int) num,
 
148
            (unsigned int) ptr);
 
149
 
 
150
    switch (cmd) {
 
151
    case BIO_CTRL_RESET:
 
152
        num = 0;
 
153
    case BIO_C_FILE_SEEK:
 
154
    case BIO_C_FILE_TELL:
 
155
        ret = 0;
 
156
        break;
 
157
    case BIO_CTRL_INFO:
 
158
        ret = 1;
 
159
        break;
 
160
    case BIO_C_SET_FD:
 
161
        BioFree(bio);
 
162
        /* Sets State* */
 
163
        bio->ptr        = *((char **)ptr);
 
164
        bio->shutdown   = (int)num;
 
165
        bio->init       = 1;
 
166
        break;
 
167
    case BIO_C_GET_FD:
 
168
        if (bio->init) {
 
169
            ip = (int *)ptr;
 
170
            if (ip != NULL) {
 
171
                *ip = bio->num;
 
172
            }
 
173
            ret = bio->num;
 
174
        } else {
 
175
            ret = -1;
 
176
        }
 
177
        break;
 
178
    case BIO_CTRL_GET_CLOSE:
 
179
        ret = bio->shutdown;
 
180
        break;
 
181
    case BIO_CTRL_SET_CLOSE:
 
182
        bio->shutdown = (int)num;
 
183
        break;
 
184
    case BIO_CTRL_EOF:
 
185
        dprintf(stderr, "BIO_CTRL_EOF\n");
 
186
        ret = Tcl_Eof(chan);
 
187
        break;
 
188
    case BIO_CTRL_PENDING:
 
189
        ret = (Tcl_InputBuffered(chan) ? 1 : 0);
 
190
        dprintf(stderr, "BIO_CTRL_PENDING(%d)\n", (int) ret);
 
191
        break;
 
192
    case BIO_CTRL_WPENDING:
 
193
        ret = 0;
 
194
        break;
 
195
    case BIO_CTRL_DUP:
 
196
        break;
 
197
    case BIO_CTRL_FLUSH:
 
198
        dprintf(stderr, "BIO_CTRL_FLUSH\n");
 
199
        if (channelTypeVersion == TLS_CHANNEL_VERSION_2) {
 
200
            ret = ((Tcl_WriteRaw(chan, "", 0) >= 0) ? 1 : -1);
 
201
        } else {
 
202
            ret = ((Tcl_Flush(chan) == TCL_OK) ? 1 : -1);
 
203
        }
 
204
        break;
 
205
    default:
 
206
        ret = 0;
 
207
        break;
 
208
    }
 
209
    return(ret);
 
210
}
 
211
 
 
212
static int
 
213
BioNew  (bio)
 
214
    BIO *bio;
 
215
{
 
216
    bio->init   = 0;
 
217
    bio->num    = 0;
 
218
    bio->ptr    = NULL;
 
219
    bio->flags  = 0;
 
220
 
 
221
    return 1;
 
222
}
 
223
 
 
224
static int
 
225
BioFree (bio)
 
226
    BIO *bio;
 
227
{
 
228
    if (bio == NULL) {
 
229
        return 0;
 
230
    }
 
231
 
 
232
    if (bio->shutdown) {
 
233
        if (bio->init) {
 
234
            /*shutdown(bio->num, 2) */
 
235
            /*closesocket(bio->num) */
 
236
        }
 
237
        bio->init       = 0;
 
238
        bio->flags      = 0;
 
239
        bio->num        = 0;
 
240
    }
 
241
    return 1;
 
242
}