155714Skris/* crypto/bio/bss_file.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280297Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280297Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280297Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280297Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280297Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 59280297Sjkim/*- 60280297Sjkim * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout 61280297Sjkim * with binary data (e.g. asn1parse -inform DER < xxx) under 62280297Sjkim * Windows 6355714Skris */ 6455714Skris 6555714Skris#ifndef HEADER_BSS_FILE_C 66280297Sjkim# define HEADER_BSS_FILE_C 6755714Skris 68280297Sjkim# if defined(__linux) || defined(__sun) || defined(__hpux) 69280297Sjkim/* 70280297Sjkim * Following definition aliases fopen to fopen64 on above mentioned 71280297Sjkim * platforms. This makes it possible to open and sequentially access files 72280297Sjkim * larger than 2GB from 32-bit application. It does not allow to traverse 73280297Sjkim * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit 74280297Sjkim * platform permits that, not with fseek/ftell. Not to mention that breaking 75280297Sjkim * 2GB limit for seeking would require surgery to *our* API. But sequential 76280297Sjkim * access suffices for practical cases when you can run into large files, 77280297Sjkim * such as fingerprinting, so we can let API alone. For reference, the list 78280297Sjkim * of 32-bit platforms which allow for sequential access of large files 79280297Sjkim * without extra "magic" comprise *BSD, Darwin, IRIX... 80160814Ssimon */ 81280297Sjkim# ifndef _FILE_OFFSET_BITS 82280297Sjkim# define _FILE_OFFSET_BITS 64 83280297Sjkim# endif 84280297Sjkim# endif 85160814Ssimon 86280297Sjkim# include <stdio.h> 87280297Sjkim# include <errno.h> 88280297Sjkim# include "cryptlib.h" 89280297Sjkim# include "bio_lcl.h" 90280297Sjkim# include <openssl/err.h> 9155714Skris 92280297Sjkim# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) 93280297Sjkim# include <nwfileio.h> 94280297Sjkim# endif 95194206Ssimon 96280297Sjkim# if !defined(OPENSSL_NO_STDIO) 9755714Skris 9868651Skrisstatic int MS_CALLBACK file_write(BIO *h, const char *buf, int num); 9968651Skrisstatic int MS_CALLBACK file_read(BIO *h, char *buf, int size); 10068651Skrisstatic int MS_CALLBACK file_puts(BIO *h, const char *str); 10168651Skrisstatic int MS_CALLBACK file_gets(BIO *h, char *str, int size); 10268651Skrisstatic long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2); 10355714Skrisstatic int MS_CALLBACK file_new(BIO *h); 10455714Skrisstatic int MS_CALLBACK file_free(BIO *data); 105280297Sjkimstatic BIO_METHOD methods_filep = { 106280297Sjkim BIO_TYPE_FILE, 107280297Sjkim "FILE pointer", 108280297Sjkim file_write, 109280297Sjkim file_read, 110280297Sjkim file_puts, 111280297Sjkim file_gets, 112280297Sjkim file_ctrl, 113280297Sjkim file_new, 114280297Sjkim file_free, 115280297Sjkim NULL, 116280297Sjkim}; 11755714Skris 118291719Sjkimstatic FILE *file_fopen(const char *filename, const char *mode) 119280297Sjkim{ 120280297Sjkim FILE *file = NULL; 12155714Skris 122280297Sjkim# if defined(_WIN32) && defined(CP_UTF8) 123280297Sjkim int sz, len_0 = (int)strlen(filename) + 1; 124280297Sjkim DWORD flags; 125238405Sjkim 126280297Sjkim /* 127280297Sjkim * Basically there are three cases to cover: a) filename is 128280297Sjkim * pure ASCII string; b) actual UTF-8 encoded string and 129280297Sjkim * c) locale-ized string, i.e. one containing 8-bit 130280297Sjkim * characters that are meaningful in current system locale. 131280297Sjkim * If filename is pure ASCII or real UTF-8 encoded string, 132280297Sjkim * MultiByteToWideChar succeeds and _wfopen works. If 133280297Sjkim * filename is locale-ized string, chances are that 134280297Sjkim * MultiByteToWideChar fails reporting 135280297Sjkim * ERROR_NO_UNICODE_TRANSLATION, in which case we fall 136280297Sjkim * back to fopen... 137280297Sjkim */ 138280297Sjkim if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS), 139280297Sjkim filename, len_0, NULL, 0)) > 0 || 140280297Sjkim (GetLastError() == ERROR_INVALID_FLAGS && 141280297Sjkim (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), 142280297Sjkim filename, len_0, NULL, 0)) > 0) 143280297Sjkim ) { 144280297Sjkim WCHAR wmode[8]; 145280297Sjkim WCHAR *wfilename = _alloca(sz * sizeof(WCHAR)); 146238405Sjkim 147280297Sjkim if (MultiByteToWideChar(CP_UTF8, flags, 148280297Sjkim filename, len_0, wfilename, sz) && 149280297Sjkim MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, 150280297Sjkim wmode, sizeof(wmode) / sizeof(wmode[0])) && 151280297Sjkim (file = _wfopen(wfilename, wmode)) == NULL && 152280297Sjkim (errno == ENOENT || errno == EBADF) 153280297Sjkim ) { 154280297Sjkim /* 155280297Sjkim * UTF-8 decode succeeded, but no file, filename 156280297Sjkim * could still have been locale-ized... 157280297Sjkim */ 158280297Sjkim file = fopen(filename, mode); 159280297Sjkim } 160280297Sjkim } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { 161280297Sjkim file = fopen(filename, mode); 162280297Sjkim } 163280297Sjkim# else 164280297Sjkim file = fopen(filename, mode); 165280297Sjkim# endif 166291719Sjkim return (file); 167291719Sjkim} 168291719Sjkim 169291719SjkimBIO *BIO_new_file(const char *filename, const char *mode) 170291719Sjkim{ 171291719Sjkim BIO *ret; 172291719Sjkim FILE *file = file_fopen(filename, mode); 173291719Sjkim 174280297Sjkim if (file == NULL) { 175280297Sjkim SYSerr(SYS_F_FOPEN, get_last_sys_error()); 176280297Sjkim ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); 177306195Sjkim if (errno == ENOENT 178306195Sjkim# ifdef ENXIO 179306195Sjkim || errno == ENXIO 180306195Sjkim# endif 181306195Sjkim ) 182280297Sjkim BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); 183280297Sjkim else 184280297Sjkim BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); 185280297Sjkim return (NULL); 186280297Sjkim } 187280297Sjkim if ((ret = BIO_new(BIO_s_file())) == NULL) { 188280297Sjkim fclose(file); 189280297Sjkim return (NULL); 190280297Sjkim } 19155714Skris 192280297Sjkim BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage 193280297Sjkim * UPLINK */ 194280297Sjkim BIO_set_fp(ret, file, BIO_CLOSE); 195280297Sjkim return (ret); 196280297Sjkim} 19755714Skris 19855714SkrisBIO *BIO_new_fp(FILE *stream, int close_flag) 199280297Sjkim{ 200280297Sjkim BIO *ret; 20155714Skris 202280297Sjkim if ((ret = BIO_new(BIO_s_file())) == NULL) 203280297Sjkim return (NULL); 20455714Skris 205280297Sjkim BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for 206280297Sjkim * documentation puposes */ 207280297Sjkim BIO_set_fp(ret, stream, close_flag); 208280297Sjkim return (ret); 209280297Sjkim} 21055714Skris 21155714SkrisBIO_METHOD *BIO_s_file(void) 212280297Sjkim{ 213280297Sjkim return (&methods_filep); 214280297Sjkim} 21555714Skris 21655714Skrisstatic int MS_CALLBACK file_new(BIO *bi) 217280297Sjkim{ 218280297Sjkim bi->init = 0; 219280297Sjkim bi->num = 0; 220280297Sjkim bi->ptr = NULL; 221280297Sjkim bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ 222280297Sjkim return (1); 223280297Sjkim} 22455714Skris 22555714Skrisstatic int MS_CALLBACK file_free(BIO *a) 226280297Sjkim{ 227280297Sjkim if (a == NULL) 228280297Sjkim return (0); 229280297Sjkim if (a->shutdown) { 230280297Sjkim if ((a->init) && (a->ptr != NULL)) { 231280297Sjkim if (a->flags & BIO_FLAGS_UPLINK) 232280297Sjkim UP_fclose(a->ptr); 233280297Sjkim else 234280297Sjkim fclose(a->ptr); 235280297Sjkim a->ptr = NULL; 236280297Sjkim a->flags = BIO_FLAGS_UPLINK; 237280297Sjkim } 238280297Sjkim a->init = 0; 239280297Sjkim } 240280297Sjkim return (1); 241280297Sjkim} 242280297Sjkim 24355714Skrisstatic int MS_CALLBACK file_read(BIO *b, char *out, int outl) 244280297Sjkim{ 245280297Sjkim int ret = 0; 24655714Skris 247280297Sjkim if (b->init && (out != NULL)) { 248280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 249280297Sjkim ret = UP_fread(out, 1, (int)outl, b->ptr); 250280297Sjkim else 251280297Sjkim ret = fread(out, 1, (int)outl, (FILE *)b->ptr); 252280297Sjkim if (ret == 0 253280297Sjkim && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : 254325335Sjkim ferror((FILE *)b->ptr)) { 255280297Sjkim SYSerr(SYS_F_FREAD, get_last_sys_error()); 256280297Sjkim BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); 257280297Sjkim ret = -1; 258280297Sjkim } 259280297Sjkim } 260280297Sjkim return (ret); 261280297Sjkim} 26255714Skris 26368651Skrisstatic int MS_CALLBACK file_write(BIO *b, const char *in, int inl) 264280297Sjkim{ 265280297Sjkim int ret = 0; 26655714Skris 267280297Sjkim if (b->init && (in != NULL)) { 268280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 269280297Sjkim ret = UP_fwrite(in, (int)inl, 1, b->ptr); 270280297Sjkim else 271280297Sjkim ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); 272280297Sjkim if (ret) 273280297Sjkim ret = inl; 274280297Sjkim /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ 275280297Sjkim /* 276280297Sjkim * according to Tim Hudson <tjh@cryptsoft.com>, the commented out 277280297Sjkim * version above can cause 'inl' write calls under some stupid stdio 278280297Sjkim * implementations (VMS) 279280297Sjkim */ 280280297Sjkim } 281280297Sjkim return (ret); 282280297Sjkim} 28355714Skris 28468651Skrisstatic long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) 285280297Sjkim{ 286280297Sjkim long ret = 1; 287280297Sjkim FILE *fp = (FILE *)b->ptr; 288280297Sjkim FILE **fpp; 289280297Sjkim char p[4]; 290325335Sjkim int st; 29155714Skris 292280297Sjkim switch (cmd) { 293280297Sjkim case BIO_C_FILE_SEEK: 294280297Sjkim case BIO_CTRL_RESET: 295280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 296280297Sjkim ret = (long)UP_fseek(b->ptr, num, 0); 297280297Sjkim else 298280297Sjkim ret = (long)fseek(fp, num, 0); 299280297Sjkim break; 300280297Sjkim case BIO_CTRL_EOF: 301280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 302280297Sjkim ret = (long)UP_feof(fp); 303280297Sjkim else 304280297Sjkim ret = (long)feof(fp); 305280297Sjkim break; 306280297Sjkim case BIO_C_FILE_TELL: 307280297Sjkim case BIO_CTRL_INFO: 308280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 309280297Sjkim ret = UP_ftell(b->ptr); 310280297Sjkim else 311280297Sjkim ret = ftell(fp); 312280297Sjkim break; 313280297Sjkim case BIO_C_SET_FILE_PTR: 314280297Sjkim file_free(b); 315280297Sjkim b->shutdown = (int)num & BIO_CLOSE; 316280297Sjkim b->ptr = ptr; 317280297Sjkim b->init = 1; 318280297Sjkim# if BIO_FLAGS_UPLINK!=0 319280297Sjkim# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) 320280297Sjkim# define _IOB_ENTRIES 20 321280297Sjkim# endif 322280297Sjkim /* Safety net to catch purely internal BIO_set_fp calls */ 323325335Sjkim# if defined(_MSC_VER) && _MSC_VER>=1900 324325335Sjkim if (ptr == stdin || ptr == stdout || ptr == stderr) 325325335Sjkim BIO_clear_flags(b, BIO_FLAGS_UPLINK); 326325335Sjkim# elif defined(_IOB_ENTRIES) 327280297Sjkim if ((size_t)ptr >= (size_t)stdin && 328280297Sjkim (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) 329280297Sjkim BIO_clear_flags(b, BIO_FLAGS_UPLINK); 330280297Sjkim# endif 331280297Sjkim# endif 332280297Sjkim# ifdef UP_fsetmod 333280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 334280297Sjkim UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); 335280297Sjkim else 336280297Sjkim# endif 337280297Sjkim { 338280297Sjkim# if defined(OPENSSL_SYS_WINDOWS) 339280297Sjkim int fd = _fileno((FILE *)ptr); 340280297Sjkim if (num & BIO_FP_TEXT) 341280297Sjkim _setmode(fd, _O_TEXT); 342280297Sjkim else 343280297Sjkim _setmode(fd, _O_BINARY); 344280297Sjkim# elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) 345280297Sjkim int fd = fileno((FILE *)ptr); 346280297Sjkim /* Under CLib there are differences in file modes */ 347280297Sjkim if (num & BIO_FP_TEXT) 348280297Sjkim setmode(fd, O_TEXT); 349280297Sjkim else 350280297Sjkim setmode(fd, O_BINARY); 351280297Sjkim# elif defined(OPENSSL_SYS_MSDOS) 352280297Sjkim int fd = fileno((FILE *)ptr); 353280297Sjkim /* Set correct text/binary mode */ 354280297Sjkim if (num & BIO_FP_TEXT) 355280297Sjkim _setmode(fd, _O_TEXT); 356280297Sjkim /* Dangerous to set stdin/stdout to raw (unless redirected) */ 357280297Sjkim else { 358280297Sjkim if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { 359280297Sjkim if (isatty(fd) <= 0) 360280297Sjkim _setmode(fd, _O_BINARY); 361280297Sjkim } else 362280297Sjkim _setmode(fd, _O_BINARY); 363280297Sjkim } 364344604Sjkim# elif defined(OPENSSL_SYS_OS2) 365280297Sjkim int fd = fileno((FILE *)ptr); 366280297Sjkim if (num & BIO_FP_TEXT) 367280297Sjkim setmode(fd, O_TEXT); 368280297Sjkim else 369280297Sjkim setmode(fd, O_BINARY); 370344604Sjkim# elif defined(OPENSSL_SYS_WIN32_CYGWIN) 371344604Sjkim int fd = fileno((FILE *)ptr); 372344604Sjkim if (!(num & BIO_FP_TEXT)) 373344604Sjkim setmode(fd, O_BINARY); 374280297Sjkim# endif 375280297Sjkim } 376280297Sjkim break; 377280297Sjkim case BIO_C_SET_FILENAME: 378280297Sjkim file_free(b); 379280297Sjkim b->shutdown = (int)num & BIO_CLOSE; 380280297Sjkim if (num & BIO_FP_APPEND) { 381280297Sjkim if (num & BIO_FP_READ) 382331638Sjkim BUF_strlcpy(p, "a+", sizeof(p)); 383280297Sjkim else 384331638Sjkim BUF_strlcpy(p, "a", sizeof(p)); 385280297Sjkim } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) 386331638Sjkim BUF_strlcpy(p, "r+", sizeof(p)); 387280297Sjkim else if (num & BIO_FP_WRITE) 388331638Sjkim BUF_strlcpy(p, "w", sizeof(p)); 389280297Sjkim else if (num & BIO_FP_READ) 390331638Sjkim BUF_strlcpy(p, "r", sizeof(p)); 391280297Sjkim else { 392280297Sjkim BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); 393280297Sjkim ret = 0; 394280297Sjkim break; 395280297Sjkim } 396344604Sjkim# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) 397280297Sjkim if (!(num & BIO_FP_TEXT)) 398280297Sjkim strcat(p, "b"); 399280297Sjkim else 400280297Sjkim strcat(p, "t"); 401344604Sjkim# elif defined(OPENSSL_SYS_WIN32_CYGWIN) 402344604Sjkim if (!(num & BIO_FP_TEXT)) 403344604Sjkim strcat(p, "b"); 404280297Sjkim# endif 405280297Sjkim# if defined(OPENSSL_SYS_NETWARE) 406280297Sjkim if (!(num & BIO_FP_TEXT)) 407280297Sjkim strcat(p, "b"); 408280297Sjkim else 409280297Sjkim strcat(p, "t"); 410280297Sjkim# endif 411291719Sjkim fp = file_fopen(ptr, p); 412280297Sjkim if (fp == NULL) { 413280297Sjkim SYSerr(SYS_F_FOPEN, get_last_sys_error()); 414280297Sjkim ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); 415280297Sjkim BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); 416280297Sjkim ret = 0; 417280297Sjkim break; 418280297Sjkim } 419280297Sjkim b->ptr = fp; 420280297Sjkim b->init = 1; 421280297Sjkim BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage 422280297Sjkim * UPLINK */ 423280297Sjkim break; 424280297Sjkim case BIO_C_GET_FILE_PTR: 425280297Sjkim /* the ptr parameter is actually a FILE ** in this case. */ 426280297Sjkim if (ptr != NULL) { 427280297Sjkim fpp = (FILE **)ptr; 428280297Sjkim *fpp = (FILE *)b->ptr; 429280297Sjkim } 430280297Sjkim break; 431280297Sjkim case BIO_CTRL_GET_CLOSE: 432280297Sjkim ret = (long)b->shutdown; 433280297Sjkim break; 434280297Sjkim case BIO_CTRL_SET_CLOSE: 435280297Sjkim b->shutdown = (int)num; 436280297Sjkim break; 437280297Sjkim case BIO_CTRL_FLUSH: 438325335Sjkim st = b->flags & BIO_FLAGS_UPLINK 439325335Sjkim ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); 440325335Sjkim if (st == EOF) { 441325335Sjkim SYSerr(SYS_F_FFLUSH, get_last_sys_error()); 442325335Sjkim ERR_add_error_data(1, "fflush()"); 443325335Sjkim BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); 444325335Sjkim ret = 0; 445325335Sjkim } 446280297Sjkim break; 447280297Sjkim case BIO_CTRL_DUP: 448280297Sjkim ret = 1; 449280297Sjkim break; 45055714Skris 451280297Sjkim case BIO_CTRL_WPENDING: 452280297Sjkim case BIO_CTRL_PENDING: 453280297Sjkim case BIO_CTRL_PUSH: 454280297Sjkim case BIO_CTRL_POP: 455280297Sjkim default: 456280297Sjkim ret = 0; 457280297Sjkim break; 458280297Sjkim } 459280297Sjkim return (ret); 460280297Sjkim} 46155714Skris 46255714Skrisstatic int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) 463280297Sjkim{ 464280297Sjkim int ret = 0; 46555714Skris 466280297Sjkim buf[0] = '\0'; 467280297Sjkim if (bp->flags & BIO_FLAGS_UPLINK) { 468280297Sjkim if (!UP_fgets(buf, size, bp->ptr)) 469280297Sjkim goto err; 470280297Sjkim } else { 471280297Sjkim if (!fgets(buf, size, (FILE *)bp->ptr)) 472280297Sjkim goto err; 473280297Sjkim } 474280297Sjkim if (buf[0] != '\0') 475280297Sjkim ret = strlen(buf); 476280297Sjkim err: 477280297Sjkim return (ret); 478280297Sjkim} 47955714Skris 48068651Skrisstatic int MS_CALLBACK file_puts(BIO *bp, const char *str) 481280297Sjkim{ 482280297Sjkim int n, ret; 48355714Skris 484280297Sjkim n = strlen(str); 485280297Sjkim ret = file_write(bp, str, n); 486280297Sjkim return (ret); 487280297Sjkim} 48855714Skris 489280297Sjkim# endif /* OPENSSL_NO_STDIO */ 49055714Skris 491280297Sjkim#endif /* HEADER_BSS_FILE_C */ 492