diff --git a/configure.ac b/configure.ac index 24b851e4..489bddb2 100644 --- a/configure.ac +++ b/configure.ac @@ -341,7 +341,7 @@ case $host in ;; esac -AC_CHECK_FUNCS(gettimeofday select strtoll memset_s) +AC_CHECK_FUNCS(gettimeofday select strtoll memset_s snprintf) dnl Check for select() into ws2_32 for Msys/Mingw if test "$ac_cv_func_select" != "yes"; then diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 3dc115ef..3198c4d6 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -90,8 +90,6 @@ check_include_files(winsock2.h HAVE_WINSOCK2_H) check_symbol_exists(strcasecmp strings.h HAVE_STRCASECMP) check_symbol_exists(_stricmp string.h HAVE__STRICMP) -check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF) -check_symbol_exists(_snprintf stdio.h HAVE__SNPRINTF) check_symbol_exists(__func__ "" HAVE___FUNC__) check_symbol_exists(__FUNCTION__ "" HAVE___FUNCTION__) diff --git a/example/libssh2_config_cmake.h.in b/example/libssh2_config_cmake.h.in index 12264f7f..bdcbe849 100644 --- a/example/libssh2_config_cmake.h.in +++ b/example/libssh2_config_cmake.h.in @@ -48,8 +48,6 @@ /* Functions */ #cmakedefine HAVE_STRCASECMP #cmakedefine HAVE__STRICMP -#cmakedefine HAVE_SNPRINTF -#cmakedefine HAVE__SNPRINTF /* Workaround for platforms without POSIX strcasecmp (e.g. Windows) */ #ifndef HAVE_STRCASECMP diff --git a/example/subsystem_netconf.c b/example/subsystem_netconf.c index e53cfa5f..1b17bf67 100644 --- a/example/subsystem_netconf.c +++ b/example/subsystem_netconf.c @@ -37,10 +37,8 @@ #define INADDR_NONE (in_addr_t)~0 #endif -#ifndef HAVE_SNPRINTF -# ifdef HAVE__SNPRINTF -# define snprintf _snprintf -# endif +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf #endif const char *keyfile1 = "/home/username/.ssh/id_rsa.pub"; diff --git a/nw/GNUmakefile b/nw/GNUmakefile index 8899fdd8..4098b51f 100644 --- a/nw/GNUmakefile +++ b/nw/GNUmakefile @@ -424,6 +424,7 @@ ifdef ENABLE_IPV6 @echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@ endif endif + @echo $(DL)#define HAVE_SNPRINTF 1$(DL) >> $@ @echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@ @echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@ diff --git a/os400/libssh2_config.h b/os400/libssh2_config.h index 6ec04da1..5aa8e20b 100644 --- a/os400/libssh2_config.h +++ b/os400/libssh2_config.h @@ -212,6 +212,10 @@ /* Use OS/400 Qc3 */ #define LIBSSH2_OS400QC3 +/* Use our platform-specific local implementation: + _libssh2_os400_snprintf */ +#define HAVE_SNPRINTF 1 + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" diff --git a/src/libssh2_config_cmake.h.in b/src/libssh2_config_cmake.h.in index 40047924..4a915815 100644 --- a/src/libssh2_config_cmake.h.in +++ b/src/libssh2_config_cmake.h.in @@ -76,29 +76,3 @@ #cmakedefine HAVE_IOCTLSOCKET_CASE #cmakedefine HAVE_SO_NONBLOCK #cmakedefine HAVE_DISABLED_NONBLOCKING - -/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible. - We provide a safe wrapper if snprintf not found */ -#ifndef HAVE_SNPRINTF -#include -#include -/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1 -* then assume cp is pointing to a null char and do nothing. Returns number -* number of chars placed in cp excluding the trailing null char. So for -* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len -* <= 0 the return value is 0 (and no chars are written to cp). */ -static int snprintf(char * cp, int cp_max_len, const char * fmt, ...) -{ - va_list args; - int n; - - if (cp_max_len < 2) - return 0; - va_start(args, fmt); - n = vsnprintf(cp, cp_max_len, fmt, args); - va_end(args); - return (n < cp_max_len) ? n : (cp_max_len - 1); -} - -#define HAVE_SNPRINTF -#endif diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index 4bf17f9f..44bfb12e 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -126,6 +126,12 @@ #define TRUE 1 #endif +/* Use local implementation when not available */ +#if !defined(HAVE_SNPRINTF) +#define LIBSSH2_SNPRINTF +#define snprintf _libssh2_snprintf +#endif + #ifdef _MSC_VER /* "inline" keyword is valid only with C++ engine! */ #define inline __inline diff --git a/src/misc.c b/src/misc.c index 933a2041..686401c1 100644 --- a/src/misc.c +++ b/src/misc.c @@ -60,6 +60,30 @@ #include #include +/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible. + We provide a safe wrapper if snprintf not found */ +#ifdef LIBSSH2_SNPRINTF +#include + +/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1 +* then assume cp is pointing to a null char and do nothing. Returns number +* number of chars placed in cp excluding the trailing null char. So for +* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len +* <= 0 the return value is 0 (and no chars are written to cp). */ +int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...) +{ + va_list args; + int n; + + if(cp_max_len < 2) + return 0; + va_start(args, fmt); + n = vsnprintf(cp, cp_max_len, fmt, args); + va_end(args); + return (n < cp_max_len) ? n : (cp_max_len - 1); +} +#endif + int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char *errmsg, int errflags) { diff --git a/tests/libssh2_config_cmake.h.in b/tests/libssh2_config_cmake.h.in index f75711a3..cbcdec23 100644 --- a/tests/libssh2_config_cmake.h.in +++ b/tests/libssh2_config_cmake.h.in @@ -42,30 +42,3 @@ #cmakedefine HAVE_ARPA_INET_H #cmakedefine HAVE_NETINET_IN_H #cmakedefine HAVE_WINSOCK2_H -#cmakedefine HAVE_SNPRINTF - -/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible. - We provide a safe wrapper if snprintf not found */ -#ifndef HAVE_SNPRINTF -#include -#include -/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1 -* then assume cp is pointing to a null char and do nothing. Returns number -* number of chars placed in cp excluding the trailing null char. So for -* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len -* <= 0 the return value is 0 (and no chars are written to cp). */ -static int snprintf(char *cp, int cp_max_len, const char *fmt, ...) -{ - va_list args; - int n; - - if (cp_max_len < 2) - return 0; - va_start(args, fmt); - n = vsnprintf(cp, cp_max_len, fmt, args); - va_end(args); - return (n < cp_max_len) ? n : (cp_max_len - 1); -} - -#define HAVE_SNPRINTF -#endif diff --git a/tests/session_fixture.h b/tests/session_fixture.h index f42d1dc8..3820a5a9 100644 --- a/tests/session_fixture.h +++ b/tests/session_fixture.h @@ -40,6 +40,10 @@ #include +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif + LIBSSH2_SESSION *start_session_fixture(void); void stop_session_fixture(void); void print_last_session_error(const char *function); diff --git a/vms/libssh2_config.h b/vms/libssh2_config.h index b8f73e27..45a49b5a 100644 --- a/vms/libssh2_config.h +++ b/vms/libssh2_config.h @@ -25,6 +25,7 @@ typedef unsigned int socklen_t; /* missing in headers on VMS */ #define HAVE_ARPA_INET_H #define HAVE_GETTIMEOFDAY 1 +#define HAVE_SNPRINTF 1 #define POSIX_C_SOURCE diff --git a/win32/libssh2_config.h b/win32/libssh2_config.h index 0da35c48..a497eab5 100644 --- a/win32/libssh2_config.h +++ b/win32/libssh2_config.h @@ -4,38 +4,36 @@ #ifndef WIN32 #define WIN32 #endif + #ifndef _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE 1 -#endif /* _CRT_SECURE_NO_DEPRECATE */ - -#ifdef __MINGW32__ -#define HAVE_UNISTD_H -#define HAVE_INTTYPES_H -#define HAVE_SYS_TIME_H -#define HAVE_GETTIMEOFDAY -#endif /* __MINGW32__ */ +#endif #define HAVE_LIBCRYPT32 #define HAVE_WINSOCK2_H #define HAVE_IOCTLSOCKET #define HAVE_SELECT +#define HAVE_SNPRINTF -#ifdef _MSC_VER -#if _MSC_VER < 1900 -#define snprintf _snprintf -#if _MSC_VER < 1500 -#define vsnprintf _vsnprintf -#endif -#define strdup _strdup -#define strncasecmp _strnicmp -#define strcasecmp _stricmp -#endif +#ifdef __MINGW32__ +# define HAVE_UNISTD_H +# define HAVE_INTTYPES_H +# define HAVE_SYS_TIME_H +# define HAVE_GETTIMEOFDAY +#elif defined(_MSC_VER) +# if _MSC_VER < 1900 +# undef HAVE_SNPRINTF +# if _MSC_VER < 1500 +# define vsnprintf _vsnprintf +# endif +# define strdup _strdup +# define strncasecmp _strnicmp +# define strcasecmp _stricmp +# endif #else -#ifndef __MINGW32__ -#define strncasecmp strnicmp -#define strcasecmp stricmp -#endif /* __MINGW32__ */ -#endif /* _MSC_VER */ +# define strncasecmp strnicmp +# define strcasecmp stricmp +#endif /* Enable newer diffie-hellman-group-exchange-sha1 syntax */ #define LIBSSH2_DH_GEX_NEW 1