source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_lbuf.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 8.4 KB
Line 
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <errno.h>
12#include "bio_lcl.h"
13#include "internal/cryptlib.h"
14#include <openssl/evp.h>
15
16static int linebuffer_write(BIO *h, const char *buf, int num);
17static int linebuffer_read(BIO *h, char *buf, int size);
18static int linebuffer_puts(BIO *h, const char *str);
19static int linebuffer_gets(BIO *h, char *str, int size);
20static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
21static int linebuffer_new(BIO *h);
22static int linebuffer_free(BIO *data);
23static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
24
25/* A 10k maximum should be enough for most purposes */
26#define DEFAULT_LINEBUFFER_SIZE 1024*10
27
28/* #define DEBUG */
29
30static const BIO_METHOD methods_linebuffer = {
31 BIO_TYPE_LINEBUFFER,
32 "linebuffer",
33 linebuffer_write,
34 linebuffer_read,
35 linebuffer_puts,
36 linebuffer_gets,
37 linebuffer_ctrl,
38 linebuffer_new,
39 linebuffer_free,
40 linebuffer_callback_ctrl,
41};
42
43const BIO_METHOD *BIO_f_linebuffer(void)
44{
45 return (&methods_linebuffer);
46}
47
48typedef struct bio_linebuffer_ctx_struct {
49 char *obuf; /* the output char array */
50 int obuf_size; /* how big is the output buffer */
51 int obuf_len; /* how many bytes are in it */
52} BIO_LINEBUFFER_CTX;
53
54static int linebuffer_new(BIO *bi)
55{
56 BIO_LINEBUFFER_CTX *ctx;
57
58 ctx = OPENSSL_malloc(sizeof(*ctx));
59 if (ctx == NULL)
60 return (0);
61 ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
62 if (ctx->obuf == NULL) {
63 OPENSSL_free(ctx);
64 return (0);
65 }
66 ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE;
67 ctx->obuf_len = 0;
68
69 bi->init = 1;
70 bi->ptr = (char *)ctx;
71 bi->flags = 0;
72 return (1);
73}
74
75static int linebuffer_free(BIO *a)
76{
77 BIO_LINEBUFFER_CTX *b;
78
79 if (a == NULL)
80 return (0);
81 b = (BIO_LINEBUFFER_CTX *)a->ptr;
82 OPENSSL_free(b->obuf);
83 OPENSSL_free(a->ptr);
84 a->ptr = NULL;
85 a->init = 0;
86 a->flags = 0;
87 return (1);
88}
89
90static int linebuffer_read(BIO *b, char *out, int outl)
91{
92 int ret = 0;
93
94 if (out == NULL)
95 return (0);
96 if (b->next_bio == NULL)
97 return (0);
98 ret = BIO_read(b->next_bio, out, outl);
99 BIO_clear_retry_flags(b);
100 BIO_copy_next_retry(b);
101 return (ret);
102}
103
104static int linebuffer_write(BIO *b, const char *in, int inl)
105{
106 int i, num = 0, foundnl;
107 BIO_LINEBUFFER_CTX *ctx;
108
109 if ((in == NULL) || (inl <= 0))
110 return (0);
111 ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
112 if ((ctx == NULL) || (b->next_bio == NULL))
113 return (0);
114
115 BIO_clear_retry_flags(b);
116
117 do {
118 const char *p;
119
120 for (p = in; p < in + inl && *p != '\n'; p++) ;
121 if (*p == '\n') {
122 p++;
123 foundnl = 1;
124 } else
125 foundnl = 0;
126
127 /*
128 * If a NL was found and we already have text in the save buffer,
129 * concatenate them and write
130 */
131 while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
132 && ctx->obuf_len > 0) {
133 int orig_olen = ctx->obuf_len;
134
135 i = ctx->obuf_size - ctx->obuf_len;
136 if (p - in > 0) {
137 if (i >= p - in) {
138 memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in);
139 ctx->obuf_len += p - in;
140 inl -= p - in;
141 num += p - in;
142 in = p;
143 } else {
144 memcpy(&(ctx->obuf[ctx->obuf_len]), in, i);
145 ctx->obuf_len += i;
146 inl -= i;
147 in += i;
148 num += i;
149 }
150 }
151 i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
152 if (i <= 0) {
153 ctx->obuf_len = orig_olen;
154 BIO_copy_next_retry(b);
155
156 if (i < 0)
157 return ((num > 0) ? num : i);
158 if (i == 0)
159 return (num);
160 }
161 if (i < ctx->obuf_len)
162 memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
163 ctx->obuf_len -= i;
164 }
165
166 /*
167 * Now that the save buffer is emptied, let's write the input buffer
168 * if a NL was found and there is anything to write.
169 */
170 if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) {
171 i = BIO_write(b->next_bio, in, p - in);
172 if (i <= 0) {
173 BIO_copy_next_retry(b);
174 if (i < 0)
175 return ((num > 0) ? num : i);
176 if (i == 0)
177 return (num);
178 }
179 num += i;
180 in += i;
181 inl -= i;
182 }
183 }
184 while (foundnl && inl > 0);
185 /*
186 * We've written as much as we can. The rest of the input buffer, if
187 * any, is text that doesn't and with a NL and therefore needs to be
188 * saved for the next trip.
189 */
190 if (inl > 0) {
191 memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
192 ctx->obuf_len += inl;
193 num += inl;
194 }
195 return num;
196}
197
198static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
199{
200 BIO *dbio;
201 BIO_LINEBUFFER_CTX *ctx;
202 long ret = 1;
203 char *p;
204 int r;
205 int obs;
206
207 ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
208
209 switch (cmd) {
210 case BIO_CTRL_RESET:
211 ctx->obuf_len = 0;
212 if (b->next_bio == NULL)
213 return (0);
214 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
215 break;
216 case BIO_CTRL_INFO:
217 ret = (long)ctx->obuf_len;
218 break;
219 case BIO_CTRL_WPENDING:
220 ret = (long)ctx->obuf_len;
221 if (ret == 0) {
222 if (b->next_bio == NULL)
223 return (0);
224 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
225 }
226 break;
227 case BIO_C_SET_BUFF_SIZE:
228 obs = (int)num;
229 p = ctx->obuf;
230 if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) {
231 p = OPENSSL_malloc((int)num);
232 if (p == NULL)
233 goto malloc_error;
234 }
235 if (ctx->obuf != p) {
236 if (ctx->obuf_len > obs) {
237 ctx->obuf_len = obs;
238 }
239 memcpy(p, ctx->obuf, ctx->obuf_len);
240 OPENSSL_free(ctx->obuf);
241 ctx->obuf = p;
242 ctx->obuf_size = obs;
243 }
244 break;
245 case BIO_C_DO_STATE_MACHINE:
246 if (b->next_bio == NULL)
247 return (0);
248 BIO_clear_retry_flags(b);
249 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
250 BIO_copy_next_retry(b);
251 break;
252
253 case BIO_CTRL_FLUSH:
254 if (b->next_bio == NULL)
255 return (0);
256 if (ctx->obuf_len <= 0) {
257 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
258 break;
259 }
260
261 for (;;) {
262 BIO_clear_retry_flags(b);
263 if (ctx->obuf_len > 0) {
264 r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
265 BIO_copy_next_retry(b);
266 if (r <= 0)
267 return ((long)r);
268 if (r < ctx->obuf_len)
269 memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r);
270 ctx->obuf_len -= r;
271 } else {
272 ctx->obuf_len = 0;
273 break;
274 }
275 }
276 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
277 break;
278 case BIO_CTRL_DUP:
279 dbio = (BIO *)ptr;
280 if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
281 ret = 0;
282 break;
283 default:
284 if (b->next_bio == NULL)
285 return (0);
286 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
287 break;
288 }
289 return (ret);
290 malloc_error:
291 BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE);
292 return (0);
293}
294
295static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
296{
297 long ret = 1;
298
299 if (b->next_bio == NULL)
300 return (0);
301 switch (cmd) {
302 default:
303 ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
304 break;
305 }
306 return (ret);
307}
308
309static int linebuffer_gets(BIO *b, char *buf, int size)
310{
311 if (b->next_bio == NULL)
312 return (0);
313 return (BIO_gets(b->next_bio, buf, size));
314}
315
316static int linebuffer_puts(BIO *b, const char *str)
317{
318 return (linebuffer_write(b, str, strlen(str)));
319}
Note: See TracBrowser for help on using the repository browser.