/* * Copyright 2003-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "e_os.h" #include #include #include "internal/cryptlib.h" size_t OPENSSL_strnlen(const char *str, size_t maxlen) { const char *p; for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; return p - str; } size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size) { size_t l = 0; for (; size > 1 && *src; size--) { *dst++ = *src++; l++; } if (size) *dst = '\0'; return l + strlen(src); } size_t OPENSSL_strlcat(char *dst, const char *src, size_t size) { size_t l = 0; for (; size > 0 && *dst; size--, dst++) l++; return l + OPENSSL_strlcpy(dst, src, size); } int OPENSSL_hexchar2int(unsigned char c) { #ifdef CHARSET_EBCDIC c = os_toebcdic[c]; #endif switch (c) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'a': case 'A': return 0x0A; case 'b': case 'B': return 0x0B; case 'c': case 'C': return 0x0C; case 'd': case 'D': return 0x0D; case 'e': case 'E': return 0x0E; case 'f': case 'F': return 0x0F; } return -1; } int openssl_strerror_r(int errnum, char *buf, size_t buflen) { #if defined(_MSC_VER) && _MSC_VER>=1400 return !strerror_s(buf, buflen, errnum); #elif defined(_GNU_SOURCE) char *err; /* * GNU strerror_r may not actually set buf. * It can return a pointer to some (immutable) static string in which case * buf is left unused. */ err = strerror_r(errnum, buf, buflen); if (err == NULL || buflen == 0) return 0; /* * If err is statically allocated, err != buf and we need to copy the data. * If err points somewhere inside buf, OPENSSL_strlcpy can handle this, * since src and dest are not annotated with __restrict and the function * reads src byte for byte and writes to dest. * If err == buf we do not have to copy anything. */ if (err != buf) OPENSSL_strlcpy(buf, err, buflen); return 1; #elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) /* * We can use "real" strerror_r. The OpenSSL version differs in that it * gives 1 on success and 0 on failure for consistency with other OpenSSL * functions. Real strerror_r does it the other way around */ return !strerror_r(errnum, buf, buflen); #else char *err; /* Fall back to non-thread safe strerror()...its all we can do */ if (buflen < 2) return 0; err = strerror(errnum); /* Can this ever happen? */ if (err == NULL) return 0; OPENSSL_strlcpy(buf, err, buflen); return 1; #endif }