1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (C) 1995-1998 Eric Young ([email protected])
2*8fb009dcSAndroid Build Coastguard Worker * All rights reserved.
3*8fb009dcSAndroid Build Coastguard Worker *
4*8fb009dcSAndroid Build Coastguard Worker * This package is an SSL implementation written
5*8fb009dcSAndroid Build Coastguard Worker * by Eric Young ([email protected]).
6*8fb009dcSAndroid Build Coastguard Worker * The implementation was written so as to conform with Netscapes SSL.
7*8fb009dcSAndroid Build Coastguard Worker *
8*8fb009dcSAndroid Build Coastguard Worker * This library is free for commercial and non-commercial use as long as
9*8fb009dcSAndroid Build Coastguard Worker * the following conditions are aheared to. The following conditions
10*8fb009dcSAndroid Build Coastguard Worker * apply to all code found in this distribution, be it the RC4, RSA,
11*8fb009dcSAndroid Build Coastguard Worker * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12*8fb009dcSAndroid Build Coastguard Worker * included with this distribution is covered by the same copyright terms
13*8fb009dcSAndroid Build Coastguard Worker * except that the holder is Tim Hudson ([email protected]).
14*8fb009dcSAndroid Build Coastguard Worker *
15*8fb009dcSAndroid Build Coastguard Worker * Copyright remains Eric Young's, and as such any Copyright notices in
16*8fb009dcSAndroid Build Coastguard Worker * the code are not to be removed.
17*8fb009dcSAndroid Build Coastguard Worker * If this package is used in a product, Eric Young should be given attribution
18*8fb009dcSAndroid Build Coastguard Worker * as the author of the parts of the library used.
19*8fb009dcSAndroid Build Coastguard Worker * This can be in the form of a textual message at program startup or
20*8fb009dcSAndroid Build Coastguard Worker * in documentation (online or textual) provided with the package.
21*8fb009dcSAndroid Build Coastguard Worker *
22*8fb009dcSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
23*8fb009dcSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
24*8fb009dcSAndroid Build Coastguard Worker * are met:
25*8fb009dcSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the copyright
26*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
27*8fb009dcSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
28*8fb009dcSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
29*8fb009dcSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
30*8fb009dcSAndroid Build Coastguard Worker * 3. All advertising materials mentioning features or use of this software
31*8fb009dcSAndroid Build Coastguard Worker * must display the following acknowledgement:
32*8fb009dcSAndroid Build Coastguard Worker * "This product includes cryptographic software written by
33*8fb009dcSAndroid Build Coastguard Worker * Eric Young ([email protected])"
34*8fb009dcSAndroid Build Coastguard Worker * The word 'cryptographic' can be left out if the rouines from the library
35*8fb009dcSAndroid Build Coastguard Worker * being used are not cryptographic related :-).
36*8fb009dcSAndroid Build Coastguard Worker * 4. If you include any Windows specific code (or a derivative thereof) from
37*8fb009dcSAndroid Build Coastguard Worker * the apps directory (application code) you must include an acknowledgement:
38*8fb009dcSAndroid Build Coastguard Worker * "This product includes software written by Tim Hudson ([email protected])"
39*8fb009dcSAndroid Build Coastguard Worker *
40*8fb009dcSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41*8fb009dcSAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*8fb009dcSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43*8fb009dcSAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44*8fb009dcSAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45*8fb009dcSAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46*8fb009dcSAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8fb009dcSAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48*8fb009dcSAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49*8fb009dcSAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50*8fb009dcSAndroid Build Coastguard Worker * SUCH DAMAGE.
51*8fb009dcSAndroid Build Coastguard Worker *
52*8fb009dcSAndroid Build Coastguard Worker * The licence and distribution terms for any publically available version or
53*8fb009dcSAndroid Build Coastguard Worker * derivative of this code cannot be changed. i.e. this code cannot simply be
54*8fb009dcSAndroid Build Coastguard Worker * copied and put under another distribution licence
55*8fb009dcSAndroid Build Coastguard Worker * [including the GNU Public Licence.] */
56*8fb009dcSAndroid Build Coastguard Worker
57*8fb009dcSAndroid Build Coastguard Worker #if defined(__linux) || defined(__sun) || defined(__hpux)
58*8fb009dcSAndroid Build Coastguard Worker // Following definition aliases fopen to fopen64 on above mentioned
59*8fb009dcSAndroid Build Coastguard Worker // platforms. This makes it possible to open and sequentially access
60*8fb009dcSAndroid Build Coastguard Worker // files larger than 2GB from 32-bit application. It does not allow to
61*8fb009dcSAndroid Build Coastguard Worker // traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
62*8fb009dcSAndroid Build Coastguard Worker // 32-bit platform permits that, not with fseek/ftell. Not to mention
63*8fb009dcSAndroid Build Coastguard Worker // that breaking 2GB limit for seeking would require surgery to *our*
64*8fb009dcSAndroid Build Coastguard Worker // API. But sequential access suffices for practical cases when you
65*8fb009dcSAndroid Build Coastguard Worker // can run into large files, such as fingerprinting, so we can let API
66*8fb009dcSAndroid Build Coastguard Worker // alone. For reference, the list of 32-bit platforms which allow for
67*8fb009dcSAndroid Build Coastguard Worker // sequential access of large files without extra "magic" comprise *BSD,
68*8fb009dcSAndroid Build Coastguard Worker // Darwin, IRIX...
69*8fb009dcSAndroid Build Coastguard Worker #ifndef _FILE_OFFSET_BITS
70*8fb009dcSAndroid Build Coastguard Worker #define _FILE_OFFSET_BITS 64
71*8fb009dcSAndroid Build Coastguard Worker #endif
72*8fb009dcSAndroid Build Coastguard Worker #endif
73*8fb009dcSAndroid Build Coastguard Worker
74*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bio.h>
75*8fb009dcSAndroid Build Coastguard Worker
76*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
77*8fb009dcSAndroid Build Coastguard Worker #include <errno.h>
78*8fb009dcSAndroid Build Coastguard Worker #include <stdio.h>
79*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
80*8fb009dcSAndroid Build Coastguard Worker
81*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
82*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
83*8fb009dcSAndroid Build Coastguard Worker
84*8fb009dcSAndroid Build Coastguard Worker #include "../internal.h"
85*8fb009dcSAndroid Build Coastguard Worker
86*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_WINDOWS)
87*8fb009dcSAndroid Build Coastguard Worker #include <fcntl.h>
88*8fb009dcSAndroid Build Coastguard Worker #include <io.h>
89*8fb009dcSAndroid Build Coastguard Worker #endif
90*8fb009dcSAndroid Build Coastguard Worker
91*8fb009dcSAndroid Build Coastguard Worker #define BIO_FP_READ 0x02
92*8fb009dcSAndroid Build Coastguard Worker #define BIO_FP_WRITE 0x04
93*8fb009dcSAndroid Build Coastguard Worker #define BIO_FP_APPEND 0x08
94*8fb009dcSAndroid Build Coastguard Worker
95*8fb009dcSAndroid Build Coastguard Worker #if !defined(OPENSSL_NO_FILESYSTEM)
96*8fb009dcSAndroid Build Coastguard Worker #define fopen_if_available fopen
97*8fb009dcSAndroid Build Coastguard Worker #else
fopen_if_available(const char * path,const char * mode)98*8fb009dcSAndroid Build Coastguard Worker static FILE *fopen_if_available(const char *path, const char *mode) {
99*8fb009dcSAndroid Build Coastguard Worker errno = ENOENT;
100*8fb009dcSAndroid Build Coastguard Worker return NULL;
101*8fb009dcSAndroid Build Coastguard Worker }
102*8fb009dcSAndroid Build Coastguard Worker #endif
103*8fb009dcSAndroid Build Coastguard Worker
BIO_new_file(const char * filename,const char * mode)104*8fb009dcSAndroid Build Coastguard Worker BIO *BIO_new_file(const char *filename, const char *mode) {
105*8fb009dcSAndroid Build Coastguard Worker BIO *ret;
106*8fb009dcSAndroid Build Coastguard Worker FILE *file;
107*8fb009dcSAndroid Build Coastguard Worker
108*8fb009dcSAndroid Build Coastguard Worker file = fopen_if_available(filename, mode);
109*8fb009dcSAndroid Build Coastguard Worker if (file == NULL) {
110*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_SYSTEM_ERROR();
111*8fb009dcSAndroid Build Coastguard Worker
112*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
113*8fb009dcSAndroid Build Coastguard Worker if (errno == ENOENT) {
114*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE);
115*8fb009dcSAndroid Build Coastguard Worker } else {
116*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB);
117*8fb009dcSAndroid Build Coastguard Worker }
118*8fb009dcSAndroid Build Coastguard Worker return NULL;
119*8fb009dcSAndroid Build Coastguard Worker }
120*8fb009dcSAndroid Build Coastguard Worker
121*8fb009dcSAndroid Build Coastguard Worker ret = BIO_new_fp(file, BIO_CLOSE);
122*8fb009dcSAndroid Build Coastguard Worker if (ret == NULL) {
123*8fb009dcSAndroid Build Coastguard Worker fclose(file);
124*8fb009dcSAndroid Build Coastguard Worker return NULL;
125*8fb009dcSAndroid Build Coastguard Worker }
126*8fb009dcSAndroid Build Coastguard Worker
127*8fb009dcSAndroid Build Coastguard Worker return ret;
128*8fb009dcSAndroid Build Coastguard Worker }
129*8fb009dcSAndroid Build Coastguard Worker
BIO_new_fp(FILE * stream,int flags)130*8fb009dcSAndroid Build Coastguard Worker BIO *BIO_new_fp(FILE *stream, int flags) {
131*8fb009dcSAndroid Build Coastguard Worker BIO *ret = BIO_new(BIO_s_file());
132*8fb009dcSAndroid Build Coastguard Worker if (ret == NULL) {
133*8fb009dcSAndroid Build Coastguard Worker return NULL;
134*8fb009dcSAndroid Build Coastguard Worker }
135*8fb009dcSAndroid Build Coastguard Worker
136*8fb009dcSAndroid Build Coastguard Worker BIO_set_fp(ret, stream, flags);
137*8fb009dcSAndroid Build Coastguard Worker return ret;
138*8fb009dcSAndroid Build Coastguard Worker }
139*8fb009dcSAndroid Build Coastguard Worker
file_free(BIO * bio)140*8fb009dcSAndroid Build Coastguard Worker static int file_free(BIO *bio) {
141*8fb009dcSAndroid Build Coastguard Worker if (!bio->shutdown) {
142*8fb009dcSAndroid Build Coastguard Worker return 1;
143*8fb009dcSAndroid Build Coastguard Worker }
144*8fb009dcSAndroid Build Coastguard Worker
145*8fb009dcSAndroid Build Coastguard Worker if (bio->init && bio->ptr != NULL) {
146*8fb009dcSAndroid Build Coastguard Worker fclose(bio->ptr);
147*8fb009dcSAndroid Build Coastguard Worker bio->ptr = NULL;
148*8fb009dcSAndroid Build Coastguard Worker }
149*8fb009dcSAndroid Build Coastguard Worker bio->init = 0;
150*8fb009dcSAndroid Build Coastguard Worker
151*8fb009dcSAndroid Build Coastguard Worker return 1;
152*8fb009dcSAndroid Build Coastguard Worker }
153*8fb009dcSAndroid Build Coastguard Worker
file_read(BIO * b,char * out,int outl)154*8fb009dcSAndroid Build Coastguard Worker static int file_read(BIO *b, char *out, int outl) {
155*8fb009dcSAndroid Build Coastguard Worker if (!b->init) {
156*8fb009dcSAndroid Build Coastguard Worker return 0;
157*8fb009dcSAndroid Build Coastguard Worker }
158*8fb009dcSAndroid Build Coastguard Worker
159*8fb009dcSAndroid Build Coastguard Worker size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
160*8fb009dcSAndroid Build Coastguard Worker if (ret == 0 && ferror((FILE *)b->ptr)) {
161*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_SYSTEM_ERROR();
162*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
163*8fb009dcSAndroid Build Coastguard Worker return -1;
164*8fb009dcSAndroid Build Coastguard Worker }
165*8fb009dcSAndroid Build Coastguard Worker
166*8fb009dcSAndroid Build Coastguard Worker // fread reads at most |outl| bytes, so |ret| fits in an int.
167*8fb009dcSAndroid Build Coastguard Worker return (int)ret;
168*8fb009dcSAndroid Build Coastguard Worker }
169*8fb009dcSAndroid Build Coastguard Worker
file_write(BIO * b,const char * in,int inl)170*8fb009dcSAndroid Build Coastguard Worker static int file_write(BIO *b, const char *in, int inl) {
171*8fb009dcSAndroid Build Coastguard Worker if (!b->init) {
172*8fb009dcSAndroid Build Coastguard Worker return 0;
173*8fb009dcSAndroid Build Coastguard Worker }
174*8fb009dcSAndroid Build Coastguard Worker
175*8fb009dcSAndroid Build Coastguard Worker int ret = (int)fwrite(in, inl, 1, (FILE *)b->ptr);
176*8fb009dcSAndroid Build Coastguard Worker if (ret > 0) {
177*8fb009dcSAndroid Build Coastguard Worker ret = inl;
178*8fb009dcSAndroid Build Coastguard Worker }
179*8fb009dcSAndroid Build Coastguard Worker return ret;
180*8fb009dcSAndroid Build Coastguard Worker }
181*8fb009dcSAndroid Build Coastguard Worker
file_ctrl(BIO * b,int cmd,long num,void * ptr)182*8fb009dcSAndroid Build Coastguard Worker static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
183*8fb009dcSAndroid Build Coastguard Worker long ret = 1;
184*8fb009dcSAndroid Build Coastguard Worker FILE *fp = (FILE *)b->ptr;
185*8fb009dcSAndroid Build Coastguard Worker FILE **fpp;
186*8fb009dcSAndroid Build Coastguard Worker
187*8fb009dcSAndroid Build Coastguard Worker switch (cmd) {
188*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_RESET:
189*8fb009dcSAndroid Build Coastguard Worker num = 0;
190*8fb009dcSAndroid Build Coastguard Worker OPENSSL_FALLTHROUGH;
191*8fb009dcSAndroid Build Coastguard Worker case BIO_C_FILE_SEEK:
192*8fb009dcSAndroid Build Coastguard Worker ret = (long)fseek(fp, num, 0);
193*8fb009dcSAndroid Build Coastguard Worker break;
194*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_EOF:
195*8fb009dcSAndroid Build Coastguard Worker ret = (long)feof(fp);
196*8fb009dcSAndroid Build Coastguard Worker break;
197*8fb009dcSAndroid Build Coastguard Worker case BIO_C_FILE_TELL:
198*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_INFO:
199*8fb009dcSAndroid Build Coastguard Worker ret = ftell(fp);
200*8fb009dcSAndroid Build Coastguard Worker break;
201*8fb009dcSAndroid Build Coastguard Worker case BIO_C_SET_FILE_PTR:
202*8fb009dcSAndroid Build Coastguard Worker file_free(b);
203*8fb009dcSAndroid Build Coastguard Worker static_assert((BIO_CLOSE & BIO_FP_TEXT) == 0,
204*8fb009dcSAndroid Build Coastguard Worker "BIO_CLOSE and BIO_FP_TEXT must not collide");
205*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_WINDOWS)
206*8fb009dcSAndroid Build Coastguard Worker // If |BIO_FP_TEXT| is not set, OpenSSL will switch the file to binary
207*8fb009dcSAndroid Build Coastguard Worker // mode. BoringSSL intentionally diverges here because it means code
208*8fb009dcSAndroid Build Coastguard Worker // tested under POSIX will inadvertently change the state of |FILE|
209*8fb009dcSAndroid Build Coastguard Worker // objects when wrapping them in a |BIO|.
210*8fb009dcSAndroid Build Coastguard Worker if (num & BIO_FP_TEXT) {
211*8fb009dcSAndroid Build Coastguard Worker _setmode(_fileno(ptr), _O_TEXT);
212*8fb009dcSAndroid Build Coastguard Worker }
213*8fb009dcSAndroid Build Coastguard Worker #endif
214*8fb009dcSAndroid Build Coastguard Worker b->shutdown = (int)num & BIO_CLOSE;
215*8fb009dcSAndroid Build Coastguard Worker b->ptr = ptr;
216*8fb009dcSAndroid Build Coastguard Worker b->init = 1;
217*8fb009dcSAndroid Build Coastguard Worker break;
218*8fb009dcSAndroid Build Coastguard Worker case BIO_C_SET_FILENAME:
219*8fb009dcSAndroid Build Coastguard Worker file_free(b);
220*8fb009dcSAndroid Build Coastguard Worker b->shutdown = (int)num & BIO_CLOSE;
221*8fb009dcSAndroid Build Coastguard Worker const char *mode;
222*8fb009dcSAndroid Build Coastguard Worker if (num & BIO_FP_APPEND) {
223*8fb009dcSAndroid Build Coastguard Worker if (num & BIO_FP_READ) {
224*8fb009dcSAndroid Build Coastguard Worker mode = "ab+";
225*8fb009dcSAndroid Build Coastguard Worker } else {
226*8fb009dcSAndroid Build Coastguard Worker mode = "ab";
227*8fb009dcSAndroid Build Coastguard Worker }
228*8fb009dcSAndroid Build Coastguard Worker } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) {
229*8fb009dcSAndroid Build Coastguard Worker mode = "rb+";
230*8fb009dcSAndroid Build Coastguard Worker } else if (num & BIO_FP_WRITE) {
231*8fb009dcSAndroid Build Coastguard Worker mode = "wb";
232*8fb009dcSAndroid Build Coastguard Worker } else if (num & BIO_FP_READ) {
233*8fb009dcSAndroid Build Coastguard Worker mode = "rb";
234*8fb009dcSAndroid Build Coastguard Worker } else {
235*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
236*8fb009dcSAndroid Build Coastguard Worker ret = 0;
237*8fb009dcSAndroid Build Coastguard Worker break;
238*8fb009dcSAndroid Build Coastguard Worker }
239*8fb009dcSAndroid Build Coastguard Worker fp = fopen_if_available(ptr, mode);
240*8fb009dcSAndroid Build Coastguard Worker if (fp == NULL) {
241*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_SYSTEM_ERROR();
242*8fb009dcSAndroid Build Coastguard Worker ERR_add_error_data(5, "fopen('", ptr, "','", mode, "')");
243*8fb009dcSAndroid Build Coastguard Worker OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
244*8fb009dcSAndroid Build Coastguard Worker ret = 0;
245*8fb009dcSAndroid Build Coastguard Worker break;
246*8fb009dcSAndroid Build Coastguard Worker }
247*8fb009dcSAndroid Build Coastguard Worker b->ptr = fp;
248*8fb009dcSAndroid Build Coastguard Worker b->init = 1;
249*8fb009dcSAndroid Build Coastguard Worker break;
250*8fb009dcSAndroid Build Coastguard Worker case BIO_C_GET_FILE_PTR:
251*8fb009dcSAndroid Build Coastguard Worker // the ptr parameter is actually a FILE ** in this case.
252*8fb009dcSAndroid Build Coastguard Worker if (ptr != NULL) {
253*8fb009dcSAndroid Build Coastguard Worker fpp = (FILE **)ptr;
254*8fb009dcSAndroid Build Coastguard Worker *fpp = (FILE *)b->ptr;
255*8fb009dcSAndroid Build Coastguard Worker }
256*8fb009dcSAndroid Build Coastguard Worker break;
257*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_GET_CLOSE:
258*8fb009dcSAndroid Build Coastguard Worker ret = (long)b->shutdown;
259*8fb009dcSAndroid Build Coastguard Worker break;
260*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_SET_CLOSE:
261*8fb009dcSAndroid Build Coastguard Worker b->shutdown = (int)num;
262*8fb009dcSAndroid Build Coastguard Worker break;
263*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_FLUSH:
264*8fb009dcSAndroid Build Coastguard Worker ret = 0 == fflush((FILE *)b->ptr);
265*8fb009dcSAndroid Build Coastguard Worker break;
266*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_WPENDING:
267*8fb009dcSAndroid Build Coastguard Worker case BIO_CTRL_PENDING:
268*8fb009dcSAndroid Build Coastguard Worker default:
269*8fb009dcSAndroid Build Coastguard Worker ret = 0;
270*8fb009dcSAndroid Build Coastguard Worker break;
271*8fb009dcSAndroid Build Coastguard Worker }
272*8fb009dcSAndroid Build Coastguard Worker return ret;
273*8fb009dcSAndroid Build Coastguard Worker }
274*8fb009dcSAndroid Build Coastguard Worker
file_gets(BIO * bp,char * buf,int size)275*8fb009dcSAndroid Build Coastguard Worker static int file_gets(BIO *bp, char *buf, int size) {
276*8fb009dcSAndroid Build Coastguard Worker if (size == 0) {
277*8fb009dcSAndroid Build Coastguard Worker return 0;
278*8fb009dcSAndroid Build Coastguard Worker }
279*8fb009dcSAndroid Build Coastguard Worker
280*8fb009dcSAndroid Build Coastguard Worker if (!fgets(buf, size, (FILE *)bp->ptr)) {
281*8fb009dcSAndroid Build Coastguard Worker buf[0] = 0;
282*8fb009dcSAndroid Build Coastguard Worker // TODO(davidben): This doesn't distinguish error and EOF. This should check
283*8fb009dcSAndroid Build Coastguard Worker // |ferror| as in |file_read|.
284*8fb009dcSAndroid Build Coastguard Worker return 0;
285*8fb009dcSAndroid Build Coastguard Worker }
286*8fb009dcSAndroid Build Coastguard Worker
287*8fb009dcSAndroid Build Coastguard Worker return (int)strlen(buf);
288*8fb009dcSAndroid Build Coastguard Worker }
289*8fb009dcSAndroid Build Coastguard Worker
290*8fb009dcSAndroid Build Coastguard Worker static const BIO_METHOD methods_filep = {
291*8fb009dcSAndroid Build Coastguard Worker BIO_TYPE_FILE, "FILE pointer",
292*8fb009dcSAndroid Build Coastguard Worker file_write, file_read,
293*8fb009dcSAndroid Build Coastguard Worker NULL /* puts */, file_gets,
294*8fb009dcSAndroid Build Coastguard Worker file_ctrl, NULL /* create */,
295*8fb009dcSAndroid Build Coastguard Worker file_free, NULL /* callback_ctrl */,
296*8fb009dcSAndroid Build Coastguard Worker };
297*8fb009dcSAndroid Build Coastguard Worker
BIO_s_file(void)298*8fb009dcSAndroid Build Coastguard Worker const BIO_METHOD *BIO_s_file(void) { return &methods_filep; }
299*8fb009dcSAndroid Build Coastguard Worker
300*8fb009dcSAndroid Build Coastguard Worker
BIO_get_fp(BIO * bio,FILE ** out_file)301*8fb009dcSAndroid Build Coastguard Worker int BIO_get_fp(BIO *bio, FILE **out_file) {
302*8fb009dcSAndroid Build Coastguard Worker return (int)BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char *)out_file);
303*8fb009dcSAndroid Build Coastguard Worker }
304*8fb009dcSAndroid Build Coastguard Worker
BIO_set_fp(BIO * bio,FILE * file,int flags)305*8fb009dcSAndroid Build Coastguard Worker int BIO_set_fp(BIO *bio, FILE *file, int flags) {
306*8fb009dcSAndroid Build Coastguard Worker return (int)BIO_ctrl(bio, BIO_C_SET_FILE_PTR, flags, (char *)file);
307*8fb009dcSAndroid Build Coastguard Worker }
308*8fb009dcSAndroid Build Coastguard Worker
BIO_read_filename(BIO * bio,const char * filename)309*8fb009dcSAndroid Build Coastguard Worker int BIO_read_filename(BIO *bio, const char *filename) {
310*8fb009dcSAndroid Build Coastguard Worker return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ,
311*8fb009dcSAndroid Build Coastguard Worker (char *)filename);
312*8fb009dcSAndroid Build Coastguard Worker }
313*8fb009dcSAndroid Build Coastguard Worker
BIO_write_filename(BIO * bio,const char * filename)314*8fb009dcSAndroid Build Coastguard Worker int BIO_write_filename(BIO *bio, const char *filename) {
315*8fb009dcSAndroid Build Coastguard Worker return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE,
316*8fb009dcSAndroid Build Coastguard Worker (char *)filename);
317*8fb009dcSAndroid Build Coastguard Worker }
318*8fb009dcSAndroid Build Coastguard Worker
BIO_append_filename(BIO * bio,const char * filename)319*8fb009dcSAndroid Build Coastguard Worker int BIO_append_filename(BIO *bio, const char *filename) {
320*8fb009dcSAndroid Build Coastguard Worker return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND,
321*8fb009dcSAndroid Build Coastguard Worker (char *)filename);
322*8fb009dcSAndroid Build Coastguard Worker }
323*8fb009dcSAndroid Build Coastguard Worker
BIO_rw_filename(BIO * bio,const char * filename)324*8fb009dcSAndroid Build Coastguard Worker int BIO_rw_filename(BIO *bio, const char *filename) {
325*8fb009dcSAndroid Build Coastguard Worker return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME,
326*8fb009dcSAndroid Build Coastguard Worker BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE,
327*8fb009dcSAndroid Build Coastguard Worker (char *)filename);
328*8fb009dcSAndroid Build Coastguard Worker }
329*8fb009dcSAndroid Build Coastguard Worker
BIO_tell(BIO * bio)330*8fb009dcSAndroid Build Coastguard Worker long BIO_tell(BIO *bio) { return BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL); }
331*8fb009dcSAndroid Build Coastguard Worker
BIO_seek(BIO * bio,long offset)332*8fb009dcSAndroid Build Coastguard Worker long BIO_seek(BIO *bio, long offset) {
333*8fb009dcSAndroid Build Coastguard Worker return BIO_ctrl(bio, BIO_C_FILE_SEEK, offset, NULL);
334*8fb009dcSAndroid Build Coastguard Worker }
335