From a412b8919821efd00121d28cf2441c5445bee602 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sun, 6 Sep 2015 10:51:04 +0200 Subject: [PATCH] dup_bio_* and bio_open_* are utility functions and belong in apps.c Reviewed-by: Tim Hudson --- apps/apps.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++- apps/openssl.c | 150 ---------------------------------------------- 2 files changed, 158 insertions(+), 151 deletions(-) diff --git a/apps/apps.c b/apps/apps.c index f3b2d48f3a..0b5f9fd062 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -121,7 +121,13 @@ #if !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_WINCE) && !defined(NETWARE_CLIB) # include #endif -#include +#ifndef NO_SYS_TYPES_H +# include +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include +# include +#endif #include #include #include @@ -2707,3 +2713,154 @@ int raw_write_stdout(const void *buf, int siz) return write(fileno(stdout), buf, siz); } #endif + +/* + * Centralized handling if input and output files with format specification + * The format is meant to show what the input and output is supposed to be, + * and is therefore a show of intent more than anything else. However, it + * does impact behavior on some platform, such as differentiating between + * text and binary input/output on non-Unix platforms + */ +BIO *dup_bio_in(void) +{ + return BIO_new_fp(stdin, BIO_NOCLOSE | BIO_FP_TEXT); +} + +BIO *dup_bio_out(void) +{ + BIO *b = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); +#ifdef OPENSSL_SYS_VMS + b = BIO_push(BIO_new(BIO_f_linebuffer()), b); +#endif + return b; +} + +void unbuffer(FILE *fp) +{ + setbuf(fp, NULL); +} + +static const char *modestr(char mode, int format) +{ + OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w'); + + switch (mode) { + case 'a': + return (format & B_FORMAT_TEXT) ? "a" : "ab"; + case 'r': + return (format & B_FORMAT_TEXT) ? "r" : "rb"; + case 'w': + return (format & B_FORMAT_TEXT) ? "w" : "wb"; + } + /* The assert above should make sure we never reach this point */ + return NULL; +} + +static const char *modeverb(char mode) +{ + switch (mode) { + case 'a': + return "appending"; + case 'r': + return "reading"; + case 'w': + return "writing"; + } + return "(doing something)"; +} + +/* + * Open a file for writing, owner-read-only. + */ +BIO *bio_open_owner(const char *filename, int format, int private) +{ + FILE *fp = NULL; + BIO *b = NULL; + int fd = -1, bflags, mode, binmode; + + if (!private || filename == NULL || strcmp(filename, "-") == 0) + return bio_open_default(filename, 'w', format); + + mode = O_WRONLY; +#ifdef O_CREAT + mode |= O_CREAT; +#endif +#ifdef O_TRUNC + mode |= O_TRUNC; +#endif + binmode = !(format & B_FORMAT_TEXT); + if (binmode) { +#ifdef O_BINARY + mode |= O_BINARY; +#elif defined(_O_BINARY) + mode |= _O_BINARY; +#endif + } + + fd = open(filename, mode, 0600); + if (fd < 0) + goto err; + fp = fdopen(fd, modestr('w', format)); + if (fp == NULL) + goto err; + bflags = BIO_CLOSE; + if (!binmode) + bflags |= BIO_FP_TEXT; + b = BIO_new_fp(fp, bflags); + if (b) + return b; + + err: + BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n", + opt_getprog(), filename, strerror(errno)); + ERR_print_errors(bio_err); + /* If we have fp, then fdopen took over fd, so don't close both. */ + if (fp) + fclose(fp); + else if (fd >= 0) + close(fd); + return NULL; +} + +static BIO *bio_open_default_(const char *filename, char mode, int format, + int quiet) +{ + BIO *ret; + + if (filename == NULL || strcmp(filename, "-") == 0) { + ret = mode == 'r' ? dup_bio_in() : dup_bio_out(); + if (quiet) { + ERR_clear_error(); + return ret; + } + if (ret != NULL) + return ret; + BIO_printf(bio_err, + "Can't open %s, %s\n", + mode == 'r' ? "stdin" : "stdout", strerror(errno)); + } else { + ret = BIO_new_file(filename, modestr(mode, format)); + if (quiet) { + ERR_clear_error(); + return ret; + } + if (ret != NULL) + return ret; + BIO_printf(bio_err, + "Can't open %s for %s, %s\n", + filename, modeverb(mode), strerror(errno)); + } + ERR_print_errors(bio_err); + return NULL; +} + +BIO *bio_open_default(const char *filename, char mode, int format) +{ + return bio_open_default_(filename, mode, format, 0); +} + +BIO *bio_open_default_quiet(const char *filename, char mode, int format) +{ + return bio_open_default_(filename, mode, format, 1); +} + diff --git a/apps/openssl.c b/apps/openssl.c index bfd77a55b4..0208289fb6 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -132,13 +132,6 @@ #ifdef OPENSSL_SYS_VMS # include #endif -#ifndef NO_SYS_TYPES_H -# include -#endif -#ifndef OPENSSL_NO_POSIX_IO -# include -# include -#endif #define INCLUDE_FUNCTION_TABLE #include "apps.h" @@ -280,149 +273,6 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line) } } -BIO *dup_bio_in(void) -{ - return BIO_new_fp(stdin, BIO_NOCLOSE | BIO_FP_TEXT); -} - -BIO *dup_bio_out(void) -{ - BIO *b = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); -#ifdef OPENSSL_SYS_VMS - b = BIO_push(BIO_new(BIO_f_linebuffer()), b); -#endif - return b; -} - -void unbuffer(FILE *fp) -{ - setbuf(fp, NULL); -} - -static const char *modestr(char mode, int format) -{ - OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w'); - - switch (mode) { - case 'a': - return (format & B_FORMAT_TEXT) ? "a" : "ab"; - case 'r': - return (format & B_FORMAT_TEXT) ? "r" : "rb"; - case 'w': - return (format & B_FORMAT_TEXT) ? "w" : "wb"; - } - /* The assert above should make sure we never reach this point */ - return NULL; -} - -static const char *modeverb(char mode) -{ - switch (mode) { - case 'a': - return "appending"; - case 'r': - return "reading"; - case 'w': - return "writing"; - } - return "(doing something)"; -} - -/* - * Open a file for writing, owner-read-only. - */ -BIO *bio_open_owner(const char *filename, int format, int private) -{ - FILE *fp = NULL; - BIO *b = NULL; - int fd = -1, bflags, mode, binmode; - - if (!private || filename == NULL || strcmp(filename, "-") == 0) - return bio_open_default(filename, 'w', format); - - mode = O_WRONLY; -#ifdef O_CREAT - mode |= O_CREAT; -#endif -#ifdef O_TRUNC - mode |= O_TRUNC; -#endif - binmode = !(format & B_FORMAT_TEXT); - if (binmode) { -#ifdef O_BINARY - mode |= O_BINARY; -#elif defined(_O_BINARY) - mode |= _O_BINARY; -#endif - } - - fd = open(filename, mode, 0600); - if (fd < 0) - goto err; - fp = fdopen(fd, modestr('w', format)); - if (fp == NULL) - goto err; - bflags = BIO_CLOSE; - if (!binmode) - bflags |= BIO_FP_TEXT; - b = BIO_new_fp(fp, bflags); - if (b) - return b; - - err: - BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n", - opt_getprog(), filename, strerror(errno)); - ERR_print_errors(bio_err); - /* If we have fp, then fdopen took over fd, so don't close both. */ - if (fp) - fclose(fp); - else if (fd >= 0) - close(fd); - return NULL; -} - -static BIO *bio_open_default_(const char *filename, char mode, int format, - int quiet) -{ - BIO *ret; - - if (filename == NULL || strcmp(filename, "-") == 0) { - ret = mode == 'r' ? dup_bio_in() : dup_bio_out(); - if (quiet) { - ERR_clear_error(); - return ret; - } - if (ret != NULL) - return ret; - BIO_printf(bio_err, - "Can't open %s, %s\n", - mode == 'r' ? "stdin" : "stdout", strerror(errno)); - } else { - ret = BIO_new_file(filename, modestr(mode, format)); - if (quiet) { - ERR_clear_error(); - return ret; - } - if (ret != NULL) - return ret; - BIO_printf(bio_err, - "Can't open %s for %s, %s\n", - filename, modeverb(mode), strerror(errno)); - } - ERR_print_errors(bio_err); - return NULL; -} - -BIO *bio_open_default(const char *filename, char mode, int format) -{ - return bio_open_default_(filename, mode, format, 0); -} - -BIO *bio_open_default_quiet(const char *filename, char mode, int format) -{ - return bio_open_default_(filename, mode, format, 1); -} - #if defined( OPENSSL_SYS_VMS) extern char **copy_argv(int *argc, char **argv); #endif -- 2.25.1