From aa4d426b4d3527d7e166df1a05058c9a4a0f6683 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 30 Apr 2021 00:33:56 +0200 Subject: initial/final commit --- .../src/vmime/platforms/posix/posixHandler.cpp | 292 +++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 vmime-master/src/vmime/platforms/posix/posixHandler.cpp (limited to 'vmime-master/src/vmime/platforms/posix/posixHandler.cpp') diff --git a/vmime-master/src/vmime/platforms/posix/posixHandler.cpp b/vmime-master/src/vmime/platforms/posix/posixHandler.cpp new file mode 100644 index 0000000..eecdbea --- /dev/null +++ b/vmime-master/src/vmime/platforms/posix/posixHandler.cpp @@ -0,0 +1,292 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_POSIX + + +#include "vmime/platforms/posix/posixHandler.hpp" + +#include "vmime/platforms/posix/posixCriticalSection.hpp" + +#include "vmime/utility/stringUtils.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if VMIME_HAVE_SYSCALL +# include +#endif + +#include + +#include +#include +#include + + +/* +#ifdef _POSIX_PRIORITY_SCHEDULING + #include +#endif // _POSIX_PRIORITY_SCHEDULING +*/ + + +namespace vmime { +namespace platforms { +namespace posix { + + +posixHandler::posixHandler() { + +#if VMIME_HAVE_MESSAGING_FEATURES + m_socketFactory = make_shared (); +#endif +#if VMIME_HAVE_FILESYSTEM_FEATURES + m_fileSysFactory = make_shared (); + m_childProcFactory = make_shared (); +#endif + +} + + +posixHandler::~posixHandler() { + +} + + +unsigned long posixHandler::getUnixTime() const { + + return static_cast (::time(NULL)); +} + + +const vmime::datetime posixHandler::getCurrentLocalTime() const { + + const time_t t(::time(NULL)); + + // Get the local time +#if VMIME_HAVE_LOCALTIME_R + tm local; + ::localtime_r(&t, &local); +#else + tm local = *::localtime(&t); // WARNING: this is not thread-safe! +#endif + + // Get the UTC time +#if VMIME_HAVE_GMTIME_R + tm gmt; + ::gmtime_r(&t, &gmt); +#else + tm gmt = *::gmtime(&t); // WARNING: this is not thread-safe! +#endif + + // "A negative value for tm_isdst causes mktime() to attempt + // to determine whether Daylight Saving Time is in effect + // for the specified time." + local.tm_isdst = -1; + gmt.tm_isdst = -1; + + // Calculate the difference (in seconds) + const time_t diff = ::mktime(&local) - ::mktime(&gmt); + + // Return the date + return vmime::datetime( + local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, + local.tm_hour, local.tm_min, local.tm_sec, static_cast (diff / 60) + ); +} + + +const vmime::charset posixHandler::getLocalCharset() const { + + // Note: nl_langinfo() might be affected by calls to setlocale() + // in a multithread environment. There is not MT-safe alternative + // to nl_langinfo(). + auto codeset = ::nl_langinfo(CODESET); + + if (codeset) { + return vmime::charset(codeset); + } + + return vmime::charset(); +} + + +static inline bool isAcceptableHostname(const vmime::string& str) { + + // At least, try to find something better than "localhost" + if (utility::stringUtils::isStringEqualNoCase(str, "localhost", 9) || + utility::stringUtils::isStringEqualNoCase(str, "localhost.localdomain", 21)) { + + return false; + } + + // Anything else will be OK, as long as it is a valid hostname + return utility::stringUtils::isValidHostname(str); +} + + +const vmime::string posixHandler::getHostName() const { + char hostname[256]; + + ::gethostname(hostname, sizeof(hostname)); + hostname[sizeof(hostname)-1] = '\0'; + + // Try to get official canonical name of this host + struct addrinfo hints; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // either IPV4 or IPV6 + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + + struct addrinfo* info; + + if (getaddrinfo(hostname, "http", &hints, &info) == 0) { + // First, try to get a Fully-Qualified Domain Name (FQDN) + for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) { + + if (p->ai_canonname) { + + const string hn(p->ai_canonname); + + if (utility::stringUtils::isValidFQDN(hn)) { + freeaddrinfo(info); + return hn; + } + } + } + + // Then, try to find an acceptable host name + for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) { + + if (p->ai_canonname) { + + const string hn(p->ai_canonname); + + if (isAcceptableHostname(hn)) { + freeaddrinfo(info); + return hn; + } + } + } + + freeaddrinfo(info); + } + + if (::strlen(hostname) == 0 || !isAcceptableHostname(hostname)) { + ::strcpy(hostname, "localhost.localdomain"); + } + + return hostname; +} + + +unsigned int posixHandler::getProcessId() const { + + return ::getpid(); +} + + +unsigned int posixHandler::getThreadId() const { + +#if VMIME_HAVE_GETTID + return static_cast (::gettid()); +#elif VMIME_HAVE_SYSCALL && VMIME_HAVE_SYSCALL_GETTID + return static_cast (::syscall(SYS_gettid)); +#elif VMIME_HAVE_GETTHRID // OpenBSD + return static_cast (::getthrid()); +#else + #error We have no implementation of getThreadId() for this platform! +#endif + +} + + +#if VMIME_HAVE_MESSAGING_FEATURES + +shared_ptr posixHandler::getSocketFactory() { + + return m_socketFactory; +} + +#endif + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + +shared_ptr posixHandler::getFileSystemFactory() { + + return m_fileSysFactory; +} + + +shared_ptr posixHandler::getChildProcessFactory() { + + return m_childProcFactory; +} + +#endif + + +void posixHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count) { + + int fd = open("/dev/urandom", O_RDONLY); + + if (fd != -1) { + + read(fd, buffer, count); + close(fd); + + } else { // fallback + + for (unsigned int i = 0 ; i < count ; ++i) { + buffer[i] = static_cast (rand() % 255); + } + } +} + + +shared_ptr posixHandler::createCriticalSection() { + + return make_shared (); +} + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_POSIX -- cgit v1.2.3