etc/services - sync with NetBSD-8
[minix.git] / crypto / external / bsd / openssl / dist / demos / tunala / buffer.c
blob8e2cc9d200c11b021c180f4b3372aa0020ff9083
1 #include "tunala.h"
3 #ifndef NO_BUFFER
5 void buffer_init(buffer_t * buf)
7 buf->used = 0;
8 buf->total_in = buf->total_out = 0;
11 void buffer_close(buffer_t * buf)
13 /* Our data is static - nothing needs "release", just reset it */
14 buf->used = 0;
17 /* Code these simple ones in compact form */
18 unsigned int buffer_used(buffer_t * buf)
20 return buf->used;
23 unsigned int buffer_unused(buffer_t * buf)
25 return (MAX_DATA_SIZE - buf->used);
28 int buffer_full(buffer_t * buf)
30 return (buf->used == MAX_DATA_SIZE ? 1 : 0);
33 int buffer_notfull(buffer_t * buf)
35 return (buf->used < MAX_DATA_SIZE ? 1 : 0);
38 int buffer_empty(buffer_t * buf)
40 return (buf->used == 0 ? 1 : 0);
43 int buffer_notempty(buffer_t * buf)
45 return (buf->used > 0 ? 1 : 0);
48 unsigned long buffer_total_in(buffer_t * buf)
50 return buf->total_in;
53 unsigned long buffer_total_out(buffer_t * buf)
55 return buf->total_out;
59 * These 3 static (internal) functions don't adjust the "total" variables as
60 * it's not sure when they're called how it should be interpreted. Only the
61 * higher-level "buffer_[to|from]_[fd|SSL|BIO]" functions should alter these
62 * values.
64 # if 0 /* To avoid "unused" warnings */
65 static unsigned int buffer_adddata(buffer_t * buf, const unsigned char *ptr,
66 unsigned int size)
68 unsigned int added = MAX_DATA_SIZE - buf->used;
69 if (added > size)
70 added = size;
71 if (added == 0)
72 return 0;
73 memcpy(buf->data + buf->used, ptr, added);
74 buf->used += added;
75 buf->total_in += added;
76 return added;
79 static unsigned int buffer_tobuffer(buffer_t * to, buffer_t * from, int cap)
81 unsigned int moved, tomove = from->used;
82 if ((int)tomove > cap)
83 tomove = cap;
84 if (tomove == 0)
85 return 0;
86 moved = buffer_adddata(to, from->data, tomove);
87 if (moved == 0)
88 return 0;
89 buffer_takedata(from, NULL, moved);
90 return moved;
92 # endif
94 static unsigned int buffer_takedata(buffer_t * buf, unsigned char *ptr,
95 unsigned int size)
97 unsigned int taken = buf->used;
98 if (taken > size)
99 taken = size;
100 if (taken == 0)
101 return 0;
102 if (ptr)
103 memcpy(ptr, buf->data, taken);
104 buf->used -= taken;
105 /* Do we have to scroll? */
106 if (buf->used > 0)
107 memmove(buf->data, buf->data + taken, buf->used);
108 return taken;
111 # ifndef NO_IP
113 int buffer_from_fd(buffer_t * buf, int fd)
115 int toread = buffer_unused(buf);
116 if (toread == 0)
117 /* Shouldn't be called in this case! */
118 abort();
119 toread = read(fd, buf->data + buf->used, toread);
120 if (toread > 0) {
121 buf->used += toread;
122 buf->total_in += toread;
124 return toread;
127 int buffer_to_fd(buffer_t * buf, int fd)
129 int towrite = buffer_used(buf);
130 if (towrite == 0)
131 /* Shouldn't be called in this case! */
132 abort();
133 towrite = write(fd, buf->data, towrite);
134 if (towrite > 0) {
135 buffer_takedata(buf, NULL, towrite);
136 buf->total_out += towrite;
138 return towrite;
141 # endif /* !defined(NO_IP) */
143 # ifndef NO_OPENSSL
145 static void int_ssl_check(SSL *s, int ret)
147 int e = SSL_get_error(s, ret);
148 switch (e) {
150 * These seem to be harmless and already "dealt with" by our
151 * non-blocking environment. NB: "ZERO_RETURN" is the clean "error"
152 * indicating a successfully closed SSL tunnel. We let this happen
153 * because our IO loop should not appear to have broken on this
154 * condition - and outside the IO loop, the "shutdown" state is
155 * checked.
157 case SSL_ERROR_NONE:
158 case SSL_ERROR_WANT_READ:
159 case SSL_ERROR_WANT_WRITE:
160 case SSL_ERROR_WANT_X509_LOOKUP:
161 case SSL_ERROR_ZERO_RETURN:
162 return;
164 * These seem to be indications of a genuine error that should result
165 * in the SSL tunnel being regarded as "dead".
167 case SSL_ERROR_SYSCALL:
168 case SSL_ERROR_SSL:
169 SSL_set_app_data(s, (char *)1);
170 return;
171 default:
172 break;
175 * For any other errors that (a) exist, and (b) crop up - we need to
176 * interpret what to do with them - so "politely inform" the caller that
177 * the code needs updating here.
179 abort();
182 void buffer_from_SSL(buffer_t * buf, SSL *ssl)
184 int ret;
185 if (!ssl || buffer_full(buf))
186 return;
187 ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
188 if (ret > 0) {
189 buf->used += ret;
190 buf->total_in += ret;
192 if (ret < 0)
193 int_ssl_check(ssl, ret);
196 void buffer_to_SSL(buffer_t * buf, SSL *ssl)
198 int ret;
199 if (!ssl || buffer_empty(buf))
200 return;
201 ret = SSL_write(ssl, buf->data, buf->used);
202 if (ret > 0) {
203 buffer_takedata(buf, NULL, ret);
204 buf->total_out += ret;
206 if (ret < 0)
207 int_ssl_check(ssl, ret);
210 void buffer_from_BIO(buffer_t * buf, BIO *bio)
212 int ret;
213 if (!bio || buffer_full(buf))
214 return;
215 ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf));
216 if (ret > 0) {
217 buf->used += ret;
218 buf->total_in += ret;
222 void buffer_to_BIO(buffer_t * buf, BIO *bio)
224 int ret;
225 if (!bio || buffer_empty(buf))
226 return;
227 ret = BIO_write(bio, buf->data, buf->used);
228 if (ret > 0) {
229 buffer_takedata(buf, NULL, ret);
230 buf->total_out += ret;
234 # endif /* !defined(NO_OPENSSL) */
236 #endif /* !defined(NO_BUFFER) */