bss_file.c revision 280297
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 11855714SkrisBIO *BIO_new_file(const char *filename, const char *mode) 119280297Sjkim{ 120280297Sjkim BIO *ret; 121280297Sjkim FILE *file = NULL; 12255714Skris 123280297Sjkim# if defined(_WIN32) && defined(CP_UTF8) 124280297Sjkim int sz, len_0 = (int)strlen(filename) + 1; 125280297Sjkim DWORD flags; 126238405Sjkim 127280297Sjkim /* 128280297Sjkim * Basically there are three cases to cover: a) filename is 129280297Sjkim * pure ASCII string; b) actual UTF-8 encoded string and 130280297Sjkim * c) locale-ized string, i.e. one containing 8-bit 131280297Sjkim * characters that are meaningful in current system locale. 132280297Sjkim * If filename is pure ASCII or real UTF-8 encoded string, 133280297Sjkim * MultiByteToWideChar succeeds and _wfopen works. If 134280297Sjkim * filename is locale-ized string, chances are that 135280297Sjkim * MultiByteToWideChar fails reporting 136280297Sjkim * ERROR_NO_UNICODE_TRANSLATION, in which case we fall 137280297Sjkim * back to fopen... 138280297Sjkim */ 139280297Sjkim if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS), 140280297Sjkim filename, len_0, NULL, 0)) > 0 || 141280297Sjkim (GetLastError() == ERROR_INVALID_FLAGS && 142280297Sjkim (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), 143280297Sjkim filename, len_0, NULL, 0)) > 0) 144280297Sjkim ) { 145280297Sjkim WCHAR wmode[8]; 146280297Sjkim WCHAR *wfilename = _alloca(sz * sizeof(WCHAR)); 147238405Sjkim 148280297Sjkim if (MultiByteToWideChar(CP_UTF8, flags, 149280297Sjkim filename, len_0, wfilename, sz) && 150280297Sjkim MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, 151280297Sjkim wmode, sizeof(wmode) / sizeof(wmode[0])) && 152280297Sjkim (file = _wfopen(wfilename, wmode)) == NULL && 153280297Sjkim (errno == ENOENT || errno == EBADF) 154280297Sjkim ) { 155280297Sjkim /* 156280297Sjkim * UTF-8 decode succeeded, but no file, filename 157280297Sjkim * could still have been locale-ized... 158280297Sjkim */ 159280297Sjkim file = fopen(filename, mode); 160280297Sjkim } 161280297Sjkim } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { 162280297Sjkim file = fopen(filename, mode); 163280297Sjkim } 164280297Sjkim# else 165280297Sjkim file = fopen(filename, mode); 166280297Sjkim# endif 167280297Sjkim if (file == NULL) { 168280297Sjkim SYSerr(SYS_F_FOPEN, get_last_sys_error()); 169280297Sjkim ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); 170280297Sjkim if (errno == ENOENT) 171280297Sjkim BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); 172280297Sjkim else 173280297Sjkim BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); 174280297Sjkim return (NULL); 175280297Sjkim } 176280297Sjkim if ((ret = BIO_new(BIO_s_file())) == NULL) { 177280297Sjkim fclose(file); 178280297Sjkim return (NULL); 179280297Sjkim } 18055714Skris 181280297Sjkim BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage 182280297Sjkim * UPLINK */ 183280297Sjkim BIO_set_fp(ret, file, BIO_CLOSE); 184280297Sjkim return (ret); 185280297Sjkim} 18655714Skris 18755714SkrisBIO *BIO_new_fp(FILE *stream, int close_flag) 188280297Sjkim{ 189280297Sjkim BIO *ret; 19055714Skris 191280297Sjkim if ((ret = BIO_new(BIO_s_file())) == NULL) 192280297Sjkim return (NULL); 19355714Skris 194280297Sjkim BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for 195280297Sjkim * documentation puposes */ 196280297Sjkim BIO_set_fp(ret, stream, close_flag); 197280297Sjkim return (ret); 198280297Sjkim} 19955714Skris 20055714SkrisBIO_METHOD *BIO_s_file(void) 201280297Sjkim{ 202280297Sjkim return (&methods_filep); 203280297Sjkim} 20455714Skris 20555714Skrisstatic int MS_CALLBACK file_new(BIO *bi) 206280297Sjkim{ 207280297Sjkim bi->init = 0; 208280297Sjkim bi->num = 0; 209280297Sjkim bi->ptr = NULL; 210280297Sjkim bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ 211280297Sjkim return (1); 212280297Sjkim} 21355714Skris 21455714Skrisstatic int MS_CALLBACK file_free(BIO *a) 215280297Sjkim{ 216280297Sjkim if (a == NULL) 217280297Sjkim return (0); 218280297Sjkim if (a->shutdown) { 219280297Sjkim if ((a->init) && (a->ptr != NULL)) { 220280297Sjkim if (a->flags & BIO_FLAGS_UPLINK) 221280297Sjkim UP_fclose(a->ptr); 222280297Sjkim else 223280297Sjkim fclose(a->ptr); 224280297Sjkim a->ptr = NULL; 225280297Sjkim a->flags = BIO_FLAGS_UPLINK; 226280297Sjkim } 227280297Sjkim a->init = 0; 228280297Sjkim } 229280297Sjkim return (1); 230280297Sjkim} 231280297Sjkim 23255714Skrisstatic int MS_CALLBACK file_read(BIO *b, char *out, int outl) 233280297Sjkim{ 234280297Sjkim int ret = 0; 23555714Skris 236280297Sjkim if (b->init && (out != NULL)) { 237280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 238280297Sjkim ret = UP_fread(out, 1, (int)outl, b->ptr); 239280297Sjkim else 240280297Sjkim ret = fread(out, 1, (int)outl, (FILE *)b->ptr); 241280297Sjkim if (ret == 0 242280297Sjkim && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : 243280297Sjkim ferror((FILE *)b->ptr)) { 244280297Sjkim SYSerr(SYS_F_FREAD, get_last_sys_error()); 245280297Sjkim BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); 246280297Sjkim ret = -1; 247280297Sjkim } 248280297Sjkim } 249280297Sjkim return (ret); 250280297Sjkim} 25155714Skris 25268651Skrisstatic int MS_CALLBACK file_write(BIO *b, const char *in, int inl) 253280297Sjkim{ 254280297Sjkim int ret = 0; 25555714Skris 256280297Sjkim if (b->init && (in != NULL)) { 257280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 258280297Sjkim ret = UP_fwrite(in, (int)inl, 1, b->ptr); 259280297Sjkim else 260280297Sjkim ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); 261280297Sjkim if (ret) 262280297Sjkim ret = inl; 263280297Sjkim /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ 264280297Sjkim /* 265280297Sjkim * according to Tim Hudson <tjh@cryptsoft.com>, the commented out 266280297Sjkim * version above can cause 'inl' write calls under some stupid stdio 267280297Sjkim * implementations (VMS) 268280297Sjkim */ 269280297Sjkim } 270280297Sjkim return (ret); 271280297Sjkim} 27255714Skris 27368651Skrisstatic long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) 274280297Sjkim{ 275280297Sjkim long ret = 1; 276280297Sjkim FILE *fp = (FILE *)b->ptr; 277280297Sjkim FILE **fpp; 278280297Sjkim char p[4]; 27955714Skris 280280297Sjkim switch (cmd) { 281280297Sjkim case BIO_C_FILE_SEEK: 282280297Sjkim case BIO_CTRL_RESET: 283280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 284280297Sjkim ret = (long)UP_fseek(b->ptr, num, 0); 285280297Sjkim else 286280297Sjkim ret = (long)fseek(fp, num, 0); 287280297Sjkim break; 288280297Sjkim case BIO_CTRL_EOF: 289280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 290280297Sjkim ret = (long)UP_feof(fp); 291280297Sjkim else 292280297Sjkim ret = (long)feof(fp); 293280297Sjkim break; 294280297Sjkim case BIO_C_FILE_TELL: 295280297Sjkim case BIO_CTRL_INFO: 296280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 297280297Sjkim ret = UP_ftell(b->ptr); 298280297Sjkim else 299280297Sjkim ret = ftell(fp); 300280297Sjkim break; 301280297Sjkim case BIO_C_SET_FILE_PTR: 302280297Sjkim file_free(b); 303280297Sjkim b->shutdown = (int)num & BIO_CLOSE; 304280297Sjkim b->ptr = ptr; 305280297Sjkim b->init = 1; 306280297Sjkim# if BIO_FLAGS_UPLINK!=0 307280297Sjkim# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) 308280297Sjkim# define _IOB_ENTRIES 20 309280297Sjkim# endif 310280297Sjkim# if defined(_IOB_ENTRIES) 311280297Sjkim /* Safety net to catch purely internal BIO_set_fp calls */ 312280297Sjkim if ((size_t)ptr >= (size_t)stdin && 313280297Sjkim (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) 314280297Sjkim BIO_clear_flags(b, BIO_FLAGS_UPLINK); 315280297Sjkim# endif 316280297Sjkim# endif 317280297Sjkim# ifdef UP_fsetmod 318280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 319280297Sjkim UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); 320280297Sjkim else 321280297Sjkim# endif 322280297Sjkim { 323280297Sjkim# if defined(OPENSSL_SYS_WINDOWS) 324280297Sjkim int fd = _fileno((FILE *)ptr); 325280297Sjkim if (num & BIO_FP_TEXT) 326280297Sjkim _setmode(fd, _O_TEXT); 327280297Sjkim else 328280297Sjkim _setmode(fd, _O_BINARY); 329280297Sjkim# elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) 330280297Sjkim int fd = fileno((FILE *)ptr); 331280297Sjkim /* Under CLib there are differences in file modes */ 332280297Sjkim if (num & BIO_FP_TEXT) 333280297Sjkim setmode(fd, O_TEXT); 334280297Sjkim else 335280297Sjkim setmode(fd, O_BINARY); 336280297Sjkim# elif defined(OPENSSL_SYS_MSDOS) 337280297Sjkim int fd = fileno((FILE *)ptr); 338280297Sjkim /* Set correct text/binary mode */ 339280297Sjkim if (num & BIO_FP_TEXT) 340280297Sjkim _setmode(fd, _O_TEXT); 341280297Sjkim /* Dangerous to set stdin/stdout to raw (unless redirected) */ 342280297Sjkim else { 343280297Sjkim if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { 344280297Sjkim if (isatty(fd) <= 0) 345280297Sjkim _setmode(fd, _O_BINARY); 346280297Sjkim } else 347280297Sjkim _setmode(fd, _O_BINARY); 348280297Sjkim } 349280297Sjkim# elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) 350280297Sjkim int fd = fileno((FILE *)ptr); 351280297Sjkim if (num & BIO_FP_TEXT) 352280297Sjkim setmode(fd, O_TEXT); 353280297Sjkim else 354280297Sjkim setmode(fd, O_BINARY); 355280297Sjkim# endif 356280297Sjkim } 357280297Sjkim break; 358280297Sjkim case BIO_C_SET_FILENAME: 359280297Sjkim file_free(b); 360280297Sjkim b->shutdown = (int)num & BIO_CLOSE; 361280297Sjkim if (num & BIO_FP_APPEND) { 362280297Sjkim if (num & BIO_FP_READ) 363280297Sjkim BUF_strlcpy(p, "a+", sizeof p); 364280297Sjkim else 365280297Sjkim BUF_strlcpy(p, "a", sizeof p); 366280297Sjkim } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) 367280297Sjkim BUF_strlcpy(p, "r+", sizeof p); 368280297Sjkim else if (num & BIO_FP_WRITE) 369280297Sjkim BUF_strlcpy(p, "w", sizeof p); 370280297Sjkim else if (num & BIO_FP_READ) 371280297Sjkim BUF_strlcpy(p, "r", sizeof p); 372280297Sjkim else { 373280297Sjkim BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); 374280297Sjkim ret = 0; 375280297Sjkim break; 376280297Sjkim } 377280297Sjkim# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) 378280297Sjkim if (!(num & BIO_FP_TEXT)) 379280297Sjkim strcat(p, "b"); 380280297Sjkim else 381280297Sjkim strcat(p, "t"); 382280297Sjkim# endif 383280297Sjkim# if defined(OPENSSL_SYS_NETWARE) 384280297Sjkim if (!(num & BIO_FP_TEXT)) 385280297Sjkim strcat(p, "b"); 386280297Sjkim else 387280297Sjkim strcat(p, "t"); 388280297Sjkim# endif 389280297Sjkim fp = fopen(ptr, p); 390280297Sjkim if (fp == NULL) { 391280297Sjkim SYSerr(SYS_F_FOPEN, get_last_sys_error()); 392280297Sjkim ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); 393280297Sjkim BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); 394280297Sjkim ret = 0; 395280297Sjkim break; 396280297Sjkim } 397280297Sjkim b->ptr = fp; 398280297Sjkim b->init = 1; 399280297Sjkim BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage 400280297Sjkim * UPLINK */ 401280297Sjkim break; 402280297Sjkim case BIO_C_GET_FILE_PTR: 403280297Sjkim /* the ptr parameter is actually a FILE ** in this case. */ 404280297Sjkim if (ptr != NULL) { 405280297Sjkim fpp = (FILE **)ptr; 406280297Sjkim *fpp = (FILE *)b->ptr; 407280297Sjkim } 408280297Sjkim break; 409280297Sjkim case BIO_CTRL_GET_CLOSE: 410280297Sjkim ret = (long)b->shutdown; 411280297Sjkim break; 412280297Sjkim case BIO_CTRL_SET_CLOSE: 413280297Sjkim b->shutdown = (int)num; 414280297Sjkim break; 415280297Sjkim case BIO_CTRL_FLUSH: 416280297Sjkim if (b->flags & BIO_FLAGS_UPLINK) 417280297Sjkim UP_fflush(b->ptr); 418280297Sjkim else 419280297Sjkim fflush((FILE *)b->ptr); 420280297Sjkim break; 421280297Sjkim case BIO_CTRL_DUP: 422280297Sjkim ret = 1; 423280297Sjkim break; 42455714Skris 425280297Sjkim case BIO_CTRL_WPENDING: 426280297Sjkim case BIO_CTRL_PENDING: 427280297Sjkim case BIO_CTRL_PUSH: 428280297Sjkim case BIO_CTRL_POP: 429280297Sjkim default: 430280297Sjkim ret = 0; 431280297Sjkim break; 432280297Sjkim } 433280297Sjkim return (ret); 434280297Sjkim} 43555714Skris 43655714Skrisstatic int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) 437280297Sjkim{ 438280297Sjkim int ret = 0; 43955714Skris 440280297Sjkim buf[0] = '\0'; 441280297Sjkim if (bp->flags & BIO_FLAGS_UPLINK) { 442280297Sjkim if (!UP_fgets(buf, size, bp->ptr)) 443280297Sjkim goto err; 444280297Sjkim } else { 445280297Sjkim if (!fgets(buf, size, (FILE *)bp->ptr)) 446280297Sjkim goto err; 447280297Sjkim } 448280297Sjkim if (buf[0] != '\0') 449280297Sjkim ret = strlen(buf); 450280297Sjkim err: 451280297Sjkim return (ret); 452280297Sjkim} 45355714Skris 45468651Skrisstatic int MS_CALLBACK file_puts(BIO *bp, const char *str) 455280297Sjkim{ 456280297Sjkim int n, ret; 45755714Skris 458280297Sjkim n = strlen(str); 459280297Sjkim ret = file_write(bp, str, n); 460280297Sjkim return (ret); 461280297Sjkim} 46255714Skris 463280297Sjkim# endif /* OPENSSL_NO_STDIO */ 46455714Skris 465280297Sjkim#endif /* HEADER_BSS_FILE_C */ 466