aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2004-12-18 01:57:39 +0000
committerVincent Richard <[email protected]>2004-12-18 01:57:39 +0000
commit460cae786af2c4c8ff205f7feb45b50c43a6700b (patch)
treeadc4c2f466ae5dd625f57a13df3247dd565fbb3a
parentAdded appendComponent() and getComponentAt() functions. (diff)
downloadvmime-460cae786af2c4c8ff205f7feb45b50c43a6700b.tar.gz
vmime-460cae786af2c4c8ff205f7feb45b50c43a6700b.zip
Default platform handlers (currently only POSIX).
-rw-r--r--ChangeLog24
-rw-r--r--SConstruct78
-rw-r--r--examples/README4
-rw-r--r--examples/common.inc312
-rw-r--r--examples/example1.cpp4
-rw-r--r--examples/example2.cpp4
-rw-r--r--examples/example3.cpp4
-rw-r--r--examples/example4.cpp4
-rw-r--r--examples/example5.cpp4
-rw-r--r--examples/example6.cpp4
-rw-r--r--src/platforms/posix/file.cpp479
-rw-r--r--src/platforms/posix/file.hpp203
-rw-r--r--src/platforms/posix/handler.cpp186
-rw-r--r--src/platforms/posix/handler.hpp78
-rw-r--r--src/platforms/posix/socket.cpp190
-rw-r--r--src/platforms/posix/socket.hpp75
-rw-r--r--tests/parser/encoderTest.cpp4
-rw-r--r--tests/parser/headerTest.cpp4
-rw-r--r--tests/parser/mailboxTest.cpp4
-rw-r--r--tests/parser/mediaTypeTest.cpp4
-rw-r--r--tests/parser/textTest.cpp4
21 files changed, 1333 insertions, 340 deletions
diff --git a/ChangeLog b/ChangeLog
index 4001d9e8..ff8b00e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,30 @@
VERSION 0.6.0-cvs
=================
+2004-12-17 Vincent Richard <[email protected]>
+
+ * Made default platform handlers (currently, only "posix"). Source files
+ are in src/platforms/[platform-name].
+
+ To use a default platform handler, do the following:
+ - #include <vmime/platforms/[platform-name]/handler.hpp>
+ - call vmime::platformDependant::setHandler() with the appropriate class
+ - link your program with both 'libvmime' and 'libvmime-[platform-name]'
+
+ For example, to use the default platform handler for POSIX (GNU/Linux):
+
+ #include <vmime/platforms/posix/handler.hpp>
+
+ int main()
+ {
+ vmime::platformDependant::setHandler
+ <vmime::platforms::posix::posixHandler>();
+
+ // ...
+ }
+
+ and link your program with "-lvmime" and "-lvmime-posix".
+
2004-10-21 Vincent Richard <[email protected]>
* A _LOT_ of cleaning/refactoring in VMime code:
diff --git a/SConstruct b/SConstruct
index 3a5d4633..0f1e8125 100644
--- a/SConstruct
+++ b/SConstruct
@@ -170,6 +170,15 @@ libvmime_messaging_proto_sources = [
]
]
+libvmime_platforms_sources = {
+ 'posix':
+ [
+ 'platforms/posix/file.cpp', 'platforms/posix/file.hpp',
+ 'platforms/posix/handler.cpp', 'platforms/posix/handler.hpp',
+ 'platforms/posix/socket.cpp', 'platforms/posix/socket.hpp'
+ ]
+}
+
libvmime_extra = [
'AUTHORS',
'ChangeLog',
@@ -339,7 +348,7 @@ opts.AddOptions(
),
EnumOption(
'with_filesystem',
- 'Enable file-system support (eg. "maildir" messaging support)',
+ 'Enable file-system support (this is needed for "maildir" messaging support)',
'yes',
allowed_values = ('yes', 'no'),
map = { },
@@ -349,9 +358,20 @@ opts.AddOptions(
'with_messaging_protocols',
'Specifies which protocols to build into the library.\n'
+ 'This option has no effect if "with_messaging" is not activated.\n'
- + 'Separate protocols with spaces; string must be quoted with ".',
+ + 'Separate protocols with spaces; string must be quoted with ".\n'
+ + 'Available protocols: pop3, smtp, imap, maildir.',
'"pop3 smtp imap"'
),
+ (
+ 'with_platforms',
+ 'Specifies which default platform handlers libraries to build.\n'
+ + 'This builds a library for each platform selected (eg: "libvmime-posix.a").\n'
+ + 'If no default handler is available for your platform, you will have\n'
+ + 'to write your own...\n'
+ + 'Separate platforms with spaces; string must be quoted with ".\n'
+ + 'Available platform handlers: posix.',
+ '"posix"'
+ ),
EnumOption(
'with_wide_char_support',
'Support for wide characters (rarely used, should be set to "no")',
@@ -457,6 +477,14 @@ for proto in re.split('\W+', env['with_messaging_protocols']):
if len(proto) >= 1:
messaging_protocols.append(proto)
+# Platforms
+platforms = [ ]
+
+for platform in re.split('\W+', env['with_platforms']):
+ platform = string.strip(platform)
+ if len(platform) >= 1:
+ platforms.append(platform)
+
# Show configuration summary
print ""
print "+=================+"
@@ -471,6 +499,7 @@ print "Messaging support : " + env['with_messaging']
if env['with_messaging'] == 'yes':
print " * protocols : " + env['with_messaging_protocols']
print "File-system support : " + env['with_filesystem']
+print "Default handlers : " + env['with_platforms']
print ""
@@ -635,7 +664,7 @@ libvmime_sources_HPP = [ ]
libvmime_install_includes = [ ]
for file in libvmime_full_sources:
- slash = string.find(file, '/')
+ slash = string.rfind(file, '/')
dir = ''
if slash != -1:
@@ -647,6 +676,7 @@ for file in libvmime_full_sources:
libvmime_sources_HPP.append(buildDirectory + file)
libvmime_install_includes.append([dir, buildDirectory + file])
+
# Main program build
if env['debug'] == 'yes':
if env['static'] == 'yes':
@@ -677,6 +707,42 @@ if env['static'] == 'yes': Default(libVmime)
if env['shared'] == 'yes': Default(libVmimeSh)
+# Platform header files
+for platform in libvmime_platforms_sources:
+ files = libvmime_platforms_sources[platform]
+
+ for file in files:
+ slash = string.rfind(file, '/')
+ dir = ''
+
+ if slash != -1:
+ dir = file[0:slash] + '/'
+
+ if file[-4:] == '.hpp':
+ libvmime_install_includes.append([dir, buildDirectory + file])
+
+# Platform libraries
+platformLibraries = [ ]
+
+for platform in platforms:
+ files = libvmime_platforms_sources[platform]
+
+ sources_CPP = [ ]
+
+ for file in files:
+ if file[-4:] == '.cpp':
+ sources_CPP.append(buildDirectory + file)
+
+ platformLib = env.StaticLibrary(
+ target = 'vmime-' + platform,
+ source = sources_CPP
+ )
+
+ Default(platformLib)
+
+ platformLibraries.append(platformLib)
+
+
# Tests
if env['build_tests'] == 'yes':
libUnitpp = env.StaticLibrary(
@@ -691,7 +757,7 @@ if env['build_tests'] == 'yes':
env.Program(
target = test[0],
source = test[1],
- LIBS=['unit++', 'vmime-debug'],
+ LIBS=['unit++', 'vmime-posix', 'vmime-debug'],
LIBPATH=['.', './tests/']
)
)
@@ -710,6 +776,10 @@ installPaths = [libDir, includeDir]
if env['static'] == 'yes': env.Install(libDir, libVmime)
if env['shared'] == 'yes': env.Install(libDir, libVmimeSh)
+# Platform libraries
+for platformLib in platformLibraries:
+ env.Install(libDir, platformLib)
+
# Header files
for i in range(len(libvmime_install_includes)):
env.Install(includeDir + '/' + libvmime_install_includes[i][0], libvmime_install_includes[i][1])
diff --git a/examples/README b/examples/README
index b8e11937..f741c387 100644
--- a/examples/README
+++ b/examples/README
@@ -2,8 +2,8 @@
1) Configure, compile and install vmime library
2) Compile the sample programs with:
- $ g++ -o exampleX exampleX.cpp ../libvmime.a
+ $ g++ -o exampleX exampleX.cpp ../libvmime.a ../libvmime-posix.a
3) For a more complete documentation, please visit:
- http://www.kisli.com/vmime/doc/
+ http://vmime.sourceforge.net/documentation/
diff --git a/examples/common.inc b/examples/common.inc
deleted file mode 100644
index 8da13f2c..00000000
--- a/examples/common.inc
+++ /dev/null
@@ -1,312 +0,0 @@
-//
-// VMime library (http://vmime.sourceforge.net)
-// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
-//
-// 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 <ctime>
-
-#include <unistd.h>
-#include <locale.h>
-#include <langinfo.h>
-
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <fcntl.h>
-
-#include <pthread.h>
-
-#include <sched.h>
-
-#include "../src/vmime"
-
-
-class my_socket : public vmime::messaging::socket
-{
-private:
-
- char m_buffer[65536];
- int m_desc;
-
-public:
-
- my_socket()
- : m_desc(0)
- {
- if ((m_desc = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- // Error
- }
-
- //::fcntl(m_desc, F_SETFL, ::fcntl(m_desc, F_GETFL, 0) | O_NONBLOCK);
- }
-
- ~my_socket()
- {
- ::close(m_desc);
- }
-
- void connect(const vmime::string& address, const vmime::port_t port)
- {
- ::sockaddr_in addr;
-
- memset(&addr, 0, sizeof(addr));
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons((unsigned short) port);
- addr.sin_addr.s_addr = ::inet_addr(address.c_str());
-
- std::cout << "Connecting to '" << address << "' port " << port << "..." << std::endl;
-
- if (addr.sin_addr.s_addr == (::in_addr_t) -1)
- {
- ::hostent* hostInfo = (hostent*) ::gethostbyname(address.c_str());
-
- if (hostInfo == NULL)
- {
- // Error: cannot resolve address
- throw vmime::exceptions::connection_error();
- }
-
- bcopy(hostInfo->h_addr, (char*) &addr.sin_addr, hostInfo->h_length);
-
- std::cout << "Address resolved to " << inet_ntoa(addr.sin_addr) << std::endl;
- }
- else
- {
- // Error: cannot resolve address
- throw vmime::exceptions::connection_error();
- }
-
- std::cout << std::endl;
-
- if (::connect(m_desc, (sockaddr*) &addr, sizeof(addr)) == -1)
- {
- // Error
- throw vmime::exceptions::connection_error();
- }
- }
-
- const bool isConnected() const
- {
- return (m_desc != 0);
- }
-
- void disconnect()
- {
- ::shutdown(m_desc, SHUT_RDWR);
- }
-
- void receive(vmime::string& buffer)
- {
- ::ssize_t 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);
-
-#if DEBUG_SOCKET_IO
- std::cout << "S: " << buffer;
- std::cout.flush();
-#endif
- }
- }
-
- const int receiveRaw(char* buffer, const int count)
- {
- ::ssize_t ret = ::recv(m_desc, buffer, count, 0);
-
- if (ret == -1)
- {
- // Error or no data
- return (0);
- }
- else
- {
-#if DEBUG_SOCKET_IO
- std::cout << "S: " << vmime::string(buffer, count);
- std::cout.flush();
-#endif
-
- return (ret);
- }
- }
-
- void send(const vmime::string& buffer)
- {
-#if DEBUG_SOCKET_IO
- std::cout << "C: " << buffer;
- std::cout.flush();
-#endif
-
- ::send(m_desc, buffer.data(), buffer.length(), 0);
- }
-
- void sendRaw(const char* buffer, const int count)
- {
-#if DEBUG_SOCKET_IO
- std::cout << "C: " << vmime::string(buffer, count);
- std::cout.flush();
-#endif
-
- ::send(m_desc, buffer, count, 0);
- }
-};
-
-
-class my_socket_factory : public vmime::messaging::socketFactory
-{
-public:
-
- vmime::messaging::socket* create()
- {
- return (new my_socket);
- }
-};
-
-
-
-/*
-
-TODO: file, fileSystemFactory
-
-
-
-#include <errno.h>
-
-
-
-Erreurs pour fileIterator [ opendir() ] :
-===> switch + exception appropriƩe (exceptions::fileIteratorException ?)
-
-* EACESS Permission denied.
-
-* EMFILE Too many file descriptors in use by process.
-
-* ENFILE Too many files are currently open in the system.
-
-* ENOENT Directory does not exist, or name is an empty string.
-
-* ENOMEM Insufficient memory to complete the operation.
-
-* ENOTDIR Name is not a directory.
-
-*/
-
-
-
-class my_handler : public vmime::platformDependant::handler
-{
-private:
-
- my_socket_factory* m_sf;
-
-public:
-
- my_handler()
- : m_sf(new my_socket_factory)
- {
- }
-
- ~my_handler()
- {
- delete (m_sf);
- }
-
- const unsigned int getUnixTime() const
- {
- return ::std::time(NULL);
- }
-
- // WARNING: this is not thread-safe!
- const vmime::datetime getCurrentLocalTime() const
- {
- const ::std::time_t t(::std::time(NULL));
-
- // Get the local time
- ::std::tm local = *::std::localtime(&t);
-
- // Get the UTC time
- ::std::tm gmt = *::std::gmtime(&t);
-
- // "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 = ::std::mktime(&local) - ::std::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 getLocaleCharset() const
- {
- vmime::string prevLocale(::setlocale(::LC_ALL, ""));
- vmime::charset ch(::nl_langinfo(::CODESET));
- ::setlocale(::LC_ALL, prevLocale.c_str());
-
- return (ch);
- }
-
- const vmime::string getHostName() const
- {
- // TODO: you should return the real (unique) host name
- return "localhost";
- }
-
- const unsigned int getProcessId() const
- {
- return getpid();
- }
-
- vmime::messaging::socketFactory* getSocketFactory(const vmime::string& /* name */) const
- {
- return m_sf;
- }
-
- vmime::messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& /* name */) const
- {
- // Not used for now
- return NULL;
- }
-
- vmime::utility::fileSystemFactory* getFileSystemFactory() const
- {
- // TODO
- return NULL;
- }
-
- void wait() const
- {
- //::sched_yield();
- std::cout << "WAIT" << std::endl;
- sleep(1);
- }
-};
-
-
diff --git a/examples/example1.cpp b/examples/example1.cpp
index b639a4bc..24a50b2b 100644
--- a/examples/example1.cpp
+++ b/examples/example1.cpp
@@ -30,7 +30,7 @@
#include <iostream>
#include "../src/vmime"
-#include "common.inc"
+#include "../src/platforms/posix/handler.hpp"
int main()
@@ -38,7 +38,7 @@ int main()
std::cout << std::endl;
// VMime initialization
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
try
{
diff --git a/examples/example2.cpp b/examples/example2.cpp
index 6e7f81c6..6534d7e8 100644
--- a/examples/example2.cpp
+++ b/examples/example2.cpp
@@ -30,7 +30,7 @@
#include <iostream>
#include "../src/vmime"
-#include "common.inc"
+#include "../src/platforms/posix/handler.hpp"
int main()
@@ -38,7 +38,7 @@ int main()
std::cout << std::endl;
// VMime initialization
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
try
{
diff --git a/examples/example3.cpp b/examples/example3.cpp
index d2b41754..839c1ad7 100644
--- a/examples/example3.cpp
+++ b/examples/example3.cpp
@@ -30,7 +30,7 @@
#include <iostream>
#include "../src/vmime"
-#include "common.inc"
+#include "../src/platforms/posix/handler.hpp"
int main()
@@ -38,7 +38,7 @@ int main()
std::cout << std::endl;
// VMime initialization
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
try
{
diff --git a/examples/example4.cpp b/examples/example4.cpp
index 605452fe..9cb774e7 100644
--- a/examples/example4.cpp
+++ b/examples/example4.cpp
@@ -29,7 +29,7 @@
#include <iostream>
#include "../src/vmime"
-#include "common.inc"
+#include "../src/platforms/posix/handler.hpp"
int main()
@@ -37,7 +37,7 @@ int main()
std::cout << std::endl;
// VMime initialization
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
try
{
diff --git a/examples/example5.cpp b/examples/example5.cpp
index e5a7c93b..7885bd88 100644
--- a/examples/example5.cpp
+++ b/examples/example5.cpp
@@ -30,7 +30,7 @@
#include <iostream>
#include "../src/vmime"
-#include "common.inc"
+#include "../src/platforms/posix/handler.hpp"
int main()
@@ -38,7 +38,7 @@ int main()
std::cout << std::endl;
// VMime initialization
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
try
{
diff --git a/examples/example6.cpp b/examples/example6.cpp
index 78fe0f3d..465cf854 100644
--- a/examples/example6.cpp
+++ b/examples/example6.cpp
@@ -20,7 +20,7 @@
#include <iostream>
#include "../src/vmime"
-#include "common.inc"
+#include "../src/platforms/posix/handler.hpp"
//
@@ -70,7 +70,7 @@ void printStructure(const vmime::messaging::structure& s, int level = 0)
int main()
{
// VMime initialization
- vmime::platformDependant::setHandler <my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
//
// Test the new enumeration system for encoders
diff --git a/src/platforms/posix/file.cpp b/src/platforms/posix/file.cpp
new file mode 100644
index 00000000..f2510c78
--- /dev/null
+++ b/src/platforms/posix/file.cpp
@@ -0,0 +1,479 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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 "file.hpp"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+
+#include "../../exception.hpp"
+
+
+#if VMIME_HAVE_FILESYSTEM_FEATURES
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+//
+// posixFileIterator
+//
+
+posixFileIterator::posixFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath)
+ : m_path(path), m_nativePath(nativePath), m_dir(NULL), m_dirEntry(NULL)
+{
+ if ((m_dir = ::opendir(m_nativePath.c_str())) == NULL)
+ posixFileSystemFactory::reportError(path, errno);
+
+ m_dirEntry = ::readdir(m_dir);
+}
+
+
+posixFileIterator::~posixFileIterator()
+{
+ if (m_dir != NULL)
+ ::closedir(m_dir);
+}
+
+
+const bool posixFileIterator::hasMoreElements() const
+{
+ return (m_dirEntry != NULL);
+}
+
+
+vmime::utility::file* posixFileIterator::nextElement()
+{
+ posixFile* file = new posixFile(m_path / vmime::utility::file::path::component(m_dirEntry->d_name));
+
+ m_dirEntry = ::readdir(m_dir);
+
+ return (file);
+}
+
+
+
+//
+// posixFileWriterOutputStream
+//
+
+posixFileWriterOutputStream::posixFileWriterOutputStream(const vmime::utility::file::path& path, const int fd)
+ : m_path(path), m_fd(fd)
+{
+}
+
+
+posixFileWriterOutputStream::~posixFileWriterOutputStream()
+{
+ ::close(m_fd);
+}
+
+
+void posixFileWriterOutputStream::write(const value_type* const data, const size_type count)
+{
+ if (::write(m_fd, data, count) == -1)
+ posixFileSystemFactory::reportError(m_path, errno);
+}
+
+
+
+//
+// posixFileReaderInputStream
+//
+
+posixFileReaderInputStream::posixFileReaderInputStream(const vmime::utility::file::path& path, const int fd)
+ : m_path(path), m_fd(fd), m_eof(false)
+{
+}
+
+
+posixFileReaderInputStream::~posixFileReaderInputStream()
+{
+ ::close(m_fd);
+}
+
+
+const bool posixFileReaderInputStream::eof() const
+{
+ return (m_eof);
+}
+
+
+void posixFileReaderInputStream::reset()
+{
+ ::lseek(m_fd, 0, SEEK_SET);
+}
+
+
+const vmime::utility::stream::size_type posixFileReaderInputStream::read
+ (value_type* const data, const size_type count)
+{
+ ssize_t c = 0;
+
+ if ((c = ::read(m_fd, data, count)) == -1)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ if (c == 0)
+ m_eof = true;
+
+ return static_cast <size_type>(c);
+}
+
+
+const vmime::utility::stream::size_type posixFileReaderInputStream::skip(const size_type count)
+{
+ const off_t curPos = ::lseek(m_fd, 0, SEEK_CUR);
+ const off_t newPos = ::lseek(m_fd, count, SEEK_CUR);
+
+ return static_cast <size_type>(newPos - curPos);
+}
+
+
+
+//
+// posixFileWriter
+//
+
+posixFileWriter::posixFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath)
+ : m_path(path), m_nativePath(nativePath)
+{
+}
+
+
+vmime::utility::outputStream* posixFileWriter::getOutputStream()
+{
+ int fd = 0;
+
+ if ((fd = ::open(m_nativePath.c_str(), O_RDONLY, 0660)) == -1)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ return new posixFileWriterOutputStream(m_path, fd);
+}
+
+
+
+//
+// posixFileReader
+//
+
+posixFileReader::posixFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath)
+ : m_path(path), m_nativePath(nativePath)
+{
+}
+
+
+vmime::utility::inputStream* posixFileReader::getInputStream()
+{
+ int fd = 0;
+
+ if ((fd = ::open(m_nativePath.c_str(), O_RDONLY, 0660)) == -1)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ return new posixFileReaderInputStream(m_path, fd);
+}
+
+
+
+//
+// posixFile
+//
+
+posixFile::posixFile(const vmime::utility::file::path& path)
+ : m_path(path), m_nativePath(posixFileSystemFactory::pathToStringImpl(path))
+{
+}
+
+
+void posixFile::createFile()
+{
+ int fd = 0;
+
+ if ((fd = ::open(m_nativePath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660)) == -1)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ ::close(fd);
+}
+
+
+void posixFile::createDirectory(const bool createAll)
+{
+ createDirectoryImpl(m_path, m_path, createAll);
+}
+
+
+const bool posixFile::isFile() const
+{
+ struct stat buf;
+ return (::stat(m_nativePath.c_str(), &buf) == 0 && S_ISREG(buf.st_mode));
+}
+
+
+const bool posixFile::isDirectory() const
+{
+ struct stat buf;
+ return (::stat(m_nativePath.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode));
+}
+
+
+const bool posixFile::canRead() const
+{
+ struct stat buf;
+ return (::stat(m_nativePath.c_str(), &buf) == 0 &&
+ S_ISREG(buf.st_mode) &&
+ ::access(m_nativePath.c_str(), R_OK | F_OK) == 0);
+}
+
+
+const bool posixFile::canWrite() const
+{
+ struct stat buf;
+ return (::stat(m_nativePath.c_str(), &buf) == 0 &&
+ S_ISREG(buf.st_mode) &&
+ ::access(m_nativePath.c_str(), W_OK | F_OK) == 0);
+}
+
+
+const posixFile::length_type posixFile::getLength()
+{
+ struct stat buf;
+
+ if (::stat(m_nativePath.c_str(), &buf) != 0)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ return static_cast <length_type>(buf.st_size);
+}
+
+
+const posixFile::path& posixFile::getFullPath() const
+{
+ return (m_path);
+}
+
+
+const bool posixFile::exists() const
+{
+ struct stat buf;
+ return (::stat(m_nativePath.c_str(), &buf) == 0);
+}
+
+
+const vmime::utility::file* posixFile::getParent() const
+{
+ if (m_path.isEmpty())
+ return NULL;
+ else
+ return new posixFile(m_path.getParent());
+}
+
+
+void posixFile::rename(const path& newName)
+{
+ const vmime::string newNativePath = posixFileSystemFactory::pathToStringImpl(newName);
+
+ if (::rename(m_nativePath.c_str(), newNativePath.c_str()) != 0)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ m_path = newName;
+ m_nativePath = newNativePath;
+}
+
+
+void posixFile::remove()
+{
+ struct stat buf;
+
+ if (::stat(m_nativePath.c_str(), &buf) != 0)
+ posixFileSystemFactory::reportError(m_path, errno);
+
+ if (S_ISDIR(buf.st_mode))
+ {
+ if (::rmdir(m_nativePath.c_str()) != 0)
+ posixFileSystemFactory::reportError(m_path, errno);
+ }
+ else if (S_ISREG(buf.st_mode))
+ {
+ if (::unlink(m_nativePath.c_str()) != 0)
+ posixFileSystemFactory::reportError(m_path, errno);
+ }
+}
+
+
+vmime::utility::fileWriter* posixFile::getFileWriter()
+{
+ return new posixFileWriter(m_path, m_nativePath);
+}
+
+
+vmime::utility::fileReader* posixFile::getFileReader()
+{
+ return new posixFileReader(m_path, m_nativePath);
+}
+
+
+vmime::utility::fileIterator* posixFile::getFiles() const
+{
+ if (!isDirectory())
+ throw vmime::exceptions::not_a_directory(m_path);
+
+ return new posixFileIterator(m_path, m_nativePath);
+}
+
+
+void posixFile::createDirectoryImpl(const vmime::utility::file::path& fullPath,
+ const vmime::utility::file::path& path, const bool recursive)
+{
+ const vmime::string nativePath = posixFileSystemFactory::pathToStringImpl(path);
+ struct stat buf;
+
+ if (::stat(nativePath.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode))
+ return;
+
+ if (!path.isEmpty() && recursive)
+ createDirectoryImpl(fullPath, path.getParent(), true);
+
+ if (::mkdir(nativePath.c_str(), 0660) != 0)
+ posixFileSystemFactory::reportError(fullPath, errno);
+}
+
+
+
+//
+// posixFileSystemFactory
+//
+
+vmime::utility::file* posixFileSystemFactory::create(const vmime::utility::file::path& path) const
+{
+ return new posixFile(path);
+}
+
+
+const vmime::utility::file::path posixFileSystemFactory::stringToPath(const vmime::string& str) const
+{
+ return (stringToPathImpl(str));
+}
+
+
+const vmime::string posixFileSystemFactory::pathToString(const vmime::utility::file::path& path) const
+{
+ return (pathToStringImpl(path));
+}
+
+
+const vmime::utility::file::path posixFileSystemFactory::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++;
+ }
+
+ return (path);
+}
+
+
+const vmime::string posixFileSystemFactory::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 posixFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const
+{
+ return (comp.getBuffer().find_first_of("/*") == vmime::string::npos);
+}
+
+
+const bool posixFileSystemFactory::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 posixFileSystemFactory::reportError(const vmime::utility::path& path, const int err)
+{
+ vmime::string desc;
+
+ switch (err)
+ {
+ case EEXIST: desc = "EEXIST: file already exists."; break;
+ case EISDIR: desc = "EISDIR: path refers to a directory."; break;
+ case EACCES: desc = "EACCES: permission denied"; break;
+ case ENAMETOOLONG: desc = "ENAMETOOLONG: path too long."; break;
+ case ENOENT: desc = "ENOENT: a directory in the path does not exist."; break;
+ case ENOTDIR: desc = "ENOTDIR: path is not a directory."; break;
+ case EROFS: desc = "EROFS: read-only filesystem."; break;
+ case ELOOP: desc = "ELOOP: too many symbolic links."; break;
+ case ENOSPC: desc = "ENOSPC: no space left on device."; break;
+ case ENOMEM: desc = "ENOMEM: insufficient kernel memory."; break;
+ case EMFILE: desc = "ENFILE: limit on number of files open by the process has been reached."; break;
+ case ENFILE: desc = "ENFILE: limit on number of files open on the system has been reached."; break;
+ case ENOTEMPTY: desc = "ENOTEMPTY: directory is not empty."; break;
+
+ default:
+
+ std::ostringstream oss;
+ oss << "Unknown error " << err << ".";
+
+ desc = oss.str();
+ break;
+ }
+
+ throw vmime::exceptions::filesystem_exception(desc, path);
+}
+
+
+
+} // posix
+} // platforms
+} // vmime
+
+
+#endif // VMIME_HAVE_FILESYSTEM_FEATURES
diff --git a/src/platforms/posix/file.hpp b/src/platforms/posix/file.hpp
new file mode 100644
index 00000000..5ebc7b59
--- /dev/null
+++ b/src/platforms/posix/file.hpp
@@ -0,0 +1,203 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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_POSIX_FILE_HPP_INCLUDED
+#define VMIME_PLATFORMS_POSIX_FILE_HPP_INCLUDED
+
+
+#include "../../utility/file.hpp"
+
+
+#if VMIME_HAVE_FILESYSTEM_FEATURES
+
+
+#include <dirent.h>
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+class posixFileWriterOutputStream : public vmime::utility::outputStream
+{
+public:
+
+ posixFileWriterOutputStream(const vmime::utility::file::path& path, const int fd);
+ ~posixFileWriterOutputStream();
+
+ void write(const value_type* const data, const size_type count);
+
+private:
+
+ const vmime::utility::file::path m_path;
+ const int m_fd;
+};
+
+
+
+class posixFileReaderInputStream : public vmime::utility::inputStream
+{
+public:
+
+ posixFileReaderInputStream(const vmime::utility::file::path& path, const int fd);
+ ~posixFileReaderInputStream();
+
+ 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;
+ const int m_fd;
+
+ bool m_eof;
+};
+
+
+
+class posixFileWriter : public vmime::utility::fileWriter
+{
+public:
+
+ posixFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath);
+
+ vmime::utility::outputStream* getOutputStream();
+
+private:
+
+ vmime::utility::file::path m_path;
+ vmime::string m_nativePath;
+};
+
+
+
+class posixFileReader : public vmime::utility::fileReader
+{
+public:
+
+ posixFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath);
+
+ vmime::utility::inputStream* getInputStream();
+
+private:
+
+ vmime::utility::file::path m_path;
+ vmime::string m_nativePath;
+};
+
+
+
+class posixFileIterator : public vmime::utility::fileIterator
+{
+public:
+
+ posixFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath);
+ ~posixFileIterator();
+
+ const bool hasMoreElements() const;
+ vmime::utility::file* nextElement();
+
+private:
+
+ vmime::utility::file::path m_path;
+ vmime::string m_nativePath;
+
+ DIR* m_dir;
+ struct dirent* m_dirEntry;
+};
+
+
+
+class posixFile : public vmime::utility::file
+{
+public:
+
+ posixFile(const vmime::utility::file::path& path);
+
+ 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 vmime::utility::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 posixFileSystemFactory : 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);
+};
+
+
+} // posix
+} // platforms
+} // vmime
+
+
+#endif // VMIME_HAVE_FILESYSTEM_FEATURES
+
+#endif // VMIME_PLATFORMS_POSIX_FILE_HPP_INCLUDED
diff --git a/src/platforms/posix/handler.cpp b/src/platforms/posix/handler.cpp
new file mode 100644
index 00000000..1c3fd7d4
--- /dev/null
+++ b/src/platforms/posix/handler.cpp
@@ -0,0 +1,186 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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 "handler.hpp"
+
+#include <time.h>
+
+#include <unistd.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <netdb.h>
+
+#include <string.h>
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+posixHandler::posixHandler()
+ : m_socketFactory(new posixSocketFactory()),
+ m_fileSysFactory(new posixFileSystemFactory())
+{
+}
+
+
+posixHandler::~posixHandler()
+{
+ delete (m_socketFactory);
+ delete (m_fileSysFactory);
+}
+
+
+const unsigned int posixHandler::getUnixTime() const
+{
+ return ::time(NULL);
+}
+
+
+const vmime::datetime posixHandler::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 = ::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 posixHandler::getLocaleCharset() const
+{
+ vmime::string prevLocale(::setlocale(::LC_ALL, ""));
+ vmime::charset ch(::nl_langinfo(::CODESET));
+ ::setlocale(::LC_ALL, prevLocale.c_str());
+
+ return (ch);
+}
+
+
+const vmime::string posixHandler::getHostName() const
+{
+ std::vector <vmime::string> 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 posixHandler::getProcessId() const
+{
+ return (::getpid());
+}
+
+
+vmime::messaging::socketFactory* posixHandler::getSocketFactory
+ (const vmime::string& /* name */) const
+{
+ return (m_socketFactory);
+}
+
+
+vmime::messaging::timeoutHandlerFactory* posixHandler::getTimeoutHandlerFactory
+ (const vmime::string& /* name */) const
+{
+ // Not used by default
+ return (NULL);
+}
+
+
+vmime::utility::fileSystemFactory* posixHandler::getFileSystemFactory() const
+{
+ return (m_fileSysFactory);
+}
+
+
+void posixHandler::wait() const
+{
+ ::sleep(1);
+}
+
+
+} // posix
+} // platforms
+} // vmime
diff --git a/src/platforms/posix/handler.hpp b/src/platforms/posix/handler.hpp
new file mode 100644
index 00000000..53ca53b9
--- /dev/null
+++ b/src/platforms/posix/handler.hpp
@@ -0,0 +1,78 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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_POSIX_HANDLER_HPP_INCLUDED
+#define VMIME_PLATFORMS_POSIX_HANDLER_HPP_INCLUDED
+
+
+#include "../../config.hpp"
+#include "../../platformDependant.hpp"
+
+#if VMIME_HAVE_MESSAGING_FEATURES
+ #include "socket.hpp"
+#endif
+
+#if VMIME_HAVE_FILESYSTEM_FEATURES
+ #include "file.hpp"
+#endif
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+class posixHandler : public vmime::platformDependant::handler
+{
+public:
+
+ posixHandler();
+ ~posixHandler();
+
+ 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;
+
+ vmime::messaging::socketFactory* getSocketFactory(const vmime::string& name) const;
+
+ vmime::messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& name) const;
+
+ vmime::utility::fileSystemFactory* getFileSystemFactory() const;
+
+ void wait() const;
+
+private:
+
+ posixSocketFactory* m_socketFactory;
+ posixFileSystemFactory* m_fileSysFactory;
+};
+
+
+} // posix
+} // platforms
+} // vmime
+
+
+#endif // VMIME_PLATFORMS_POSIX_HANDLER_HPP_INCLUDED
diff --git a/src/platforms/posix/socket.cpp b/src/platforms/posix/socket.cpp
new file mode 100644
index 00000000..8d4f8fbc
--- /dev/null
+++ b/src/platforms/posix/socket.cpp
@@ -0,0 +1,190 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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 "socket.hpp"
+
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+
+#include "../../exception.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+//
+// posixSocket
+//
+
+posixSocket::posixSocket()
+ : m_desc(-1)
+{
+}
+
+
+posixSocket::~posixSocket()
+{
+ if (m_desc != -1)
+ ::close(m_desc);
+}
+
+
+void posixSocket::connect(const vmime::string& address, const vmime::port_t port)
+{
+ // Close current connection, if any
+ if (m_desc != -1)
+ {
+ ::close(m_desc);
+ m_desc = -1;
+ }
+
+ // Resolve address
+ ::sockaddr_in addr;
+
+ memset(&addr, 0, sizeof(addr));
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons((unsigned short) port);
+ addr.sin_addr.s_addr = ::inet_addr(address.c_str());
+
+ if (addr.sin_addr.s_addr == (::in_addr_t) -1)
+ {
+ ::hostent* hostInfo = (hostent*) ::gethostbyname(address.c_str());
+
+ if (hostInfo == NULL)
+ {
+ // Error: cannot resolve address
+ throw vmime::exceptions::connection_error();
+ }
+
+ bcopy(hostInfo->h_addr, (char*) &addr.sin_addr, hostInfo->h_length);
+ }
+ else
+ {
+ // Error: cannot resolve address
+ throw vmime::exceptions::connection_error();
+ }
+
+ // Get a new socket
+ m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
+
+ if (m_desc == -1)
+ throw vmime::exceptions::connection_error();
+
+ // Start connection
+ if (::connect(m_desc, (sockaddr*) &addr, sizeof(addr)) == -1)
+ {
+ ::close(m_desc);
+ m_desc = -1;
+
+ // Error
+ throw vmime::exceptions::connection_error();
+ }
+}
+
+
+const bool posixSocket::isConnected() const
+{
+ return (m_desc != -1);
+}
+
+
+void posixSocket::disconnect()
+{
+ if (m_desc != -1)
+ {
+ ::shutdown(m_desc, SHUT_RDWR);
+ ::close(m_desc);
+
+ m_desc = -1;
+ }
+}
+
+
+void posixSocket::receive(vmime::string& buffer)
+{
+ ::ssize_t 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 posixSocket::receiveRaw(char* buffer, const int count)
+{
+ ::ssize_t ret = ::recv(m_desc, buffer, count, 0);
+
+ if (ret == -1)
+ {
+ // Error or no data
+ return (0);
+ }
+ else
+ {
+ return (ret);
+ }
+}
+
+
+void posixSocket::send(const vmime::string& buffer)
+{
+ ::send(m_desc, buffer.data(), buffer.length(), 0);
+}
+
+
+void posixSocket::sendRaw(const char* buffer, const int count)
+{
+ ::send(m_desc, buffer, count, 0);
+}
+
+
+
+
+//
+// posixSocketFactory
+//
+
+vmime::messaging::socket* posixSocketFactory::create()
+{
+ return new posixSocket();
+}
+
+
+} // posix
+} // platforms
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES
diff --git a/src/platforms/posix/socket.hpp b/src/platforms/posix/socket.hpp
new file mode 100644
index 00000000..44d4ab73
--- /dev/null
+++ b/src/platforms/posix/socket.hpp
@@ -0,0 +1,75 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// 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_POSIX_SOCKET_HPP_INCLUDED
+#define VMIME_PLATFORMS_POSIX_SOCKET_HPP_INCLUDED
+
+
+#include "../../messaging/socket.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+class posixSocket : public vmime::messaging::socket
+{
+public:
+
+ posixSocket();
+ ~posixSocket();
+
+ 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];
+ int m_desc;
+};
+
+
+
+class posixSocketFactory : public vmime::messaging::socketFactory
+{
+public:
+
+ vmime::messaging::socket* create();
+};
+
+
+} // posix
+} // platforms
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES
+
+#endif // VMIME_PLATFORMS_POSIX_SOCKET_HPP_INCLUDED
diff --git a/tests/parser/encoderTest.cpp b/tests/parser/encoderTest.cpp
index ad572b2d..d3990928 100644
--- a/tests/parser/encoderTest.cpp
+++ b/tests/parser/encoderTest.cpp
@@ -23,7 +23,7 @@
#include <ostream>
#include "../../src/vmime"
-#include "../../examples/common.inc"
+#include "../../src/platforms/posix/handler.hpp"
using namespace unitpp;
@@ -284,7 +284,7 @@ namespace
encoderTest() : suite("vmime::encoder")
{
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Base64", testcase(this, "Base64", &encoderTest::testBase64));
add("QuotedPrintable", testcase(this, "QuotedPrintable", &encoderTest::testQuotedPrintable));
diff --git a/tests/parser/headerTest.cpp b/tests/parser/headerTest.cpp
index c434adc5..ced0dbd4 100644
--- a/tests/parser/headerTest.cpp
+++ b/tests/parser/headerTest.cpp
@@ -23,7 +23,7 @@
#include <ostream>
#include "../../src/vmime"
-#include "../../examples/common.inc"
+#include "../../src/platforms/posix/handler.hpp"
using namespace unitpp;
@@ -328,7 +328,7 @@ namespace
headerTest() : suite("vmime::header")
{
// VMime initialization
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Has", testcase(this, "Has1", &headerTest::testHas1));
add("Has", testcase(this, "Has2", &headerTest::testHas2));
diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp
index 79a4004c..95547e9d 100644
--- a/tests/parser/mailboxTest.cpp
+++ b/tests/parser/mailboxTest.cpp
@@ -23,7 +23,7 @@
#include <ostream>
#include "../../src/vmime"
-#include "../../examples/common.inc"
+#include "../../src/platforms/posix/handler.hpp"
#include "testUtils.hpp"
@@ -101,7 +101,7 @@ namespace
mailboxTest() : suite("vmime::mailbox")
{
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &mailboxTest::testParse));
diff --git a/tests/parser/mediaTypeTest.cpp b/tests/parser/mediaTypeTest.cpp
index 2431d795..8b1ee550 100644
--- a/tests/parser/mediaTypeTest.cpp
+++ b/tests/parser/mediaTypeTest.cpp
@@ -23,7 +23,7 @@
#include <ostream>
#include "../../src/vmime"
-#include "../../examples/common.inc"
+#include "../../src/platforms/posix/handler.hpp"
using namespace unitpp;
@@ -98,7 +98,7 @@ namespace
mediaTypeTest() : suite("vmime::mediaType")
{
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Constructors", testcase(this, "Constructors", &mediaTypeTest::testConstructors));
add("Copy", testcase(this, "Copy", &mediaTypeTest::testCopy));
diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp
index 6dfb5016..523b5883 100644
--- a/tests/parser/textTest.cpp
+++ b/tests/parser/textTest.cpp
@@ -23,7 +23,7 @@
#include <ostream>
#include "../../src/vmime"
-#include "../../examples/common.inc"
+#include "../../src/platforms/posix/handler.hpp"
#include "testUtils.hpp"
@@ -120,7 +120,7 @@ namespace
textTest() : suite("vmime::text")
{
- vmime::platformDependant::setHandler<my_handler>();
+ vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Constructors", testcase(this, "Constructors", &textTest::testConstructors));
add("Copy", testcase(this, "Copy", &textTest::testCopy));