/src/openssl30/crypto/bio/bss_file.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the Apache License 2.0 (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 |  | #if defined(__linux) || defined(__sun) || defined(__hpux) | 
| 11 |  | /* | 
| 12 |  |  * Following definition aliases fopen to fopen64 on above mentioned | 
| 13 |  |  * platforms. This makes it possible to open and sequentially access files | 
| 14 |  |  * larger than 2GB from 32-bit application. It does not allow to traverse | 
| 15 |  |  * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit | 
| 16 |  |  * platform permits that, not with fseek/ftell. Not to mention that breaking | 
| 17 |  |  * 2GB limit for seeking would require surgery to *our* API. But sequential | 
| 18 |  |  * access suffices for practical cases when you can run into large files, | 
| 19 |  |  * such as fingerprinting, so we can let API alone. For reference, the list | 
| 20 |  |  * of 32-bit platforms which allow for sequential access of large files | 
| 21 |  |  * without extra "magic" comprise *BSD, Darwin, IRIX... | 
| 22 |  |  */ | 
| 23 |  | # ifndef _FILE_OFFSET_BITS | 
| 24 |  | #  define _FILE_OFFSET_BITS 64 | 
| 25 |  | # endif | 
| 26 |  | #endif | 
| 27 |  |  | 
| 28 |  | #include <stdio.h> | 
| 29 |  | #include <errno.h> | 
| 30 |  | #include "bio_local.h" | 
| 31 |  | #include <openssl/err.h> | 
| 32 |  |  | 
| 33 |  | #if !defined(OPENSSL_NO_STDIO) | 
| 34 |  |  | 
| 35 |  | static int file_write(BIO *h, const char *buf, int num); | 
| 36 |  | static int file_read(BIO *h, char *buf, int size); | 
| 37 |  | static int file_puts(BIO *h, const char *str); | 
| 38 |  | static int file_gets(BIO *h, char *str, int size); | 
| 39 |  | static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2); | 
| 40 |  | static int file_new(BIO *h); | 
| 41 |  | static int file_free(BIO *data); | 
| 42 |  | static const BIO_METHOD methods_filep = { | 
| 43 |  |     BIO_TYPE_FILE, | 
| 44 |  |     "FILE pointer", | 
| 45 |  |     bwrite_conv, | 
| 46 |  |     file_write, | 
| 47 |  |     bread_conv, | 
| 48 |  |     file_read, | 
| 49 |  |     file_puts, | 
| 50 |  |     file_gets, | 
| 51 |  |     file_ctrl, | 
| 52 |  |     file_new, | 
| 53 |  |     file_free, | 
| 54 |  |     NULL,                      /* file_callback_ctrl */ | 
| 55 |  | }; | 
| 56 |  |  | 
| 57 |  | BIO *BIO_new_file(const char *filename, const char *mode) | 
| 58 | 105k | { | 
| 59 | 105k |     BIO  *ret; | 
| 60 | 105k |     FILE *file = openssl_fopen(filename, mode); | 
| 61 | 105k |     int fp_flags = BIO_CLOSE; | 
| 62 |  |  | 
| 63 | 105k |     if (strchr(mode, 'b') == NULL) | 
| 64 | 105k |         fp_flags |= BIO_FP_TEXT; | 
| 65 |  |  | 
| 66 | 105k |     if (file == NULL) { | 
| 67 | 91.9k |         ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), | 
| 68 | 91.9k |                        "calling fopen(%s, %s)", | 
| 69 | 91.9k |                        filename, mode); | 
| 70 | 91.9k |         if (errno == ENOENT | 
| 71 | 91.9k | #ifdef ENXIO | 
| 72 | 91.9k |             || errno == ENXIO | 
| 73 | 91.9k | #endif | 
| 74 | 91.9k |             ) | 
| 75 | 91.9k |             ERR_raise(ERR_LIB_BIO, BIO_R_NO_SUCH_FILE); | 
| 76 | 91.9k |         else | 
| 77 | 91.9k |             ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); | 
| 78 | 91.9k |         return NULL; | 
| 79 | 91.9k |     } | 
| 80 | 14.0k |     if ((ret = BIO_new(BIO_s_file())) == NULL) { | 
| 81 | 0 |         fclose(file); | 
| 82 | 0 |         return NULL; | 
| 83 | 0 |     } | 
| 84 |  |  | 
| 85 |  |     /* we did fopen -> we disengage UPLINK */ | 
| 86 | 14.0k |     BIO_clear_flags(ret, BIO_FLAGS_UPLINK_INTERNAL); | 
| 87 | 14.0k |     BIO_set_fp(ret, file, fp_flags); | 
| 88 | 14.0k |     return ret; | 
| 89 | 14.0k | } | 
| 90 |  |  | 
| 91 |  | BIO *BIO_new_fp(FILE *stream, int close_flag) | 
| 92 | 32.5k | { | 
| 93 | 32.5k |     BIO *ret; | 
| 94 |  |  | 
| 95 | 32.5k |     if ((ret = BIO_new(BIO_s_file())) == NULL) | 
| 96 | 0 |         return NULL; | 
| 97 |  |  | 
| 98 |  |     /* redundant flag, left for documentation purposes */ | 
| 99 | 32.5k |     BIO_set_flags(ret, BIO_FLAGS_UPLINK_INTERNAL); | 
| 100 | 32.5k |     BIO_set_fp(ret, stream, close_flag); | 
| 101 | 32.5k |     return ret; | 
| 102 | 32.5k | } | 
| 103 |  |  | 
| 104 |  | const BIO_METHOD *BIO_s_file(void) | 
| 105 | 46.5k | { | 
| 106 | 46.5k |     return &methods_filep; | 
| 107 | 46.5k | } | 
| 108 |  |  | 
| 109 |  | static int file_new(BIO *bi) | 
| 110 | 46.5k | { | 
| 111 | 46.5k |     bi->init = 0; | 
| 112 | 46.5k |     bi->num = 0; | 
| 113 | 46.5k |     bi->ptr = NULL; | 
| 114 | 46.5k |     bi->flags = BIO_FLAGS_UPLINK_INTERNAL; /* default to UPLINK */ | 
| 115 | 46.5k |     return 1; | 
| 116 | 46.5k | } | 
| 117 |  |  | 
| 118 |  | static int file_free(BIO *a) | 
| 119 | 93.1k | { | 
| 120 | 93.1k |     if (a == NULL) | 
| 121 | 0 |         return 0; | 
| 122 | 93.1k |     if (a->shutdown) { | 
| 123 | 60.6k |         if ((a->init) && (a->ptr != NULL)) { | 
| 124 | 14.0k |             if (a->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 125 | 0 |                 UP_fclose(a->ptr); | 
| 126 | 14.0k |             else | 
| 127 | 14.0k |                 fclose(a->ptr); | 
| 128 | 14.0k |             a->ptr = NULL; | 
| 129 | 14.0k |             a->flags = BIO_FLAGS_UPLINK_INTERNAL; | 
| 130 | 14.0k |         } | 
| 131 | 60.6k |         a->init = 0; | 
| 132 | 60.6k |     } | 
| 133 | 93.1k |     return 1; | 
| 134 | 93.1k | } | 
| 135 |  |  | 
| 136 |  | static int file_read(BIO *b, char *out, int outl) | 
| 137 | 0 | { | 
| 138 | 0 |     int ret = 0; | 
| 139 |  | 
 | 
| 140 | 0 |     if (b->init && (out != NULL)) { | 
| 141 | 0 |         if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 142 | 0 |             ret = UP_fread(out, 1, (int)outl, b->ptr); | 
| 143 | 0 |         else | 
| 144 | 0 |             ret = fread(out, 1, (int)outl, (FILE *)b->ptr); | 
| 145 | 0 |         if (ret == 0 | 
| 146 | 0 |             && (b->flags & BIO_FLAGS_UPLINK_INTERNAL | 
| 147 | 0 |                 ? UP_ferror((FILE *)b->ptr) : ferror((FILE *)b->ptr))) { | 
| 148 | 0 |             ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), | 
| 149 | 0 |                            "calling fread()"); | 
| 150 | 0 |             ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); | 
| 151 | 0 |             ret = -1; | 
| 152 | 0 |         } | 
| 153 | 0 |     } | 
| 154 | 0 |     return ret; | 
| 155 | 0 | } | 
| 156 |  |  | 
| 157 |  | static int file_write(BIO *b, const char *in, int inl) | 
| 158 | 13.3M | { | 
| 159 | 13.3M |     int ret = 0; | 
| 160 |  |  | 
| 161 | 13.3M |     if (b->init && (in != NULL)) { | 
| 162 | 13.3M |         if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 163 | 0 |             ret = UP_fwrite(in, (int)inl, 1, b->ptr); | 
| 164 | 13.3M |         else | 
| 165 | 13.3M |             ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); | 
| 166 | 13.3M |         if (ret) | 
| 167 | 13.3M |             ret = inl; | 
| 168 |  |         /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ | 
| 169 |  |         /* | 
| 170 |  |          * according to Tim Hudson <tjh@openssl.org>, the commented out | 
| 171 |  |          * version above can cause 'inl' write calls under some stupid stdio | 
| 172 |  |          * implementations (VMS) | 
| 173 |  |          */ | 
| 174 | 13.3M |     } | 
| 175 | 13.3M |     return ret; | 
| 176 | 13.3M | } | 
| 177 |  |  | 
| 178 |  | static long file_ctrl(BIO *b, int cmd, long num, void *ptr) | 
| 179 | 46.5k | { | 
| 180 | 46.5k |     long ret = 1; | 
| 181 | 46.5k |     FILE *fp = (FILE *)b->ptr; | 
| 182 | 46.5k |     FILE **fpp; | 
| 183 | 46.5k |     char p[4]; | 
| 184 | 46.5k |     int st; | 
| 185 |  |  | 
| 186 | 46.5k |     switch (cmd) { | 
| 187 | 0 |     case BIO_C_FILE_SEEK: | 
| 188 | 0 |     case BIO_CTRL_RESET: | 
| 189 | 0 |         if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 190 | 0 |             ret = (long)UP_fseek(b->ptr, num, 0); | 
| 191 | 0 |         else | 
| 192 | 0 |             ret = (long)fseek(fp, num, 0); | 
| 193 | 0 |         break; | 
| 194 | 0 |     case BIO_CTRL_EOF: | 
| 195 | 0 |         if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 196 | 0 |             ret = (long)UP_feof(fp); | 
| 197 | 0 |         else | 
| 198 | 0 |             ret = (long)feof(fp); | 
| 199 | 0 |         break; | 
| 200 | 0 |     case BIO_C_FILE_TELL: | 
| 201 | 0 |     case BIO_CTRL_INFO: | 
| 202 | 0 |         if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 203 | 0 |             ret = UP_ftell(b->ptr); | 
| 204 | 0 |         else | 
| 205 | 0 |             ret = ftell(fp); | 
| 206 | 0 |         break; | 
| 207 | 46.5k |     case BIO_C_SET_FILE_PTR: | 
| 208 | 46.5k |         file_free(b); | 
| 209 | 46.5k |         b->shutdown = (int)num & BIO_CLOSE; | 
| 210 | 46.5k |         b->ptr = ptr; | 
| 211 | 46.5k |         b->init = 1; | 
| 212 |  | # if BIO_FLAGS_UPLINK_INTERNAL!=0 | 
| 213 |  | #  if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) | 
| 214 |  | #   define _IOB_ENTRIES 20 | 
| 215 |  | #  endif | 
| 216 |  |         /* Safety net to catch purely internal BIO_set_fp calls */ | 
| 217 |  | #  if (defined(_MSC_VER) && _MSC_VER>=1900) || defined(__BORLANDC__) | 
| 218 |  |         if (ptr == stdin || ptr == stdout || ptr == stderr) | 
| 219 |  |             BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); | 
| 220 |  | #  elif defined(_IOB_ENTRIES) | 
| 221 |  |         if ((size_t)ptr >= (size_t)stdin && | 
| 222 |  |             (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) | 
| 223 |  |             BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); | 
| 224 |  | #  endif | 
| 225 |  | # endif | 
| 226 |  | # ifdef UP_fsetmod | 
| 227 |  |         if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) | 
| 228 |  |             UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); | 
| 229 |  |         else | 
| 230 |  | # endif | 
| 231 | 46.5k |         { | 
| 232 |  | # if defined(OPENSSL_SYS_WINDOWS) | 
| 233 |  |             int fd = _fileno((FILE *)ptr); | 
| 234 |  |             if (num & BIO_FP_TEXT) | 
| 235 |  |                 _setmode(fd, _O_TEXT); | 
| 236 |  |             else | 
| 237 |  |                 _setmode(fd, _O_BINARY); | 
| 238 |  |             /* | 
| 239 |  |              * Reports show that ftell() isn't trustable in text mode. | 
| 240 |  |              * This has been confirmed as a bug in the Universal C RTL, see | 
| 241 |  |              * https://developercommunity.visualstudio.com/content/problem/425878/fseek-ftell-fail-in-text-mode-for-unix-style-text.html | 
| 242 |  |              * The suggested work-around from Microsoft engineering is to | 
| 243 |  |              * turn off buffering until the bug is resolved. | 
| 244 |  |              */ | 
| 245 |  |             if ((num & BIO_FP_TEXT) != 0) | 
| 246 |  |                 setvbuf((FILE *)ptr, NULL, _IONBF, 0); | 
| 247 |  | # elif defined(OPENSSL_SYS_MSDOS) | 
| 248 |  |             int fd = fileno((FILE *)ptr); | 
| 249 |  |             /* Set correct text/binary mode */ | 
| 250 |  |             if (num & BIO_FP_TEXT) | 
| 251 |  |                 _setmode(fd, _O_TEXT); | 
| 252 |  |             /* Dangerous to set stdin/stdout to raw (unless redirected) */ | 
| 253 |  |             else { | 
| 254 |  |                 if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { | 
| 255 |  |                     if (isatty(fd) <= 0) | 
| 256 |  |                         _setmode(fd, _O_BINARY); | 
| 257 |  |                 } else | 
| 258 |  |                     _setmode(fd, _O_BINARY); | 
| 259 |  |             } | 
| 260 |  | # elif defined(OPENSSL_SYS_WIN32_CYGWIN) | 
| 261 |  |             int fd = fileno((FILE *)ptr); | 
| 262 |  |             if (!(num & BIO_FP_TEXT)) | 
| 263 |  |                 setmode(fd, O_BINARY); | 
| 264 |  | # endif | 
| 265 | 46.5k |         } | 
| 266 | 46.5k |         break; | 
| 267 | 0 |     case BIO_C_SET_FILENAME: | 
| 268 | 0 |         file_free(b); | 
| 269 | 0 |         b->shutdown = (int)num & BIO_CLOSE; | 
| 270 | 0 |         if (num & BIO_FP_APPEND) { | 
| 271 | 0 |             if (num & BIO_FP_READ) | 
| 272 | 0 |                 OPENSSL_strlcpy(p, "a+", sizeof(p)); | 
| 273 | 0 |             else | 
| 274 | 0 |                 OPENSSL_strlcpy(p, "a", sizeof(p)); | 
| 275 | 0 |         } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) | 
| 276 | 0 |             OPENSSL_strlcpy(p, "r+", sizeof(p)); | 
| 277 | 0 |         else if (num & BIO_FP_WRITE) | 
| 278 | 0 |             OPENSSL_strlcpy(p, "w", sizeof(p)); | 
| 279 | 0 |         else if (num & BIO_FP_READ) | 
| 280 | 0 |             OPENSSL_strlcpy(p, "r", sizeof(p)); | 
| 281 | 0 |         else { | 
| 282 | 0 |             ERR_raise(ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE); | 
| 283 | 0 |             ret = 0; | 
| 284 | 0 |             break; | 
| 285 | 0 |         } | 
| 286 |  | # if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) | 
| 287 |  |         if (!(num & BIO_FP_TEXT)) | 
| 288 |  |             OPENSSL_strlcat(p, "b", sizeof(p)); | 
| 289 |  |         else | 
| 290 |  |             OPENSSL_strlcat(p, "t", sizeof(p)); | 
| 291 |  | # elif defined(OPENSSL_SYS_WIN32_CYGWIN) | 
| 292 |  |         if (!(num & BIO_FP_TEXT)) | 
| 293 |  |             OPENSSL_strlcat(p, "b", sizeof(p)); | 
| 294 |  | # endif | 
| 295 | 0 |         fp = openssl_fopen(ptr, p); | 
| 296 | 0 |         if (fp == NULL) { | 
| 297 | 0 |             ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), | 
| 298 | 0 |                            "calling fopen(%s, %s)", | 
| 299 | 0 |                            ptr, p); | 
| 300 | 0 |             ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); | 
| 301 | 0 |             ret = 0; | 
| 302 | 0 |             break; | 
| 303 | 0 |         } | 
| 304 | 0 |         b->ptr = fp; | 
| 305 | 0 |         b->init = 1; | 
| 306 |  |         /* we did fopen -> we disengage UPLINK */ | 
| 307 | 0 |         BIO_clear_flags(b, BIO_FLAGS_UPLINK_INTERNAL); | 
| 308 | 0 |         break; | 
| 309 | 0 |     case BIO_C_GET_FILE_PTR: | 
| 310 |  |         /* the ptr parameter is actually a FILE ** in this case. */ | 
| 311 | 0 |         if (ptr != NULL) { | 
| 312 | 0 |             fpp = (FILE **)ptr; | 
| 313 | 0 |             *fpp = (FILE *)b->ptr; | 
| 314 | 0 |         } | 
| 315 | 0 |         break; | 
| 316 | 0 |     case BIO_CTRL_GET_CLOSE: | 
| 317 | 0 |         ret = (long)b->shutdown; | 
| 318 | 0 |         break; | 
| 319 | 0 |     case BIO_CTRL_SET_CLOSE: | 
| 320 | 0 |         b->shutdown = (int)num; | 
| 321 | 0 |         break; | 
| 322 | 0 |     case BIO_CTRL_FLUSH: | 
| 323 | 0 |         st = b->flags & BIO_FLAGS_UPLINK_INTERNAL | 
| 324 | 0 |                 ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); | 
| 325 | 0 |         if (st == EOF) { | 
| 326 | 0 |             ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), | 
| 327 | 0 |                            "calling fflush()"); | 
| 328 | 0 |             ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB); | 
| 329 | 0 |             ret = 0; | 
| 330 | 0 |         } | 
| 331 | 0 |         break; | 
| 332 | 0 |     case BIO_CTRL_DUP: | 
| 333 | 0 |         ret = 1; | 
| 334 | 0 |         break; | 
| 335 |  |  | 
| 336 | 0 |     case BIO_CTRL_WPENDING: | 
| 337 | 0 |     case BIO_CTRL_PENDING: | 
| 338 | 0 |     case BIO_CTRL_PUSH: | 
| 339 | 0 |     case BIO_CTRL_POP: | 
| 340 | 0 |     default: | 
| 341 | 0 |         ret = 0; | 
| 342 | 0 |         break; | 
| 343 | 46.5k |     } | 
| 344 | 46.5k |     return ret; | 
| 345 | 46.5k | } | 
| 346 |  |  | 
| 347 |  | static int file_gets(BIO *bp, char *buf, int size) | 
| 348 | 573k | { | 
| 349 | 573k |     int ret = 0; | 
| 350 |  |  | 
| 351 | 573k |     buf[0] = '\0'; | 
| 352 | 573k |     if (bp->flags & BIO_FLAGS_UPLINK_INTERNAL) { | 
| 353 | 0 |         if (!UP_fgets(buf, size, bp->ptr)) | 
| 354 | 0 |             goto err; | 
| 355 | 573k |     } else { | 
| 356 | 573k |         if (!fgets(buf, size, (FILE *)bp->ptr)) | 
| 357 | 13.8k |             goto err; | 
| 358 | 573k |     } | 
| 359 | 559k |     if (buf[0] != '\0') | 
| 360 | 559k |         ret = strlen(buf); | 
| 361 | 573k |  err: | 
| 362 | 573k |     return ret; | 
| 363 | 559k | } | 
| 364 |  |  | 
| 365 |  | static int file_puts(BIO *bp, const char *str) | 
| 366 | 38.9k | { | 
| 367 | 38.9k |     int n, ret; | 
| 368 |  |  | 
| 369 | 38.9k |     n = strlen(str); | 
| 370 | 38.9k |     ret = file_write(bp, str, n); | 
| 371 | 38.9k |     return ret; | 
| 372 | 38.9k | } | 
| 373 |  |  | 
| 374 |  | #else | 
| 375 |  |  | 
| 376 |  | static int file_write(BIO *b, const char *in, int inl) | 
| 377 |  | { | 
| 378 |  |     return -1; | 
| 379 |  | } | 
| 380 |  | static int file_read(BIO *b, char *out, int outl) | 
| 381 |  | { | 
| 382 |  |     return -1; | 
| 383 |  | } | 
| 384 |  | static int file_puts(BIO *bp, const char *str) | 
| 385 |  | { | 
| 386 |  |     return -1; | 
| 387 |  | } | 
| 388 |  | static int file_gets(BIO *bp, char *buf, int size) | 
| 389 |  | { | 
| 390 |  |     return 0; | 
| 391 |  | } | 
| 392 |  | static long file_ctrl(BIO *b, int cmd, long num, void *ptr) | 
| 393 |  | { | 
| 394 |  |     return 0; | 
| 395 |  | } | 
| 396 |  | static int file_new(BIO *bi) | 
| 397 |  | { | 
| 398 |  |     return 0; | 
| 399 |  | } | 
| 400 |  | static int file_free(BIO *a) | 
| 401 |  | { | 
| 402 |  |     return 0; | 
| 403 |  | } | 
| 404 |  |  | 
| 405 |  | static const BIO_METHOD methods_filep = { | 
| 406 |  |     BIO_TYPE_FILE, | 
| 407 |  |     "FILE pointer", | 
| 408 |  |     bwrite_conv, | 
| 409 |  |     file_write, | 
| 410 |  |     bread_conv, | 
| 411 |  |     file_read, | 
| 412 |  |     file_puts, | 
| 413 |  |     file_gets, | 
| 414 |  |     file_ctrl, | 
| 415 |  |     file_new, | 
| 416 |  |     file_free, | 
| 417 |  |     NULL,                      /* file_callback_ctrl */ | 
| 418 |  | }; | 
| 419 |  |  | 
| 420 |  | const BIO_METHOD *BIO_s_file(void) | 
| 421 |  | { | 
| 422 |  |     return &methods_filep; | 
| 423 |  | } | 
| 424 |  |  | 
| 425 |  | BIO *BIO_new_file(const char *filename, const char *mode) | 
| 426 |  | { | 
| 427 |  |     return NULL; | 
| 428 |  | } | 
| 429 |  |  | 
| 430 |  | #endif                         /* OPENSSL_NO_STDIO */ |