X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbio%2Fbss_file.c;h=8bfa0bcd97d7a2a9052f4f63d1a9860f92a3cf53;hp=b7504baf20d4f9ce1f3655bd9c31e3f8c4866c82;hb=bb92e2c89b4aee9e1d1bb27a4a6da3817c66d005;hpb=8c5a2bd6bb9a8c2bb3e1b63c03e57bb1115275d1 diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index b7504baf20..8bfa0bcd97 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -89,6 +89,10 @@ #include "bio_lcl.h" #include +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) +#include +#endif + #if !defined(OPENSSL_NO_STDIO) static int MS_CALLBACK file_write(BIO *h, const char *buf, int num); @@ -114,10 +118,47 @@ static BIO_METHOD methods_filep= BIO *BIO_new_file(const char *filename, const char *mode) { - BIO *ret; - FILE *file; + BIO *ret; + FILE *file=NULL; + +#if defined(_WIN32) && defined(CP_UTF8) + int sz, len_0 = (int)strlen(filename)+1; - if ((file=fopen(filename,mode)) == NULL) + /* + * Basically there are three cases to cover: a) filename is + * pure ASCII string; b) actual UTF-8 encoded string and + * c) locale-ized string, i.e. one containing 8-bit + * characters that are meaningful in current system locale. + * If filename is pure ASCII or real UTF-8 encoded string, + * MultiByteToWideChar succeeds and _wfopen works. If + * filename is locale-ized string, chances are that + * MultiByteToWideChar fails reporting + * ERROR_NO_UNICODE_TRANSLATION, in which case we fall + * back to fopen... + */ + if ((sz=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,NULL,0))>0) + { + WCHAR wmode[8]; + WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); + + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,wfilename,sz) && + MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1, + wmode,sizeof(wmode)/sizeof(wmode[0])) && + (file=_wfopen(wfilename,wmode))==NULL && errno==ENOENT + ) /* UTF-8 decode succeeded, but no file, filename + * could still have been locale-ized... */ + file = fopen(filename,mode); + } + else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) + { + file = fopen(filename,mode); + } +#else + file=fopen(filename,mode); +#endif + if (file == NULL) { SYSerr(SYS_F_FOPEN,get_last_sys_error()); ERR_add_error_data(5,"fopen('",filename,"','",mode,"')"); @@ -268,14 +309,14 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_clear_flags(b,BIO_FLAGS_UPLINK); #endif #endif -#ifdef UP_fsetmode +#ifdef UP_fsetmod if (b->flags&BIO_FLAGS_UPLINK) - UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b'); + UP_fsetmod(b->ptr,(char)((num&BIO_FP_TEXT)?'t':'b')); else #endif { #if defined(OPENSSL_SYS_WINDOWS) - int fd = fileno((FILE*)ptr); + int fd = _fileno((FILE*)ptr); if (num & BIO_FP_TEXT) _setmode(fd,_O_TEXT); else @@ -284,9 +325,9 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) int fd = fileno((FILE*)ptr); /* Under CLib there are differences in file modes */ if (num & BIO_FP_TEXT) - _setmode(fd,O_TEXT); + setmode(fd,O_TEXT); else - _setmode(fd,O_BINARY); + setmode(fd,O_BINARY); #elif defined(OPENSSL_SYS_MSDOS) int fd = fileno((FILE*)ptr); /* Set correct text/binary mode */ @@ -399,11 +440,18 @@ static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) buf[0]='\0'; if (bp->flags&BIO_FLAGS_UPLINK) - UP_fgets(buf,size,bp->ptr); + { + if (!UP_fgets(buf,size,bp->ptr)) + goto err; + } else - fgets(buf,size,(FILE *)bp->ptr); + { + if (!fgets(buf,size,(FILE *)bp->ptr)) + goto err; + } if (buf[0] != '\0') ret=strlen(buf); + err: return(ret); }