From 48397a91cfa722169410c1a805cc803fd6ff7784 Mon Sep 17 00:00:00 2001 From: Stefan Uhrig Date: Sun, 27 Mar 2005 18:26:25 +0000 Subject: [PATCH] Added windows platform handlers. --- ChangeLog | 4 + config.hpp.msvc | 60 +++ src/platforms/windows/windowsFile.cpp | 460 +++++++++++++++++++++ src/platforms/windows/windowsHandler.cpp | 213 ++++++++++ src/platforms/windows/windowsSocket.cpp | 181 ++++++++ vmime/platforms/windows/windowsFile.hpp | 186 +++++++++ vmime/platforms/windows/windowsHandler.hpp | 87 ++++ vmime/platforms/windows/windowsSocket.hpp | 74 ++++ 8 files changed, 1265 insertions(+) create mode 100644 config.hpp.msvc create mode 100644 src/platforms/windows/windowsFile.cpp create mode 100644 src/platforms/windows/windowsHandler.cpp create mode 100644 src/platforms/windows/windowsSocket.cpp create mode 100644 vmime/platforms/windows/windowsFile.hpp create mode 100644 vmime/platforms/windows/windowsHandler.hpp create mode 100644 vmime/platforms/windows/windowsSocket.hpp diff --git a/ChangeLog b/ChangeLog index bcbeb3d7..10488506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ VERSION 0.6.4cvs ================ +2005-03-27 Stefan Uhrig + + * Added Windows platform handlers. + 2005-03-27 Vincent Richard * messageIdSequence.{cpp|hpp}: added a new basic type "messageIdSequence" for diff --git a/config.hpp.msvc b/config.hpp.msvc new file mode 100644 index 00000000..09678355 --- /dev/null +++ b/config.hpp.msvc @@ -0,0 +1,60 @@ + +// +// This file was automatically generated by configuration script. +// + +#ifndef VMIME_CONFIG_HPP_INCLUDED +#define VMIME_CONFIG_HPP_INCLUDED + + +// Name of package +#define VMIME_PACKAGE "libvmime" + +// Version number of package +#define VMIME_VERSION "0.6.4" +#define VMIME_API "6:4:6" + +// Target OS and architecture +#define VMIME_TARGET_ARCH "i686" +#define VMIME_TARGET_OS "msvc" + +// Set to 1 if debugging should be activated +#define VMIME_DEBUG 0 + +// Byte order (set one or the other, but not both!) +#define VMIME_BYTE_ORDER_BIG_ENDIAN 0 +#define VMIME_BYTE_ORDER_LITTLE_ENDIAN 1 + +// Generic types +// -- 8-bit +typedef signed char vmime_int8; +typedef unsigned char vmime_uint8; +// -- 16-bit +typedef signed short vmime_int16; +typedef unsigned short vmime_uint16; +// -- 32-bit +typedef signed int vmime_int32; +typedef unsigned int vmime_uint32; + +// Options +// -- Wide characters support +#define VMIME_WIDE_CHAR_SUPPORT 0 +#define VMIME_INLINE_TEMPLATE_SPECIALIZATION 1 +#define VMIME_NO_MULTIPLE_INHERITANCE 1 +// -- File-system support +#define VMIME_HAVE_FILESYSTEM_FEATURES 1 +// -- Messaging support +#define VMIME_HAVE_MESSAGING_FEATURES 1 +// -- Built-in messaging protocols +#define VMIME_BUILTIN_MESSAGING_PROTOS " pop3 smtp imap maildir" +#define VMIME_BUILTIN_MESSAGING_PROTO_POP3 1 +#define VMIME_BUILTIN_MESSAGING_PROTO_SMTP 1 +#define VMIME_BUILTIN_MESSAGING_PROTO_IMAP 1 +#define VMIME_BUILTIN_MESSAGING_PROTO_MAILDIR 1 +// -- Built-in platform handlers +#define VMIME_BUILTIN_PLATFORMS " windows" +#define VMIME_BUILTIN_PLATFORM_WINDOWS 1 + + +#endif // VMIME_CONFIG_HPP_INCLUDED + diff --git a/src/platforms/windows/windowsFile.cpp b/src/platforms/windows/windowsFile.cpp new file mode 100644 index 00000000..04298120 --- /dev/null +++ b/src/platforms/windows/windowsFile.cpp @@ -0,0 +1,460 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2005 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "vmime/platforms/windows/windowsFile.hpp" + +#include +#include + +#include "vmime/exception.hpp" + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + + +namespace vmime { +namespace platforms { +namespace windows { + + +vmime::utility::file* windowsFileSystemFactory::create(const vmime::utility::file::path& path) const +{ + return new windowsFile(path); +} + + +const vmime::utility::file::path windowsFileSystemFactory::stringToPath(const vmime::string& str) const +{ + return (stringToPathImpl(str)); +} + + +const vmime::string windowsFileSystemFactory::pathToString(const vmime::utility::file::path& path) const +{ + return (pathToStringImpl(path)); +} + + +const vmime::utility::file::path windowsFileSystemFactory::stringToPathImpl(const vmime::string& str) +{ + vmime::string::size_type offset = 0; + vmime::string::size_type prev = 0; + + vmime::utility::file::path path; + + while ((offset = str.find_first_of("\\", offset)) != vmime::string::npos) + { + if (offset != prev) + path.appendComponent(vmime::string(str.begin() + prev, str.begin() + offset)); + + prev = offset + 1; + offset++; + } + + if (prev < str.length()) + path.appendComponent(vmime::string(str.begin() + prev, str.end())); + + return (path); +} + + +const vmime::string windowsFileSystemFactory::pathToStringImpl(const vmime::utility::file::path& path) +{ + vmime::string native = ""; + + for (int i = 0 ; i < path.getSize() ; ++i) + { + if (i > 0) + native += "\\"; + + native += path[i].getBuffer(); + } + + return (native); +} + + +const bool windowsFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const +{ + return (comp.getBuffer().find_first_of("\\*") == vmime::string::npos); +} + + +const bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const +{ + for (int i = 0 ; i < path.getSize() ; ++i) + { + if (!isValidPathComponent(path[i])) + return false; + } + + return true; +} + + +void windowsFileSystemFactory::reportError(const vmime::utility::path& path, const int err) +{ + vmime::string desc; + + LPVOID lpMsgBuf; + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL )) + { + desc = (char*)lpMsgBuf; + LocalFree( lpMsgBuf ); + } + + throw vmime::exceptions::filesystem_exception(desc, path); +} + +windowsFile::windowsFile(const vmime::utility::file::path& path) +: m_path(path), m_nativePath(windowsFileSystemFactory::pathToStringImpl(path)) +{ +} + +void windowsFile::createFile() +{ + HANDLE hFile = CreateFile( + m_nativePath.c_str(), + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + windowsFileSystemFactory::reportError(m_path, GetLastError()); + + CloseHandle(hFile); +} + +void windowsFile::createDirectory(const bool createAll) +{ + createDirectoryImpl(m_path, m_path, createAll); +} + +const bool windowsFile::isFile() const +{ + DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str()); + if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) + return false; + return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == 0; +} + +const bool windowsFile::isDirectory() const +{ + DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str()); + if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) + return false; + return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; +} + +const bool windowsFile::canRead() const +{ + HANDLE hFile = CreateFile( + m_nativePath.c_str(), + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + return false; + CloseHandle(hFile); + return true; +} + +const bool windowsFile::canWrite() const +{ + HANDLE hFile = CreateFile( + m_nativePath.c_str(), + GENERIC_WRITE, + 0, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + return false; + CloseHandle(hFile); + return true; +} + +const windowsFile::length_type windowsFile::getLength() +{ + HANDLE hFile = CreateFile( + m_nativePath.c_str(), + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + windowsFileSystemFactory::reportError(m_path, GetLastError()); + + DWORD dwSize = GetFileSize(hFile, NULL); + CloseHandle(hFile); + + return dwSize; +} + +const vmime::utility::path& windowsFile::getFullPath() const +{ + return m_path; +} + +const bool windowsFile::exists() const +{ + WIN32_FIND_DATA findData; + HANDLE hFind = FindFirstFile(m_nativePath.c_str(), &findData); + if (hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); + return true; + } + return false; +} + +const vmime::utility::file* windowsFile::getParent() const +{ + if (m_path.isEmpty()) + return NULL; + else + return new windowsFile(m_path.getParent()); +} + +void windowsFile::rename(const path& newName) +{ + const vmime::string newNativeName = windowsFileSystemFactory::pathToStringImpl(newName); + if (MoveFile(m_nativePath.c_str(), newNativeName.c_str())) + { + m_path = newName; + m_nativePath = newNativeName; + } + else + windowsFileSystemFactory::reportError(m_path, GetLastError()); +} + +void windowsFile::remove() +{ + if (!DeleteFile(m_nativePath.c_str())) + windowsFileSystemFactory::reportError(m_path, GetLastError()); +} + +vmime::utility::fileWriter* windowsFile::getFileWriter() +{ + return new windowsFileWriter(m_path, m_nativePath); +} + +vmime::utility::fileReader* windowsFile::getFileReader() +{ + return new windowsFileReader(m_path, m_nativePath); +} + +vmime::utility::fileIterator* windowsFile::getFiles() const +{ + return new windowsFileIterator(m_path, m_nativePath); +} + +void windowsFile::createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive) +{ + const vmime::string nativePath = windowsFileSystemFactory::pathToStringImpl(path); + + windowsFile tmp(fullPath); + if (tmp.isDirectory()) + return; + + if (!path.isEmpty() && recursive) + createDirectoryImpl(fullPath, path.getParent(), true); + + if (!CreateDirectory(nativePath.c_str(), NULL)) + windowsFileSystemFactory::reportError(fullPath, GetLastError()); +} + +windowsFileIterator::windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath) +: m_path(path), m_nativePath(nativePath), m_moreElements(false), m_hFind(INVALID_HANDLE_VALUE) +{ + findFirst(); +} + +windowsFileIterator::~windowsFileIterator() +{ + if (m_hFind != INVALID_HANDLE_VALUE) + FindClose(m_hFind); +} + +const bool windowsFileIterator::hasMoreElements() const +{ + return m_moreElements; +} + +vmime::utility::file* windowsFileIterator::nextElement() +{ + vmime::utility::file* pFile = new windowsFile(m_path / vmime::utility::file::path::component(m_findData.cFileName)); + + findNext(); + + return pFile; +} + +void windowsFileIterator::findFirst() +{ + m_hFind = FindFirstFile(m_nativePath.c_str(), &m_findData); + if (m_hFind == INVALID_HANDLE_VALUE) + { + m_moreElements = false; + return; + } + + m_moreElements = true; + if (isCurrentOrParentDir()) + findNext(); +} + +void windowsFileIterator::findNext() +{ + do + { + if (!FindNextFile(m_hFind, &m_findData)) + { + m_moreElements = false; + return; + } + } + while (isCurrentOrParentDir()); +} + +bool windowsFileIterator::isCurrentOrParentDir() const +{ + vmime::string s(m_findData.cFileName); + if ((s == ".") || (s == "..")) + return true; + return false; +} + +windowsFileReader::windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath) +: m_path(path), m_nativePath(nativePath) +{ +} + +vmime::utility::inputStream* windowsFileReader::getInputStream() +{ + HANDLE hFile = CreateFile( + m_nativePath.c_str(), + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + windowsFileSystemFactory::reportError(m_path, GetLastError()); + return new windowsFileReaderInputStream(m_path, hFile); +} + +windowsFileReaderInputStream::windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile) +: m_path(path), m_hFile(hFile) +{ +} + +windowsFileReaderInputStream::~windowsFileReaderInputStream() +{ + CloseHandle(m_hFile); +} + +const bool windowsFileReaderInputStream::eof() const +{ + DWORD dwSize = GetFileSize(m_hFile, NULL); + DWORD dwPosition = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); + return (dwSize == dwPosition); +} + +void windowsFileReaderInputStream::reset() +{ + SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN); +} + +const vmime::utility::stream::size_type windowsFileReaderInputStream::read(value_type* const data, const size_type count) +{ + DWORD dwBytesRead; + if (!ReadFile(m_hFile, (LPVOID)data, (DWORD)count, &dwBytesRead, NULL)) + windowsFileSystemFactory::reportError(m_path, GetLastError()); + return dwBytesRead; +} + +const vmime::utility::stream::size_type windowsFileReaderInputStream::skip(const size_type count) +{ + DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); + DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)count, NULL, FILE_CURRENT); + return (dwNewPos - dwCurPos); +} + +windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath) +: m_path(path), m_nativePath(nativePath) +{ +} + +vmime::utility::outputStream* windowsFileWriter::getOutputStream() +{ + HANDLE hFile = CreateFile( + m_nativePath.c_str(), + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + windowsFileSystemFactory::reportError(m_path, GetLastError()); + return new windowsFileWriterOutputStream(m_path, hFile); +} + +windowsFileWriterOutputStream::windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile) +: m_path(path), m_hFile(hFile) +{ +} + +windowsFileWriterOutputStream::~windowsFileWriterOutputStream() +{ + CloseHandle(m_hFile); +} + +void windowsFileWriterOutputStream::write(const value_type* const data, const size_type count) +{ + DWORD dwBytesWritten; + if (!WriteFile(m_hFile, data, (DWORD)count, &dwBytesWritten, NULL)) + windowsFileSystemFactory::reportError(m_path, GetLastError()); +} + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_HAVE_FILESYSTEM_FEATURES diff --git a/src/platforms/windows/windowsHandler.cpp b/src/platforms/windows/windowsHandler.cpp new file mode 100644 index 00000000..6b84f59f --- /dev/null +++ b/src/platforms/windows/windowsHandler.cpp @@ -0,0 +1,213 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2005 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "vmime/platforms/windows/windowsHandler.hpp" + +#include +#include +#include +#include + +namespace vmime { +namespace platforms { +namespace windows { + + +windowsHandler::windowsHandler() +{ +#if VMIME_HAVE_MESSAGING_FEATURES + m_socketFactory = new windowsSocketFactory(); +#endif +#if VMIME_HAVE_FILESYSTEM_FEATURES + m_fileSysFactory = new windowsFileSystemFactory(); +#endif +} + + +windowsHandler::~windowsHandler() +{ +#if VMIME_HAVE_MESSAGING_FEATURES + delete (m_socketFactory); +#endif +#if VMIME_HAVE_FILESYSTEM_FEATURES + delete (m_fileSysFactory); +#endif +} + + +const unsigned int windowsHandler::getUnixTime() const +{ + return (unsigned int)::time(NULL); +} + + +const vmime::datetime windowsHandler::getCurrentLocalTime() const +{ + const time_t t(::time(NULL)); + + // Get the local time +#ifdef _REENTRANT + tm local; + ::localtime_r(&t, &local); +#else + tm local = *::localtime(&t); // WARNING: this is not thread-safe! +#endif + + // Get the UTC time +#ifdef _REENTRANT + 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 int diff = (const int)(::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, diff / 60); // minutes needed +} + + +const vmime::charset windowsHandler::getLocaleCharset() const +{ + char szCharset[256]; + + CoInitialize(NULL); + { + IMultiLanguage* pMultiLanguage; + CoCreateInstance( + CLSID_CMultiLanguage, + NULL, + CLSCTX_INPROC_SERVER, + IID_IMultiLanguage, + (void**)&pMultiLanguage); + + UINT codePage = GetACP(); + MIMECPINFO cpInfo; + pMultiLanguage->GetCodePageInfo(codePage, &cpInfo); + + int nLengthW = lstrlenW(cpInfo.wszBodyCharset) + 1; + + WideCharToMultiByte(codePage, 0, cpInfo.wszBodyCharset, nLengthW, szCharset, sizeof(szCharset), NULL, NULL ); + + pMultiLanguage->Release(); + + } + CoUninitialize(); + + return vmime::charset(szCharset); +} + + +const vmime::string windowsHandler::getHostName() const +{ + std::vector hostnames; + char buffer[256]; + + // Try with 'gethostname' + ::gethostname(buffer, sizeof(buffer)); + buffer[sizeof(buffer) - 1] = '\0'; + + if (::strlen(buffer) == 0) + ::strcpy(buffer, "localhost"); + + hostnames.push_back(buffer); + + // And with 'gethostbyname' + struct hostent* he = ::gethostbyname(buffer); + + if (he != NULL) + { + if (::strlen(he->h_name) != 0) + hostnames.push_back(he->h_name); + + char** alias = he->h_aliases; + + while (alias && *alias) + { + if (::strlen(*alias) != 0) + hostnames.push_back(*alias); + + ++alias; + } + } + + // Find a Fully-Qualified Domain Name (FQDN) + for (unsigned int i = 0 ; i < hostnames.size() ; ++i) + { + if (hostnames[i].find_first_of(".") != vmime::string::npos) + return (hostnames[i]); + } + + return (hostnames[0]); +} + + +const unsigned int windowsHandler::getProcessId() const +{ + return (::getpid()); +} + + +#if VMIME_HAVE_MESSAGING_FEATURES + +vmime::messaging::socketFactory* windowsHandler::getSocketFactory + (const vmime::string& /* name */) const +{ + return (m_socketFactory); +} + + +vmime::messaging::timeoutHandlerFactory* windowsHandler::getTimeoutHandlerFactory + (const vmime::string& /* name */) const +{ + // Not used by default + return (NULL); +} + +#endif + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + +vmime::utility::fileSystemFactory* windowsHandler::getFileSystemFactory() const +{ + return (m_fileSysFactory); +} + +#endif + + +void windowsHandler::wait() const +{ + ::Sleep(1000); +} + + +} // posix +} // platforms +} // vmime diff --git a/src/platforms/windows/windowsSocket.cpp b/src/platforms/windows/windowsSocket.cpp new file mode 100644 index 00000000..a572a271 --- /dev/null +++ b/src/platforms/windows/windowsSocket.cpp @@ -0,0 +1,181 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2005 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#pragma warning(disable: 4267) + +#include "vmime/platforms/windows/windowsSocket.hpp" + +#include "vmime/exception.hpp" + +#if VMIME_HAVE_MESSAGING_FEATURES + +namespace vmime { +namespace platforms { +namespace windows { + + +// +// posixSocket +// + +windowsSocket::windowsSocket() + : m_desc(-1) +{ + WSAData wsaData; + WSAStartup(MAKEWORD(1, 1), &wsaData); +} + + +windowsSocket::~windowsSocket() +{ + if (m_desc != -1) + ::closesocket(m_desc); + WSACleanup(); +} + + +void windowsSocket::connect(const vmime::string& address, const vmime::port_t port) +{ + // Close current connection, if any + if (m_desc != -1) + { + ::closesocket(m_desc); + m_desc = -1; + } + + // Resolve address + ::sockaddr_in addr; + + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_port = htons(static_cast (port)); + addr.sin_addr.s_addr = ::inet_addr(address.c_str()); + + if (addr.sin_addr.s_addr == static_cast (-1)) + { + ::hostent* hostInfo = ::gethostbyname(address.c_str()); + + if (hostInfo == NULL) + { + // Error: cannot resolve address + throw vmime::exceptions::connection_error("Cannot resolve address."); + } + + memcpy(reinterpret_cast (&addr.sin_addr), hostInfo->h_addr, hostInfo->h_length); + } + + // Get a new socket + m_desc = ::socket(AF_INET, SOCK_STREAM, 0); + + if (m_desc == -1) + throw vmime::exceptions::connection_error("Error while creating socket."); + + // Start connection + if (::connect(m_desc, reinterpret_cast (&addr), sizeof(addr)) == -1) + { + ::closesocket(m_desc); + m_desc = -1; + + // Error + throw vmime::exceptions::connection_error("Error while connecting socket."); + } +} + + +const bool windowsSocket::isConnected() const +{ + return (m_desc != -1); +} + + +void windowsSocket::disconnect() +{ + if (m_desc != -1) + { + ::shutdown(m_desc, SD_BOTH); + ::closesocket(m_desc); + + m_desc = -1; + } +} + + +void windowsSocket::receive(vmime::string& buffer) +{ + int ret = ::recv(m_desc, m_buffer, sizeof(m_buffer), 0); + + if (ret == -1) + { + // Error or no data + return; + } + else if (ret > 0) + { + buffer = vmime::string(m_buffer, ret); + } +} + + +const int windowsSocket::receiveRaw(char* buffer, const int count) +{ + int ret = ::recv(m_desc, buffer, count, 0); + + if (ret == -1) + { + // Error or no data + return (0); + } + else + { + return (ret); + } +} + + +void windowsSocket::send(const vmime::string& buffer) +{ + ::send(m_desc, buffer.data(), buffer.length(), 0); +} + + +void windowsSocket::sendRaw(const char* buffer, const int count) +{ + ::send(m_desc, buffer, count, 0); +} + + + + +// +// posixSocketFactory +// + +vmime::messaging::socket* windowsSocketFactory::create() +{ + return new windowsSocket(); +} + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/vmime/platforms/windows/windowsFile.hpp b/vmime/platforms/windows/windowsFile.hpp new file mode 100644 index 00000000..885a954b --- /dev/null +++ b/vmime/platforms/windows/windowsFile.hpp @@ -0,0 +1,186 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2005 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_FILE_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_FILE_HPP_INCLUDED + + +#include "vmime/utility/file.hpp" + +#include + +#if VMIME_HAVE_FILESYSTEM_FEATURES + + +namespace vmime { +namespace platforms { +namespace windows { + + +class windowsFileSystemFactory : public vmime::utility::fileSystemFactory +{ +public: + + vmime::utility::file* create(const vmime::utility::file::path& path) const; + + const vmime::utility::file::path stringToPath(const vmime::string& str) const; + const vmime::string pathToString(const vmime::utility::file::path& path) const; + + static const vmime::utility::file::path stringToPathImpl(const vmime::string& str); + static const vmime::string pathToStringImpl(const vmime::utility::file::path& path); + + const bool isValidPathComponent(const vmime::utility::file::path::component& comp) const; + const bool isValidPath(const vmime::utility::file::path& path) const; + + static void reportError(const vmime::utility::path& path, const int err); +}; + + +class windowsFile : public vmime::utility::file +{ +public: + windowsFile(const vmime::utility::file::path& path); + +public: + void createFile(); + void createDirectory(const bool createAll = false); + + const bool isFile() const; + const bool isDirectory() const; + + const bool canRead() const; + const bool canWrite() const; + + const length_type getLength(); + + const path& getFullPath() const; + + const bool exists() const; + + const file* getParent() const; + + void rename(const path& newName); + void remove(); + + vmime::utility::fileWriter* getFileWriter(); + + vmime::utility::fileReader* getFileReader(); + + vmime::utility::fileIterator* getFiles() const; + +private: + static void createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive = false); + +private: + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + +class windowsFileIterator : public vmime::utility::fileIterator +{ +public: + windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath); + ~windowsFileIterator(); + + const bool hasMoreElements() const; + vmime::utility::file* nextElement(); + +private: + void findFirst(); + void findNext(); + bool isCurrentOrParentDir() const; + +private: + vmime::utility::file::path m_path; + vmime::string m_nativePath; + WIN32_FIND_DATA m_findData; + bool m_moreElements; + HANDLE m_hFind; +}; + + +class windowsFileReader : public vmime::utility::fileReader +{ +public: + windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath); + +public: + vmime::utility::inputStream* getInputStream(); + +private: + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + +class windowsFileReaderInputStream : public vmime::utility::inputStream +{ +public: + windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile); + ~windowsFileReaderInputStream(); + +public: + const bool eof() const; + void reset(); + const size_type read(value_type* const data, const size_type count); + const size_type skip(const size_type count); + +private: + const vmime::utility::file::path m_path; + HANDLE m_hFile; +}; + + +class windowsFileWriter : public vmime::utility::fileWriter +{ +public: + windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath); + +public: + vmime::utility::outputStream* getOutputStream(); + +private: + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + +class windowsFileWriterOutputStream : public vmime::utility::outputStream +{ +public: + windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile); + ~windowsFileWriterOutputStream(); + +public: + void write(const value_type* const data, const size_type count); + +private: + const vmime::utility::file::path m_path; + HANDLE m_hFile; +}; + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_HAVE_FILESYSTEM_FEATURES + +#endif // VMIME_PLATFORMS_WINDOWS_FILE_HPP_INCLUDED diff --git a/vmime/platforms/windows/windowsHandler.hpp b/vmime/platforms/windows/windowsHandler.hpp new file mode 100644 index 00000000..7db854b7 --- /dev/null +++ b/vmime/platforms/windows/windowsHandler.hpp @@ -0,0 +1,87 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2005 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_HANDLER_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_HANDLER_HPP_INCLUDED + + +#include "vmime/config.hpp" +#include "vmime/platformDependant.hpp" + +#if VMIME_HAVE_MESSAGING_FEATURES + #include "vmime/platforms/windows/windowsSocket.hpp" +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + #include "vmime/platforms/windows/windowsFile.hpp" +#endif + + +namespace vmime { +namespace platforms { +namespace windows { + + +class windowsHandler : public vmime::platformDependant::handler +{ +public: + + windowsHandler(); + ~windowsHandler(); + + const unsigned int getUnixTime() const; + + const vmime::datetime getCurrentLocalTime() const; + + const vmime::charset getLocaleCharset() const; + + const vmime::string getHostName() const; + + const unsigned int getProcessId() const; + +#if VMIME_HAVE_MESSAGING_FEATURES + vmime::messaging::socketFactory* getSocketFactory(const vmime::string& name) const; + + vmime::messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& name) const; +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + vmime::utility::fileSystemFactory* getFileSystemFactory() const; +#endif + + void wait() const; + +private: + +#if VMIME_HAVE_MESSAGING_FEATURES + windowsSocketFactory* m_socketFactory; +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + windowsFileSystemFactory* m_fileSysFactory; +#endif +}; + + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_PLATFORMS_WINDOWS_HANDLER_HPP_INCLUDED diff --git a/vmime/platforms/windows/windowsSocket.hpp b/vmime/platforms/windows/windowsSocket.hpp new file mode 100644 index 00000000..8a06d4d3 --- /dev/null +++ b/vmime/platforms/windows/windowsSocket.hpp @@ -0,0 +1,74 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2005 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_SOCKET_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_SOCKET_HPP_INCLUDED + + +#include +#include "vmime/messaging/socket.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +namespace vmime { +namespace platforms { +namespace windows { + + +class windowsSocket : public vmime::messaging::socket +{ +public: + windowsSocket(); + ~windowsSocket(); + +public: + void connect(const vmime::string& address, const vmime::port_t port); + const bool isConnected() const; + void disconnect(); + + void receive(vmime::string& buffer); + const int receiveRaw(char* buffer, const int count); + + void send(const vmime::string& buffer); + void sendRaw(const char* buffer, const int count); + +private: + char m_buffer[65536]; + SOCKET m_desc; +}; + + + +class windowsSocketFactory : public vmime::messaging::socketFactory +{ +public: + vmime::messaging::socket* create(); +}; + + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_PLATFORMS_WINDOWS_SOCKET_HPP_INCLUDED