os/ossrv/ssl/libcrypto/src/crypto/bio/bss_file.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* crypto/bio/bss_file.c */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
sl@0
    59
/*
sl@0
    60
 * 03-Dec-1997	rdenny@dc3.com  Fix bug preventing use of stdin/stdout
sl@0
    61
 *		with binary data (e.g. asn1parse -inform DER < xxx) under
sl@0
    62
 *		Windows
sl@0
    63
 */
sl@0
    64
/*
sl@0
    65
 © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
sl@0
    66
 */
sl@0
    67
 
sl@0
    68
sl@0
    69
#ifndef HEADER_BSS_FILE_C
sl@0
    70
#define HEADER_BSS_FILE_C
sl@0
    71
sl@0
    72
#if defined(__linux) || defined(__sun) || defined(__hpux)
sl@0
    73
/* Following definition aliases fopen to fopen64 on above mentioned
sl@0
    74
 * platforms. This makes it possible to open and sequentially access
sl@0
    75
 * files larger than 2GB from 32-bit application. It does not allow to
sl@0
    76
 * traverse them beyond 2GB with fseek/ftell, but on the other hand *no*
sl@0
    77
 * 32-bit platform permits that, not with fseek/ftell. Not to mention
sl@0
    78
 * that breaking 2GB limit for seeking would require surgery to *our*
sl@0
    79
 * API. But sequential access suffices for practical cases when you
sl@0
    80
 * can run into large files, such as fingerprinting, so we can let API
sl@0
    81
 * alone. For reference, the list of 32-bit platforms which allow for
sl@0
    82
 * sequential access of large files without extra "magic" comprise *BSD,
sl@0
    83
 * Darwin, IRIX...
sl@0
    84
 */
sl@0
    85
#ifndef _FILE_OFFSET_BITS
sl@0
    86
#define _FILE_OFFSET_BITS 64
sl@0
    87
#endif
sl@0
    88
#endif
sl@0
    89
sl@0
    90
#include <stdio.h>
sl@0
    91
#include <errno.h>
sl@0
    92
#include "cryptlib.h"
sl@0
    93
#include "bio_lcl.h"
sl@0
    94
#include <openssl/err.h>
sl@0
    95
#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
sl@0
    96
#include "libcrypto_wsd_macros.h"
sl@0
    97
#include "libcrypto_wsd.h"
sl@0
    98
#endif
sl@0
    99
sl@0
   100
sl@0
   101
#if !defined(OPENSSL_NO_STDIO)
sl@0
   102
sl@0
   103
static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
sl@0
   104
static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
sl@0
   105
static int MS_CALLBACK file_puts(BIO *h, const char *str);
sl@0
   106
static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
sl@0
   107
static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
sl@0
   108
static int MS_CALLBACK file_new(BIO *h);
sl@0
   109
static int MS_CALLBACK file_free(BIO *data);
sl@0
   110
#ifndef EMULATOR
sl@0
   111
static BIO_METHOD methods_filep=
sl@0
   112
	{
sl@0
   113
	BIO_TYPE_FILE,
sl@0
   114
	"FILE pointer",
sl@0
   115
	file_write,
sl@0
   116
	file_read,
sl@0
   117
	file_puts,
sl@0
   118
	file_gets,
sl@0
   119
	file_ctrl,
sl@0
   120
	file_new,
sl@0
   121
	file_free,
sl@0
   122
	NULL,
sl@0
   123
	};
sl@0
   124
#else
sl@0
   125
GET_STATIC_VAR_FROM_TLS(methods_filep,bss_file,BIO_METHOD)
sl@0
   126
#define methods_filep (*GET_WSD_VAR_NAME(methods_filep,bss_file,s)())
sl@0
   127
const BIO_METHOD temp_s_methods_filep=
sl@0
   128
	{
sl@0
   129
	BIO_TYPE_FILE,
sl@0
   130
	"FILE pointer",
sl@0
   131
	file_write,
sl@0
   132
	file_read,
sl@0
   133
	file_puts,
sl@0
   134
	file_gets,
sl@0
   135
	file_ctrl,
sl@0
   136
	file_new,
sl@0
   137
	file_free,
sl@0
   138
	NULL,
sl@0
   139
	};
sl@0
   140
sl@0
   141
#endif	
sl@0
   142
	
sl@0
   143
sl@0
   144
EXPORT_C BIO *BIO_new_file(const char *filename, const char *mode)
sl@0
   145
	{
sl@0
   146
	BIO *ret;
sl@0
   147
	FILE *file;
sl@0
   148
sl@0
   149
	if ((file=fopen(filename,mode)) == NULL)
sl@0
   150
		{
sl@0
   151
		SYSerr(SYS_F_FOPEN,get_last_sys_error());
sl@0
   152
		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
sl@0
   153
		if (errno == ENOENT)
sl@0
   154
			BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
sl@0
   155
		else
sl@0
   156
			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
sl@0
   157
		return(NULL);
sl@0
   158
		}
sl@0
   159
	if ((ret=BIO_new(BIO_s_file_internal())) == NULL)
sl@0
   160
	{
sl@0
   161
		fclose(file);
sl@0
   162
  	return(NULL);
sl@0
   163
	}	
sl@0
   164
sl@0
   165
	BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
sl@0
   166
	BIO_set_fp(ret,file,BIO_CLOSE);
sl@0
   167
	return(ret);
sl@0
   168
	}
sl@0
   169
sl@0
   170
EXPORT_C BIO *BIO_new_fp(FILE *stream, int close_flag)
sl@0
   171
	{
sl@0
   172
	BIO *ret;
sl@0
   173
sl@0
   174
	if ((ret=BIO_new(BIO_s_file())) == NULL)
sl@0
   175
		return(NULL);
sl@0
   176
sl@0
   177
	BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */
sl@0
   178
	BIO_set_fp(ret,stream,close_flag);
sl@0
   179
	return(ret);
sl@0
   180
	}
sl@0
   181
sl@0
   182
EXPORT_C BIO_METHOD *BIO_s_file(void)
sl@0
   183
	{
sl@0
   184
	return(&methods_filep);
sl@0
   185
	}
sl@0
   186
sl@0
   187
static int MS_CALLBACK file_new(BIO *bi)
sl@0
   188
	{
sl@0
   189
	bi->init=0;
sl@0
   190
	bi->num=0;
sl@0
   191
	bi->ptr=NULL;
sl@0
   192
	bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */
sl@0
   193
	return(1);
sl@0
   194
	}
sl@0
   195
sl@0
   196
static int MS_CALLBACK file_free(BIO *a)
sl@0
   197
	{
sl@0
   198
	if (a == NULL) return(0);
sl@0
   199
	if (a->shutdown)
sl@0
   200
		{
sl@0
   201
		if ((a->init) && (a->ptr != NULL))
sl@0
   202
			{
sl@0
   203
			if (a->flags&BIO_FLAGS_UPLINK)
sl@0
   204
				UP_fclose (a->ptr);
sl@0
   205
			else
sl@0
   206
				fclose (a->ptr);
sl@0
   207
			a->ptr=NULL;
sl@0
   208
			a->flags=BIO_FLAGS_UPLINK;
sl@0
   209
			}
sl@0
   210
		a->init=0;
sl@0
   211
		}
sl@0
   212
	return(1);
sl@0
   213
	}
sl@0
   214
	
sl@0
   215
static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
sl@0
   216
	{
sl@0
   217
	int ret=0;
sl@0
   218
sl@0
   219
	if (b->init && (out != NULL))
sl@0
   220
		{
sl@0
   221
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   222
			ret=UP_fread(out,1,(int)outl,b->ptr);
sl@0
   223
		else
sl@0
   224
			ret=fread(out,1,(int)outl,(FILE *)b->ptr);
sl@0
   225
		if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr))
sl@0
   226
			{
sl@0
   227
			SYSerr(SYS_F_FREAD,get_last_sys_error());
sl@0
   228
			BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
sl@0
   229
			ret=-1;
sl@0
   230
			}
sl@0
   231
		}
sl@0
   232
	return(ret);
sl@0
   233
	}
sl@0
   234
sl@0
   235
static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
sl@0
   236
	{
sl@0
   237
	int ret=0;
sl@0
   238
sl@0
   239
	if (b->init && (in != NULL))
sl@0
   240
		{
sl@0
   241
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   242
			ret=UP_fwrite(in,(int)inl,1,b->ptr);
sl@0
   243
		else
sl@0
   244
			ret=fwrite(in,(int)inl,1,(FILE *)b->ptr);
sl@0
   245
		if (ret)
sl@0
   246
			ret=inl;
sl@0
   247
		/* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
sl@0
   248
		/* according to Tim Hudson <tjh@cryptsoft.com>, the commented
sl@0
   249
		 * out version above can cause 'inl' write calls under
sl@0
   250
		 * some stupid stdio implementations (VMS) */
sl@0
   251
		}
sl@0
   252
	return(ret);
sl@0
   253
	}
sl@0
   254
sl@0
   255
static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
sl@0
   256
	{
sl@0
   257
	long ret=1;
sl@0
   258
	FILE *fp=(FILE *)b->ptr;
sl@0
   259
	FILE **fpp;
sl@0
   260
	char p[4];
sl@0
   261
sl@0
   262
	switch (cmd)
sl@0
   263
		{
sl@0
   264
	case BIO_C_FILE_SEEK:
sl@0
   265
	case BIO_CTRL_RESET:
sl@0
   266
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   267
			ret=(long)UP_fseek(b->ptr,num,0);
sl@0
   268
		else
sl@0
   269
			ret=(long)fseek(fp,num,0);
sl@0
   270
		break;
sl@0
   271
	case BIO_CTRL_EOF:
sl@0
   272
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   273
			ret=(long)UP_feof(fp);
sl@0
   274
		else
sl@0
   275
			ret=(long)feof(fp);
sl@0
   276
		break;
sl@0
   277
	case BIO_C_FILE_TELL:
sl@0
   278
	case BIO_CTRL_INFO:
sl@0
   279
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   280
			ret=UP_ftell(b->ptr);
sl@0
   281
		else
sl@0
   282
			ret=ftell(fp);
sl@0
   283
		break;
sl@0
   284
	case BIO_C_SET_FILE_PTR:
sl@0
   285
		file_free(b);
sl@0
   286
		b->shutdown=(int)num&BIO_CLOSE;
sl@0
   287
		b->ptr=ptr;
sl@0
   288
		b->init=1;
sl@0
   289
#if BIO_FLAGS_UPLINK!=0
sl@0
   290
#if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
sl@0
   291
#define _IOB_ENTRIES 20
sl@0
   292
#endif
sl@0
   293
#if defined(_IOB_ENTRIES)
sl@0
   294
		/* Safety net to catch purely internal BIO_set_fp calls */
sl@0
   295
		if ((size_t)ptr >= (size_t)stdin &&
sl@0
   296
		    (size_t)ptr <  (size_t)(stdin+_IOB_ENTRIES))
sl@0
   297
			BIO_clear_flags(b,BIO_FLAGS_UPLINK);
sl@0
   298
#endif
sl@0
   299
#endif
sl@0
   300
#ifdef UP_fsetmode
sl@0
   301
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   302
			UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b');
sl@0
   303
		else
sl@0
   304
#endif
sl@0
   305
		{
sl@0
   306
#if defined(OPENSSL_SYS_WINDOWS)
sl@0
   307
		int fd = fileno((FILE*)ptr);
sl@0
   308
		if (num & BIO_FP_TEXT)
sl@0
   309
			_setmode(fd,_O_TEXT);
sl@0
   310
		else
sl@0
   311
			_setmode(fd,_O_BINARY);
sl@0
   312
#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
sl@0
   313
		int fd = fileno((FILE*)ptr);
sl@0
   314
         /* Under CLib there are differences in file modes
sl@0
   315
         */
sl@0
   316
		if (num & BIO_FP_TEXT)
sl@0
   317
			_setmode(fd,O_TEXT);
sl@0
   318
		else
sl@0
   319
			_setmode(fd,O_BINARY);
sl@0
   320
#elif defined(OPENSSL_SYS_MSDOS)
sl@0
   321
		int fd = fileno((FILE*)ptr);
sl@0
   322
		/* Set correct text/binary mode */
sl@0
   323
		if (num & BIO_FP_TEXT)
sl@0
   324
			_setmode(fd,_O_TEXT);
sl@0
   325
		/* Dangerous to set stdin/stdout to raw (unless redirected) */
sl@0
   326
		else
sl@0
   327
			{
sl@0
   328
			if (fd == STDIN_FILENO || fd == STDOUT_FILENO)
sl@0
   329
				{
sl@0
   330
				if (isatty(fd) <= 0)
sl@0
   331
					_setmode(fd,_O_BINARY);
sl@0
   332
				}
sl@0
   333
			else
sl@0
   334
				_setmode(fd,_O_BINARY);
sl@0
   335
			}
sl@0
   336
#elif defined(OPENSSL_SYS_OS2)
sl@0
   337
		int fd = fileno((FILE*)ptr);
sl@0
   338
		if (num & BIO_FP_TEXT)
sl@0
   339
			setmode(fd, O_TEXT);
sl@0
   340
		else
sl@0
   341
			setmode(fd, O_BINARY);
sl@0
   342
#endif
sl@0
   343
		}
sl@0
   344
		break;
sl@0
   345
	case BIO_C_SET_FILENAME:
sl@0
   346
		file_free(b);
sl@0
   347
		b->shutdown=(int)num&BIO_CLOSE;
sl@0
   348
		if (num & BIO_FP_APPEND)
sl@0
   349
			{
sl@0
   350
			if (num & BIO_FP_READ)
sl@0
   351
				BUF_strlcpy(p,"a+",sizeof p);
sl@0
   352
			else	BUF_strlcpy(p,"a",sizeof p);
sl@0
   353
			}
sl@0
   354
		else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
sl@0
   355
			BUF_strlcpy(p,"r+",sizeof p);
sl@0
   356
		else if (num & BIO_FP_WRITE)
sl@0
   357
			BUF_strlcpy(p,"w",sizeof p);
sl@0
   358
		else if (num & BIO_FP_READ)
sl@0
   359
			BUF_strlcpy(p,"r",sizeof p);
sl@0
   360
		else
sl@0
   361
			{
sl@0
   362
			BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
sl@0
   363
			ret=0;
sl@0
   364
			break;
sl@0
   365
			}
sl@0
   366
#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
sl@0
   367
		if (!(num & BIO_FP_TEXT))
sl@0
   368
			strcat(p,"b");
sl@0
   369
		else
sl@0
   370
			strcat(p,"t");
sl@0
   371
#endif
sl@0
   372
#if defined(OPENSSL_SYS_NETWARE)
sl@0
   373
		if (!(num & BIO_FP_TEXT))
sl@0
   374
			strcat(p,"b");
sl@0
   375
		else
sl@0
   376
			strcat(p,"t");
sl@0
   377
#endif
sl@0
   378
		fp=fopen(ptr,p);
sl@0
   379
		if (fp == NULL)
sl@0
   380
			{
sl@0
   381
			SYSerr(SYS_F_FOPEN,get_last_sys_error());
sl@0
   382
			ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
sl@0
   383
			BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
sl@0
   384
			ret=0;
sl@0
   385
			break;
sl@0
   386
			}
sl@0
   387
		b->ptr=fp;
sl@0
   388
		b->init=1;
sl@0
   389
		BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
sl@0
   390
		break;
sl@0
   391
	case BIO_C_GET_FILE_PTR:
sl@0
   392
		/* the ptr parameter is actually a FILE ** in this case. */
sl@0
   393
		if (ptr != NULL)
sl@0
   394
			{
sl@0
   395
			fpp=(FILE **)ptr;
sl@0
   396
			*fpp=(FILE *)b->ptr;
sl@0
   397
			}
sl@0
   398
		break;
sl@0
   399
	case BIO_CTRL_GET_CLOSE:
sl@0
   400
		ret=(long)b->shutdown;
sl@0
   401
		break;
sl@0
   402
	case BIO_CTRL_SET_CLOSE:
sl@0
   403
		b->shutdown=(int)num;
sl@0
   404
		break;
sl@0
   405
	case BIO_CTRL_FLUSH:
sl@0
   406
		if (b->flags&BIO_FLAGS_UPLINK)
sl@0
   407
			UP_fflush(b->ptr);
sl@0
   408
		else
sl@0
   409
			fflush((FILE *)b->ptr);
sl@0
   410
		break;
sl@0
   411
	case BIO_CTRL_DUP:
sl@0
   412
		ret=1;
sl@0
   413
		break;
sl@0
   414
sl@0
   415
	case BIO_CTRL_WPENDING:
sl@0
   416
	case BIO_CTRL_PENDING:
sl@0
   417
	case BIO_CTRL_PUSH:
sl@0
   418
	case BIO_CTRL_POP:
sl@0
   419
	default:
sl@0
   420
		ret=0;
sl@0
   421
		break;
sl@0
   422
		}
sl@0
   423
	return(ret);
sl@0
   424
	}
sl@0
   425
sl@0
   426
static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)
sl@0
   427
	{
sl@0
   428
	int ret=0;
sl@0
   429
sl@0
   430
	buf[0]='\0';
sl@0
   431
	if (bp->flags&BIO_FLAGS_UPLINK)
sl@0
   432
		UP_fgets(buf,size,bp->ptr);
sl@0
   433
	else
sl@0
   434
		fgets(buf,size,(FILE *)bp->ptr);
sl@0
   435
	if (buf[0] != '\0')
sl@0
   436
		ret=strlen(buf);
sl@0
   437
	return(ret);
sl@0
   438
	}
sl@0
   439
sl@0
   440
static int MS_CALLBACK file_puts(BIO *bp, const char *str)
sl@0
   441
	{
sl@0
   442
	int n,ret;
sl@0
   443
sl@0
   444
	n=strlen(str);
sl@0
   445
	ret=file_write(bp,str,n);
sl@0
   446
	return(ret);
sl@0
   447
	}
sl@0
   448
sl@0
   449
#endif /* OPENSSL_NO_STDIO */
sl@0
   450
sl@0
   451
#endif /* HEADER_BSS_FILE_C */
sl@0
   452
sl@0
   453