[haiku-commits] r43141 - in haiku/trunk: headers/private/mail src/kits/mail

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 2 Nov 2011 23:56:50 +0100 (CET)

Author: axeld
Date: 2011-11-02 23:56:50 +0100 (Wed, 02 Nov 2011)
New Revision: 43141
Changeset: https://dev.haiku-os.org/changeset/43141

Modified:
   haiku/trunk/headers/private/mail/ServerConnection.h
   haiku/trunk/src/kits/mail/Jamfile
   haiku/trunk/src/kits/mail/ServerConnection.cpp
Log:
* Put ServerConnection into the BPrivate namespace as it should have been.
* Fixed completely broken error reporting; Write()/Read() will now return the
  proper error code (and ssize_t instead of int32).
* Reimplemented WaitForData() using poll() which is more efficient.
* Now uses BNetworkAddress to resolve the server address which also should now
  work with IPv6.
* Removed some unused headers.
* Minor coding style cleanup.


Modified: haiku/trunk/headers/private/mail/ServerConnection.h
===================================================================
--- haiku/trunk/headers/private/mail/ServerConnection.h 2011-11-02 22:56:20 UTC 
(rev 43140)
+++ haiku/trunk/headers/private/mail/ServerConnection.h 2011-11-02 22:56:50 UTC 
(rev 43141)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010, Haiku Inc. All Rights Reserved.
+ * Copyright 2010-2011, Haiku Inc. All Rights Reserved.
  * Copyright 2010 Clemens Zeidler. All rights reserved.
  *
  * Distributed under the terms of the MIT License.
@@ -11,20 +11,12 @@
 #include "SupportDefs.h"
 
 
-class AbstractConnection {
-public:
-       virtual                                         ~AbstractConnection();
+namespace BPrivate {
 
-       virtual status_t                        Connect(const char* server, 
uint32 port) = 0;
-       virtual status_t                        Disconnect() = 0;
 
-       virtual status_t                        WaitForData(bigtime_t timeout) 
= 0;
+class AbstractConnection;
 
-       virtual int32                           Read(char* buffer, uint32 
nBytes) = 0;
-       virtual int32                           Write(const char* buffer, 
uint32 nBytes) = 0;
-};
 
-
 class ServerConnection {
 public:
                                                                
ServerConnection();
@@ -39,11 +31,18 @@
 
                        status_t                        WaitForData(bigtime_t 
timeout);
 
-                       int32                           Read(char* buffer, 
uint32 nBytes);
-                       int32                           Write(const char* 
buffer, uint32 nBytes);
+                       ssize_t                         Read(char* buffer, 
uint32 length);
+                       ssize_t                         Write(const char* 
buffer, uint32 length);
 
 private:
                        AbstractConnection*     fConnection;
 };
 
+
+}      // namespace BPrivate
+
+
+using BPrivate::ServerConnection;
+
+
 #endif // SERVER_CONNECTION_H

Modified: haiku/trunk/src/kits/mail/Jamfile
===================================================================
--- haiku/trunk/src/kits/mail/Jamfile   2011-11-02 22:56:20 UTC (rev 43140)
+++ haiku/trunk/src/kits/mail/Jamfile   2011-11-02 22:56:50 UTC (rev 43141)
@@ -53,9 +53,7 @@
 SharedLibrary libmail.so :
        $(sources)
        :
-       be
-       libtextencoding.so
-       tracker
+       be libbnetapi.so libtextencoding.so tracker
        $(TARGET_LIBSTDC++)
        $(TARGET_NETWORK_LIBS)
        $(TARGET_SELECT_UNAME_ETC_LIB)

Modified: haiku/trunk/src/kits/mail/ServerConnection.cpp
===================================================================
--- haiku/trunk/src/kits/mail/ServerConnection.cpp      2011-11-02 22:56:20 UTC 
(rev 43140)
+++ haiku/trunk/src/kits/mail/ServerConnection.cpp      2011-11-02 22:56:50 UTC 
(rev 43141)
@@ -1,31 +1,52 @@
+/*
+ * Copyright 2010-2011, Haiku, Inc. All rights reserved.
+ * Copyright 2010, Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ * Distributed under the terms of the MIT License.
+ */
+
+
 #include "ServerConnection.h"
 
-#include <arpa/inet.h>
-#include <netdb.h>
+#include <errno.h>
+#include <sys/poll.h>
 #include <unistd.h>
 
 #ifdef USE_SSL
-#include <openssl/ssl.h>
-#include <openssl/rand.h>
-#else
-#include <string.h>
-#include <sys/time.h>
+#      include <openssl/ssl.h>
+#      include <openssl/rand.h>
 #endif
 
 #include <Autolock.h>
 #include <Locker.h>
+#include <NetworkAddress.h>
 
 
 #define DEBUG_SERVER_CONNECTION
-
 #ifdef DEBUG_SERVER_CONNECTION
-#include <stdio.h>
-#define TRACE(x...) printf(x)
+#      include <stdio.h>
+#      define TRACE(x...) printf(x)
 #else
-#define TRACE(x...) /* nothing */
+#      define TRACE(x...) ;
 #endif
 
 
+namespace BPrivate {
+
+
+class AbstractConnection {
+public:
+       virtual                                         ~AbstractConnection();
+
+       virtual status_t                        Connect(const char* server, 
uint32 port) = 0;
+       virtual status_t                        Disconnect() = 0;
+
+       virtual status_t                        WaitForData(bigtime_t timeout) 
= 0;
+
+       virtual ssize_t                         Read(char* buffer, uint32 
length) = 0;
+       virtual ssize_t                         Write(const char* buffer, 
uint32 length) = 0;
+};
+
+
 class SocketConnection : public AbstractConnection {
 public:
                                                                
SocketConnection();
@@ -35,8 +56,8 @@
 
                        status_t                        WaitForData(bigtime_t 
timeout);
 
-                       int32                           Read(char* buffer, 
uint32 nBytes);
-                       int32                           Write(const char* 
buffer, uint32 nBytes);
+                       ssize_t                         Read(char* buffer, 
uint32 length);
+                       ssize_t                         Write(const char* 
buffer, uint32 length);
 
 protected:
                        int                                     fSocket;
@@ -44,6 +65,8 @@
 
 
 #ifdef USE_SSL
+
+
 class InitSSL {
 public:
        InitSSL()
@@ -62,8 +85,7 @@
        };
 
 
-       status_t
-       InitCheck()
+       status_t InitCheck()
        {
                return fInit ? B_OK : B_ERROR;
        }
@@ -73,9 +95,6 @@
 };
 
 
-static InitSSL gInitSSL;
-
-
 class SSLConnection : public SocketConnection {
 public:
                                                                SSLConnection();
@@ -85,34 +104,40 @@
 
                        status_t                        WaitForData(bigtime_t 
timeout);
 
-                       int32                           Read(char* buffer, 
uint32 nBytes);
-                       int32                           Write(const char* 
buffer, uint32 nBytes);
+                       ssize_t                         Read(char* buffer, 
uint32 length);
+                       ssize_t                         Write(const char* 
buffer, uint32 length);
 
 private:
                        SSL_CTX*                        fCTX;
                        SSL*                            fSSL;
                        BIO*                            fBIO;
 };
-#endif
 
 
+static InitSSL gInitSSL;
+
+
+#endif // USE_SSL
+
+
 AbstractConnection::~AbstractConnection()
 {
-
 }
 
 
+// #pragma mark -
+
+
 ServerConnection::ServerConnection()
        :
        fConnection(NULL)
 {
-
 }
 
 
 ServerConnection::~ServerConnection()
 {
-       if (fConnection)
+       if (fConnection != NULL)
                fConnection->Disconnect();
        delete fConnection;
 }
@@ -158,7 +183,7 @@
 }
 
 
-int32
+ssize_t
 ServerConnection::Read(char* buffer, uint32 nBytes)
 {
        if (fConnection == NULL)
@@ -167,7 +192,7 @@
 }
 
 
-int32
+ssize_t
 ServerConnection::Write(const char* buffer, uint32 nBytes)
 {
        if (fConnection == NULL)
@@ -176,11 +201,13 @@
 }
 
 
+// #pragma mark -
+
+
 SocketConnection::SocketConnection()
        :
        fSocket(-1)
 {
-
 }
 
 
@@ -191,29 +218,20 @@
                Disconnect();
 
        TRACE("SocketConnection to server %s:%i\n", server, (int)port);
-       uint32 hostIP = inet_addr(server);
-               // first see if we can parse it as a numeric address
-       if (hostIP == 0 || hostIP == (uint32)-1) {
-               struct hostent *he = gethostbyname(server);
-               hostIP = he ? *((uint32*)he->h_addr) : 0;
-       }
-       if (hostIP == 0)
-               return B_ERROR;
 
-       fSocket = socket(AF_INET, SOCK_STREAM, 0);
+       BNetworkAddress address;
+       status_t status = address.SetTo(server, port);
+       if (status != B_OK)
+               return status;
+
+       fSocket = socket(address.Family(), SOCK_STREAM, 0);
        if (fSocket < 0)
-               return B_ERROR;
+               return errno;
 
-       sockaddr_in saAddr;
-       memset(&saAddr, 0, sizeof(saAddr));
-       saAddr.sin_family = AF_INET;
-       saAddr.sin_port = htons(port);
-       saAddr.sin_addr.s_addr = hostIP;
-       int result = connect(fSocket, (struct sockaddr*)&saAddr,
-               sizeof(saAddr));
+       int result = connect(fSocket, address, address.Length());
        if (result < 0) {
                close(fSocket);
-               return B_ERROR;
+               return errno;
        }
 
        TRACE("SocketConnection: connected\n");
@@ -234,47 +252,58 @@
 status_t
 SocketConnection::WaitForData(bigtime_t timeout)
 {
-       timeval tv;
-       fd_set fds;
-       tv.tv_sec = long(timeout / 1e6);
-       tv.tv_usec = long(timeout - (tv.tv_sec * 1e6));
+       struct pollfd entry;
+       entry.fd = fSocket;
+       entry.events = POLLIN;
 
-       /* Initialize (clear) the socket mask. */
-       FD_ZERO(&fds);
-       /* Set the socket in the mask. */
-       FD_SET(fSocket, &fds);
+       int timeoutMillis = -1;
+       if (timeout > 0)
+               timeoutMillis = timeout / 1000;
 
-       int result = select(fSocket + 1, &fds, NULL, NULL, &tv);
+       int result = poll(&entry, 1, timeoutMillis);
        if (result == 0)
                return B_TIMED_OUT;
        if (result < 0)
-               return B_ERROR;
+               return errno;
+
        return B_OK;
 }
 
 
-int32
-SocketConnection::Read(char* buffer, uint32 nBytes)
+ssize_t
+SocketConnection::Read(char* buffer, uint32 length)
 {
-       return recv(fSocket, buffer, nBytes, 0);
+       ssize_t bytesReceived = recv(fSocket, buffer, length, 0);
+       if (bytesReceived < 0)
+               return errno;
+
+       return bytesReceived;
 }
 
 
-int32
-SocketConnection::Write(const char* buffer, uint32 nBytes)
+ssize_t
+SocketConnection::Write(const char* buffer, uint32 length)
 {
-       return send(fSocket, buffer, nBytes, 0);
+       ssize_t bytesWritten = send(fSocket, buffer, length, 0);
+       if (bytesWritten < 0)
+               return errno;
+
+       return bytesWritten;
 }
 
 
+// #pragma mark -
+
+
 #ifdef USE_SSL
+
+
 SSLConnection::SSLConnection()
        :
        fCTX(NULL),
        fSSL(NULL),
        fBIO(NULL)
 {
-       
 }
 
 
@@ -329,31 +358,46 @@
 status_t
 SSLConnection::WaitForData(bigtime_t timeout)
 {
-       if (!fSSL)
-               return B_ERROR;
-       if (SSL_pending(fSSL) > 0) {
+       if (fSSL == NULL)
+               return B_NO_INIT;
+       if (SSL_pending(fSSL) > 0)
                return B_OK;
-       }
+
        return SocketConnection::WaitForData(timeout);
 }
 
 
-int32
-SSLConnection::Read(char* buffer, uint32 nBytes)
+ssize_t
+SSLConnection::Read(char* buffer, uint32 length)
 {
-       if (!fSSL)
-               return B_ERROR;
-       return SSL_read(fSSL, buffer, nBytes);
+       if (fSSL == NULL)
+               return B_NO_INIT;
+
+       int bytesRead = SSL_read(fSSL, buffer, length);
+       if (bytesRead > 0)
+               return bytesRead;
+
+       // TODO: translate SSL error codes!
+       return B_ERROR;
 }
 
 
-int32
-SSLConnection::Write(const char* buffer, uint32 nBytes)
+ssize_t
+SSLConnection::Write(const char* buffer, uint32 length)
 {
-       if (!fSSL)
-               return B_ERROR;
-       return SSL_write(fSSL, buffer, nBytes);
+       if (fSSL == NULL)
+               return B_NO_INIT;
+
+       int bytesWritten = SSL_write(fSSL, buffer, length);
+       if (bytesWritten > 0)
+               return bytesWritten;
+
+       // TODO: translate SSL error codes!
+       return B_ERROR;
 }
 
 
-#endif
+#endif // USE_SSL
+
+
+}      // namespace BPrivate


Other related posts:

  • » [haiku-commits] r43141 - in haiku/trunk: headers/private/mail src/kits/mail - axeld