X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=crypto%2Frand%2Frandfile.c;h=19cce2c7a83674732d874486ba7bdd9ffdb3fed1;hb=13c03c8d6da334bb1cde6ce4133e7c75b3b76947;hp=a40b2864f006bd6eefdc1a17b9e1c283c2d80641;hpb=b1322259d93cf6b6286f9febcd468b6a9f577d91;p=openssl.git diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index a40b2864f0..19cce2c7a8 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -9,11 +9,6 @@ #include "e_os.h" -/* We need to define this to get macros like S_IFBLK and S_IFCHR */ -#if !defined(OPENSSL_SYS_VXWORKS) -# define _XOPEN_SOURCE 500 -#endif - #include #include #include @@ -32,6 +27,29 @@ #ifndef OPENSSL_NO_POSIX_IO # include # include +/* + * Following should not be needed, and we could have been stricter + * and demand S_IS*. But some systems just don't comply... Formally + * below macros are "anatomically incorrect", because normally they + * would look like ((m) & MASK == TYPE), but since MASK availability + * is as questionable, we settle for this poor-man fallback... + */ +# if !defined(S_ISBLK) +# if defined(_S_IFBLK) +# define S_ISBLK(m) ((m) & _S_IFBLK) +# elif defined(S_IFBLK) +# define S_ISBLK(m) ((m) & S_IFBLK) +# elif defined(_WIN32) +# define S_ISBLK(m) 0 /* no concept of block devices on Windows */ +# endif +# endif +# if !defined(S_ISCHR) +# if defined(_S_IFCHR) +# define S_ISCHR(m) ((m) & _S_IFCHR) +# elif defined(S_IFCHR) +# define S_ISCHR(m) ((m) & S_IFCHR) +# endif +# endif #endif #ifdef _WIN32 @@ -46,13 +64,46 @@ #define RAND_DATA 1024 #ifdef OPENSSL_SYS_VMS +/* + * Misc hacks needed for specific cases. + * + * __FILE_ptr32 is a type provided by DEC C headers (types.h specifically) + * to make sure the FILE* is a 32-bit pointer no matter what. We know that + * stdio function return this type (a study of stdio.h proves it). + * Additionally, we create a similar char pointer type for the sake of + * vms_setbuf below. + */ +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +# endif +typedef char *char_ptr32; +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size restore +# endif + +/* + * On VMS, setbuf() will only take 32-bit pointers, and a compilation + * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here. + * Since we know that the FILE* really is a 32-bit pointer expanded to + * 64 bits, we also know it's safe to convert it back to a 32-bit pointer. + * As for the buffer parameter, we only use NULL here, so that passes as + * well... + */ +static void vms_setbuf(FILE *fp, char *buf) +{ + setbuf((__FILE_ptr32)fp, (char_ptr32)buf); +} /* * This declaration is a nasty hack to get around vms' extension to fopen for - * passing in sharing options being disabled by our /STANDARD=ANSI89 + * passing in sharing options being disabled by /STANDARD=ANSI89 */ -static FILE *(*const vms_fopen)(const char *, const char *, ...) = - (FILE *(*)(const char *, const char *, ...))fopen; +static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) = + (__FILE_ptr32 (*)(const char *, const char *, ...))fopen; # define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0" + +# define fopen(fname,mode) vms_fopen((fname), (mode), VMS_OPEN_ATTRS) +# define setbuf(fp,buf) vms_setbuf((fp), (buf)) #endif #define RFILE ".rnd" @@ -94,22 +145,18 @@ int RAND_load_file(const char *file, long bytes) if (bytes == 0) return (ret); -#ifdef OPENSSL_SYS_VMS - in = vms_fopen(file, "rb", VMS_OPEN_ATTRS); -#else in = fopen(file, "rb"); -#endif if (in == NULL) goto err; -#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO) - if (sb.st_mode & (S_IFBLK | S_IFCHR)) { +#if defined(S_ISBLK) && defined(S_ISCHR) && !defined(OPENSSL_NO_POSIX_IO) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { /* * this file is a device. we don't want read an infinite number of * bytes from a random device, nor do we want to use buffered I/O * because we will waste system entropy. */ bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ - setbuf(stdin, NULL); /* don't do buffered reads */ + setbuf(in, NULL); /* don't do buffered reads */ } #endif for (;;) { @@ -194,13 +241,10 @@ int RAND_write_file(const char *file) * rand file in a concurrent use situation. */ - out = vms_fopen(file, "rb+", VMS_OPEN_ATTRS); - if (out == NULL) - out = vms_fopen(file, "wb", VMS_OPEN_ATTRS); -#else + out = fopen(file, "rb+"); +#endif if (out == NULL) out = fopen(file, "wb"); -#endif if (out == NULL) goto err; @@ -242,8 +286,22 @@ const char *RAND_file_name(char *buf, size_t size) if (OPENSSL_strlcpy(buf, s, size) >= size) return NULL; } else { +#ifdef OPENSSL_SYS_WINDOWS + /* + * We use the same env variables as GetTempFile() - but that function + * uses TCHARs, but getenv() gives us chars so its easier to do it this + * way + */ + if ((s = getenv("TMP")) == NULL + && (s = getenv("TEMP")) == NULL + && (s = getenv("USERPROFILE")) == NULL + && (s = getenv("SYSTEMROOT")) == NULL) { + s = getenv("HOME"); + } +#else if (OPENSSL_issetugid() == 0) s = getenv("HOME"); +#endif #ifdef DEFAULT_HOME if (s == NULL) { s = DEFAULT_HOME;