~etc-pgh-launchpad/wildpockets/trunk

« back to all changes in this revision

Viewing changes to openssl-src/crypto/bio/bss_fd.c

  • Committer: etc-pgh-launchpad at cmu
  • Date: 2010-11-30 20:56:30 UTC
  • Revision ID: etc-pgh-launchpad@lists.andrew.cmu.edu-20101130205630-0blbkcz28ovjl8wj
Committing the Wild Pockets code base to Launchpad.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* crypto/bio/bss_fd.c */
 
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 
3
 * All rights reserved.
 
4
 *
 
5
 * This package is an SSL implementation written
 
6
 * by Eric Young (eay@cryptsoft.com).
 
7
 * The implementation was written so as to conform with Netscapes SSL.
 
8
 * 
 
9
 * This library is free for commercial and non-commercial use as long as
 
10
 * the following conditions are aheared to.  The following conditions
 
11
 * apply to all code found in this distribution, be it the RC4, RSA,
 
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 
13
 * included with this distribution is covered by the same copyright terms
 
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 
15
 * 
 
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
 
17
 * the code are not to be removed.
 
18
 * If this package is used in a product, Eric Young should be given attribution
 
19
 * as the author of the parts of the library used.
 
20
 * This can be in the form of a textual message at program startup or
 
21
 * in documentation (online or textual) provided with the package.
 
22
 * 
 
23
 * Redistribution and use in source and binary forms, with or without
 
24
 * modification, are permitted provided that the following conditions
 
25
 * are met:
 
26
 * 1. Redistributions of source code must retain the copyright
 
27
 *    notice, this list of conditions and the following disclaimer.
 
28
 * 2. Redistributions in binary form must reproduce the above copyright
 
29
 *    notice, this list of conditions and the following disclaimer in the
 
30
 *    documentation and/or other materials provided with the distribution.
 
31
 * 3. All advertising materials mentioning features or use of this software
 
32
 *    must display the following acknowledgement:
 
33
 *    "This product includes cryptographic software written by
 
34
 *     Eric Young (eay@cryptsoft.com)"
 
35
 *    The word 'cryptographic' can be left out if the rouines from the library
 
36
 *    being used are not cryptographic related :-).
 
37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 
38
 *    the apps directory (application code) you must include an acknowledgement:
 
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 
40
 * 
 
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
51
 * SUCH DAMAGE.
 
52
 * 
 
53
 * The licence and distribution terms for any publically available version or
 
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 
55
 * copied and put under another distribution licence
 
56
 * [including the GNU Public Licence.]
 
57
 */
 
58
 
 
59
#include <stdio.h>
 
60
#include <errno.h>
 
61
#define USE_SOCKETS
 
62
#include "cryptlib.h"
 
63
/*
 
64
 * As for unconditional usage of "UPLINK" interface in this module.
 
65
 * Trouble is that unlike Unix file descriptors [which are indexes
 
66
 * in kernel-side per-process table], corresponding descriptors on
 
67
 * platforms which require "UPLINK" interface seem to be indexes
 
68
 * in a user-land, non-global table. Well, in fact they are indexes
 
69
 * in stdio _iob[], and recall that _iob[] was the very reason why
 
70
 * "UPLINK" interface was introduced in first place. But one way on
 
71
 * another. Neither libcrypto or libssl use this BIO meaning that
 
72
 * file descriptors can only be provided by application. Therefore
 
73
 * "UPLINK" calls are due...
 
74
 */
 
75
#include "bio_lcl.h"
 
76
 
 
77
static int fd_write(BIO *h, const char *buf, int num);
 
78
static int fd_read(BIO *h, char *buf, int size);
 
79
static int fd_puts(BIO *h, const char *str);
 
80
static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 
81
static int fd_new(BIO *h);
 
82
static int fd_free(BIO *data);
 
83
int BIO_fd_should_retry(int s);
 
84
 
 
85
static BIO_METHOD methods_fdp=
 
86
        {
 
87
        BIO_TYPE_FD,"file descriptor",
 
88
        fd_write,
 
89
        fd_read,
 
90
        fd_puts,
 
91
        NULL, /* fd_gets, */
 
92
        fd_ctrl,
 
93
        fd_new,
 
94
        fd_free,
 
95
        NULL,
 
96
        };
 
97
 
 
98
BIO_METHOD *BIO_s_fd(void)
 
99
        {
 
100
        return(&methods_fdp);
 
101
        }
 
102
 
 
103
BIO *BIO_new_fd(int fd,int close_flag)
 
104
        {
 
105
        BIO *ret;
 
106
        ret=BIO_new(BIO_s_fd());
 
107
        if (ret == NULL) return(NULL);
 
108
        BIO_set_fd(ret,fd,close_flag);
 
109
        return(ret);
 
110
        }
 
111
 
 
112
static int fd_new(BIO *bi)
 
113
        {
 
114
        bi->init=0;
 
115
        bi->num=-1;
 
116
        bi->ptr=NULL;
 
117
        bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */
 
118
        return(1);
 
119
        }
 
120
 
 
121
static int fd_free(BIO *a)
 
122
        {
 
123
        if (a == NULL) return(0);
 
124
        if (a->shutdown)
 
125
                {
 
126
                if (a->init)
 
127
                        {
 
128
                        UP_close(a->num);
 
129
                        }
 
130
                a->init=0;
 
131
                a->flags=BIO_FLAGS_UPLINK;
 
132
                }
 
133
        return(1);
 
134
        }
 
135
        
 
136
static int fd_read(BIO *b, char *out,int outl)
 
137
        {
 
138
        int ret=0;
 
139
 
 
140
        if (out != NULL)
 
141
                {
 
142
                clear_sys_error();
 
143
                ret=UP_read(b->num,out,outl);
 
144
                BIO_clear_retry_flags(b);
 
145
                if (ret <= 0)
 
146
                        {
 
147
                        if (BIO_fd_should_retry(ret))
 
148
                                BIO_set_retry_read(b);
 
149
                        }
 
150
                }
 
151
        return(ret);
 
152
        }
 
153
 
 
154
static int fd_write(BIO *b, const char *in, int inl)
 
155
        {
 
156
        int ret;
 
157
        clear_sys_error();
 
158
        ret=UP_write(b->num,in,inl);
 
159
        BIO_clear_retry_flags(b);
 
160
        if (ret <= 0)
 
161
                {
 
162
                if (BIO_fd_should_retry(ret))
 
163
                        BIO_set_retry_write(b);
 
164
                }
 
165
        return(ret);
 
166
        }
 
167
 
 
168
static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
 
169
        {
 
170
        long ret=1;
 
171
        int *ip;
 
172
 
 
173
        switch (cmd)
 
174
                {
 
175
        case BIO_CTRL_RESET:
 
176
                num=0;
 
177
        case BIO_C_FILE_SEEK:
 
178
                ret=(long)UP_lseek(b->num,num,0);
 
179
                break;
 
180
        case BIO_C_FILE_TELL:
 
181
        case BIO_CTRL_INFO:
 
182
                ret=(long)UP_lseek(b->num,0,1);
 
183
                break;
 
184
        case BIO_C_SET_FD:
 
185
                fd_free(b);
 
186
                b->num= *((int *)ptr);
 
187
                b->shutdown=(int)num;
 
188
                b->init=1;
 
189
                break;
 
190
        case BIO_C_GET_FD:
 
191
                if (b->init)
 
192
                        {
 
193
                        ip=(int *)ptr;
 
194
                        if (ip != NULL) *ip=b->num;
 
195
                        ret=b->num;
 
196
                        }
 
197
                else
 
198
                        ret= -1;
 
199
                break;
 
200
        case BIO_CTRL_GET_CLOSE:
 
201
                ret=b->shutdown;
 
202
                break;
 
203
        case BIO_CTRL_SET_CLOSE:
 
204
                b->shutdown=(int)num;
 
205
                break;
 
206
        case BIO_CTRL_PENDING:
 
207
        case BIO_CTRL_WPENDING:
 
208
                ret=0;
 
209
                break;
 
210
        case BIO_CTRL_DUP:
 
211
        case BIO_CTRL_FLUSH:
 
212
                ret=1;
 
213
                break;
 
214
        default:
 
215
                ret=0;
 
216
                break;
 
217
                }
 
218
        return(ret);
 
219
        }
 
220
 
 
221
static int fd_puts(BIO *bp, const char *str)
 
222
        {
 
223
        int n,ret;
 
224
 
 
225
        n=strlen(str);
 
226
        ret=fd_write(bp,str,n);
 
227
        return(ret);
 
228
        }
 
229
 
 
230
int BIO_fd_should_retry(int i)
 
231
        {
 
232
        int err;
 
233
 
 
234
        if ((i == 0) || (i == -1))
 
235
                {
 
236
                err=get_last_sys_error();
 
237
 
 
238
#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
 
239
                if ((i == -1) && (err == 0))
 
240
                        return(1);
 
241
#endif
 
242
 
 
243
                return(BIO_fd_non_fatal_error(err));
 
244
                }
 
245
        return(0);
 
246
        }
 
247
 
 
248
int BIO_fd_non_fatal_error(int err)
 
249
        {
 
250
        switch (err)
 
251
                {
 
252
 
 
253
#ifdef EWOULDBLOCK
 
254
# ifdef WSAEWOULDBLOCK
 
255
#  if WSAEWOULDBLOCK != EWOULDBLOCK
 
256
        case EWOULDBLOCK:
 
257
#  endif
 
258
# else
 
259
        case EWOULDBLOCK:
 
260
# endif
 
261
#endif
 
262
 
 
263
#if defined(ENOTCONN)
 
264
        case ENOTCONN:
 
265
#endif
 
266
 
 
267
#ifdef EINTR
 
268
        case EINTR:
 
269
#endif
 
270
 
 
271
#ifdef EAGAIN
 
272
#if EWOULDBLOCK != EAGAIN
 
273
        case EAGAIN:
 
274
# endif
 
275
#endif
 
276
 
 
277
#ifdef EPROTO
 
278
        case EPROTO:
 
279
#endif
 
280
 
 
281
#ifdef EINPROGRESS
 
282
        case EINPROGRESS:
 
283
#endif
 
284
 
 
285
#ifdef EALREADY
 
286
        case EALREADY:
 
287
#endif
 
288
                return(1);
 
289
                /* break; */
 
290
        default:
 
291
                break;
 
292
                }
 
293
        return(0);
 
294
        }