aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog27
-rw-r--r--camel/camel-tcp-stream-openssl.c34
-rw-r--r--camel/camel-tcp-stream-raw.c36
-rw-r--r--camel/camel-tcp-stream-ssl.c34
-rw-r--r--camel/camel-tcp-stream.c93
-rw-r--r--camel/camel-tcp-stream.h22
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c62
-rw-r--r--camel/providers/smtp/camel-smtp-transport.h9
8 files changed, 238 insertions, 79 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 2f4d8f4b71..04ac36003d 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,30 @@
+2002-03-10 Dan Winship <danw@ximian.com>
+
+ * camel-tcp-stream.c (camel_tcp_stream_get_socket): Remove this:
+ it couldn't be generically used, because different subclasses
+ returned entirely different types of data.
+ (camel_tcp_stream_get_local_address,
+ camel_tcp_stream_get_remote_address): Add these to replace what
+ get_socket was being used for.
+ (camel_tcp_address_new, camel_tcp_address_free): Utility functions
+ for get_{local,remote}_address.
+
+ * providers/smtp/camel-smtp-transport.c: Change localaddr to a
+ CamelTcpAddress *.
+ (connect_to_server): Call camel_tcp_stream_get_local_address to
+ get the local IP address.
+ (smtp_disconnect): free localaddr.
+ (smtp_helo): Update for localaddr change.
+
+ * camel-tcp-stream-raw.c (stream_get_socket): Remove
+ (stream_get_local_address, stream_get_remote_address): Implement.
+
+ * camel-tcp-stream-ssl.c (stream_get_socket): Remove
+ (stream_get_local_address, stream_get_remote_address): Implement.
+
+ * camel-tcp-stream-openssl.c (stream_get_socket): Remove
+ (stream_get_local_address, stream_get_remote_address): Implement.
+
2002-03-08 Jeffrey Stedfast <fejj@ximian.com>
* providers/pop3/camel-pop3-provider.c
diff --git a/camel/camel-tcp-stream-openssl.c b/camel/camel-tcp-stream-openssl.c
index 2c3709fbd8..7996b37ae5 100644
--- a/camel/camel-tcp-stream-openssl.c
+++ b/camel/camel-tcp-stream-openssl.c
@@ -62,7 +62,8 @@ static int stream_close (CamelStream *stream);
static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port);
static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-static gpointer stream_get_socket (CamelTcpStream *stream);
+static CamelTcpAddress *stream_get_local_address (CamelTcpStream *stream);
+static CamelTcpAddress *stream_get_remote_address (CamelTcpStream *stream);
static SSL *open_ssl_connection (CamelService *service, int sockfd, CamelTcpStreamOpenSSL *openssl);
@@ -94,7 +95,8 @@ camel_tcp_stream_openssl_class_init (CamelTcpStreamOpenSSLClass *camel_tcp_strea
camel_tcp_stream_class->connect = stream_connect;
camel_tcp_stream_class->getsockopt = stream_getsockopt;
camel_tcp_stream_class->setsockopt = stream_setsockopt;
- camel_tcp_stream_class->get_socket = stream_get_socket;
+ camel_tcp_stream_class->get_local_address = stream_get_local_address;
+ camel_tcp_stream_class->get_remote_address = stream_get_remote_address;
/* init OpenSSL stuff */
SSLeay_add_ssl_algorithms ();
@@ -788,10 +790,32 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data)
sizeof (data->value));
}
-static gpointer
-stream_get_socket (CamelTcpStream *stream)
+static CamelTcpAddress *
+stream_get_local_address (CamelTcpStream *stream)
{
- return GINT_TO_POINTER (CAMEL_TCP_STREAM_OPENSSL (stream)->priv->sockfd);
+ struct sockaddr_in sin;
+ socklen_t len;
+
+ if (getsockname (CAMEL_TCP_STREAM_OPENSSL (stream)->priv->sockfd,
+ (struct sockaddr *)&sin, &len) == -1)
+ return NULL;
+
+ return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, sin.sin_port,
+ 4, &sin.sin_addr);
+}
+
+static CamelTcpAddress *
+stream_get_remote_address (CamelTcpStream *stream)
+{
+ struct sockaddr_in sin;
+ socklen_t len;
+
+ if (getpeername (CAMEL_TCP_STREAM_OPENSSL (stream)->priv->sockfd,
+ (struct sockaddr *)&sin, &len) == -1)
+ return NULL;
+
+ return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, sin.sin_port,
+ 4, &sin.sin_addr);
}
#endif /* HAVE_OPENSSL */
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index e7003ac53d..cd3a74d6f2 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -48,7 +48,8 @@ static int stream_close (CamelStream *stream);
static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port);
static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-static gpointer stream_get_socket (CamelTcpStream *stream);
+static CamelTcpAddress *stream_get_local_address (CamelTcpStream *stream);
+static CamelTcpAddress *stream_get_remote_address (CamelTcpStream *stream);
static void
camel_tcp_stream_raw_class_init (CamelTcpStreamRawClass *camel_tcp_stream_raw_class)
@@ -68,8 +69,9 @@ camel_tcp_stream_raw_class_init (CamelTcpStreamRawClass *camel_tcp_stream_raw_cl
camel_tcp_stream_class->connect = stream_connect;
camel_tcp_stream_class->getsockopt = stream_getsockopt;
- camel_tcp_stream_class->setsockopt = stream_setsockopt;
- camel_tcp_stream_class->get_socket = stream_get_socket;
+ camel_tcp_stream_class->setsockopt = stream_setsockopt;
+ camel_tcp_stream_class->get_local_address = stream_get_local_address;
+ camel_tcp_stream_class->get_remote_address = stream_get_remote_address;
}
static void
@@ -565,8 +567,30 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data)
sizeof (data->value));
}
-static gpointer
-stream_get_socket (CamelTcpStream *stream)
+static CamelTcpAddress *
+stream_get_local_address (CamelTcpStream *stream)
{
- return GINT_TO_POINTER (CAMEL_TCP_STREAM_RAW (stream)->sockfd);
+ struct sockaddr_in sin;
+ socklen_t len;
+
+ if (getsockname (CAMEL_TCP_STREAM_RAW (stream)->sockfd,
+ (struct sockaddr *)&sin, &len) == -1)
+ return NULL;
+
+ return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, sin.sin_port,
+ 4, &sin.sin_addr);
+}
+
+static CamelTcpAddress *
+stream_get_remote_address (CamelTcpStream *stream)
+{
+ struct sockaddr_in sin;
+ socklen_t len;
+
+ if (getpeername (CAMEL_TCP_STREAM_RAW (stream)->sockfd,
+ (struct sockaddr *)&sin, &len) == -1)
+ return NULL;
+
+ return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, sin.sin_port,
+ 4, &sin.sin_addr);
}
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 7f914c8734..ac78cc92cb 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -65,7 +65,8 @@ static PRFileDesc *enable_ssl (CamelTcpStreamSSL *ssl, PRFileDesc *fd);
static int stream_connect (CamelTcpStream *stream, struct hostent *host, int port);
static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-static gpointer stream_get_socket (CamelTcpStream *stream);
+static CamelTcpAddress *stream_get_local_address (CamelTcpStream *stream);
+static CamelTcpAddress *stream_get_remote_address (CamelTcpStream *stream);
struct _CamelTcpStreamSSLPrivate {
PRFileDesc *sockfd;
@@ -94,7 +95,8 @@ camel_tcp_stream_ssl_class_init (CamelTcpStreamSSLClass *camel_tcp_stream_ssl_cl
camel_tcp_stream_class->connect = stream_connect;
camel_tcp_stream_class->getsockopt = stream_getsockopt;
camel_tcp_stream_class->setsockopt = stream_setsockopt;
- camel_tcp_stream_class->get_socket = stream_get_socket;
+ camel_tcp_stream_class->get_local_address = stream_get_local_address;
+ camel_tcp_stream_class->get_remote_address = stream_get_remote_address;
}
static void
@@ -613,10 +615,32 @@ stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data)
return 0;
}
-static gpointer
-stream_get_socket (CamelTcpStream *stream)
+static CamelTcpAddress *
+stream_get_local_address (CamelTcpStream *stream)
{
- return (gpointer) CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd;
+ PRFileDesc *sockfd = CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd;
+ PRNetAddr addr;
+
+ PR_GetSockName (sockfd, &addr);
+ if (addr.inet.family != PR_AF_INET)
+ return NULL;
+
+ return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, addr.inet.port,
+ 4, &addr.inet.ip);
+}
+
+static CamelTcpAddress *
+stream_get_remote_address (CamelTcpStream *stream)
+{
+ PRFileDesc *sockfd = CAMEL_TCP_STREAM_SSL (stream)->priv->sockfd;
+ PRNetAddr addr;
+
+ PR_GetPeerName (sockfd, &addr);
+ if (addr.inet.family != PR_AF_INET)
+ return NULL;
+
+ return camel_tcp_address_new (CAMEL_TCP_ADDRESS_IPV4, addr.inet.port,
+ 4, &addr.inet.ip);
}
#endif /* HAVE_NSS */
diff --git a/camel/camel-tcp-stream.c b/camel/camel-tcp-stream.c
index 9ab4ba2e63..2155fba6ad 100644
--- a/camel/camel-tcp-stream.c
+++ b/camel/camel-tcp-stream.c
@@ -36,7 +36,9 @@ static CamelStreamClass *parent_class = NULL;
static int tcp_connect (CamelTcpStream *stream, struct hostent *host, int port);
static int tcp_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static int tcp_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-static gpointer tcp_get_socket (CamelTcpStream *stream);
+static CamelTcpAddress *tcp_get_local_address (CamelTcpStream *stream);
+static CamelTcpAddress *tcp_get_remote_address (CamelTcpStream *stream);
+
static void
camel_tcp_stream_class_init (CamelTcpStreamClass *camel_tcp_stream_class)
@@ -46,10 +48,11 @@ camel_tcp_stream_class_init (CamelTcpStreamClass *camel_tcp_stream_class)
parent_class = CAMEL_STREAM_CLASS (camel_type_get_global_classfuncs (CAMEL_STREAM_TYPE));
/* tcp stream methods */
- camel_tcp_stream_class->connect = tcp_connect;
- camel_tcp_stream_class->getsockopt = tcp_getsockopt;
- camel_tcp_stream_class->setsockopt = tcp_setsockopt;
- camel_tcp_stream_class->get_socket = tcp_get_socket;
+ camel_tcp_stream_class->connect = tcp_connect;
+ camel_tcp_stream_class->getsockopt = tcp_getsockopt;
+ camel_tcp_stream_class->setsockopt = tcp_setsockopt;
+ camel_tcp_stream_class->get_local_address = tcp_get_local_address;
+ camel_tcp_stream_class->get_remote_address = tcp_get_remote_address;
}
static void
@@ -156,26 +159,88 @@ camel_tcp_stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *dat
}
-static gpointer
-tcp_get_socket (CamelTcpStream *stream)
+static CamelTcpAddress *
+tcp_get_local_address (CamelTcpStream *stream)
{
- w(g_warning ("CamelTcpStream::get_socket called on default implementation"));
+ w(g_warning ("CamelTcpStream::get_local_address called on default implementation"));
return NULL;
}
+/**
+ * camel_tcp_stream_get_local_address:
+ * @stream: tcp stream object
+ *
+ * Get the local address of @stream.
+ *
+ * Return value: the stream's local address (which must be freed with
+ * camel_tcp_address_free()) if the stream is connected, or %NULL if not.
+ **/
+CamelTcpAddress *
+camel_tcp_stream_get_local_address (CamelTcpStream *stream)
+{
+ g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), NULL);
+
+ return CTS_CLASS (stream)->get_local_address (stream);
+}
+
+
+static CamelTcpAddress *
+tcp_get_remote_address (CamelTcpStream *stream)
+{
+ w(g_warning ("CamelTcpStream::get_remote_address called on default implementation"));
+ return NULL;
+}
/**
- * camel_tcp_stream_get_socket:
+ * camel_tcp_stream_get_remote_address:
* @stream: tcp stream object
*
- * Get the stream's socket.
+ * Get the remote address of @stream.
*
- * Return value: the stream's socket on success or NULL on failure.
+ * Return value: the stream's remote address (which must be freed with
+ * camel_tcp_address_free()) if the stream is connected, or %NULL if not.
**/
-gpointer
-camel_tcp_stream_get_socket (CamelTcpStream *stream)
+CamelTcpAddress *
+camel_tcp_stream_get_remote_address (CamelTcpStream *stream)
{
g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), NULL);
- return CTS_CLASS (stream)->get_socket (stream);
+ return CTS_CLASS (stream)->get_remote_address (stream);
+}
+
+
+/**
+ * camel_tcp_address_new:
+ * @family: the address family (currently must be CAMEL_TCP_ADDRESS_IPV4)
+ * @port: the port number (in network byte order)
+ * @length: the length of @address
+ * @address: the address data (family dependent, in network byte order)
+ *
+ * Return value: a new CamelTcpAddress.
+ **/
+CamelTcpAddress *
+camel_tcp_address_new (CamelTcpAddressFamily family, gushort port,
+ gushort length, gpointer address)
+{
+ CamelTcpAddress *addr;
+
+ addr = g_malloc (sizeof (CamelTcpAddress) + length - 1);
+ addr->family = family;
+ addr->port = port;
+ addr->length = length;
+ memcpy (&addr->address, address, length);
+
+ return addr;
+}
+
+/**
+ * camel_tcp_address_free:
+ * @address: the address
+ *
+ * Frees @address.
+ **/
+void
+camel_tcp_address_free (CamelTcpAddress *address)
+{
+ g_free (address);
}
diff --git a/camel/camel-tcp-stream.h b/camel/camel-tcp-stream.h
index 5134aea7c6..e6651e6ccd 100644
--- a/camel/camel-tcp-stream.h
+++ b/camel/camel-tcp-stream.h
@@ -88,6 +88,17 @@ typedef struct _CamelSockOptData {
} value;
} CamelSockOptData;
+typedef enum {
+ CAMEL_TCP_ADDRESS_IPV4
+} CamelTcpAddressFamily;
+
+typedef struct {
+ CamelTcpAddressFamily family;
+ gushort port, length;
+ guint8 address[1];
+} CamelTcpAddress;
+
+
struct _CamelTcpStream
{
CamelStream parent_object;
@@ -102,7 +113,8 @@ typedef struct {
int (*getsockopt) (CamelTcpStream *stream, CamelSockOptData *data);
int (*setsockopt) (CamelTcpStream *stream, const CamelSockOptData *data);
- gpointer (*get_socket) (CamelTcpStream *stream);
+ CamelTcpAddress * (*get_local_address) (CamelTcpStream *stream);
+ CamelTcpAddress * (*get_remote_address) (CamelTcpStream *stream);
} CamelTcpStreamClass;
/* Standard Camel function */
@@ -113,7 +125,13 @@ int camel_tcp_stream_connect (CamelTcpStream *stream, struct hostent
int camel_tcp_stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
int camel_tcp_stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-gpointer camel_tcp_stream_get_socket (CamelTcpStream *stream);
+CamelTcpAddress *camel_tcp_stream_get_local_address (CamelTcpStream *stream);
+CamelTcpAddress *camel_tcp_stream_get_remote_address (CamelTcpStream *stream);
+
+CamelTcpAddress *camel_tcp_address_new (CamelTcpAddressFamily family,
+ gushort port, gushort length,
+ gpointer address);
+void camel_tcp_address_free (CamelTcpAddress *address);
#ifdef __cplusplus
}
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index d07a4305aa..26cf4aa17f 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -51,7 +51,6 @@
#include "camel-tcp-stream-raw.h"
#ifdef HAVE_NSS
#include "camel-tcp-stream-ssl.h"
-#include <prnetdb.h>
#endif
#ifdef HAVE_OPENSSL
#include "camel-tcp-stream-openssl.h"
@@ -243,9 +242,7 @@ connect_to_server (CamelService *service, int try_starttls, CamelException *ex)
CamelStream *tcp_stream;
char *respbuf = NULL;
struct hostent *h;
- guint32 addrlen;
int port, ret;
- int sockfd;
if (!CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex))
return FALSE;
@@ -299,28 +296,7 @@ connect_to_server (CamelService *service, int try_starttls, CamelException *ex)
}
/* get the localaddr - needed later by smtp_helo */
- addrlen = sizeof (transport->localaddr);
-#ifdef HAVE_NSS
- if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL) {
- PRFileDesc *sockfd = camel_tcp_stream_get_socket (CAMEL_TCP_STREAM (tcp_stream));
- PRNetAddr addr;
- char hname[1024];
-
- PR_GetSockName (sockfd, &addr);
- memset (hname, 0, sizeof (hname));
- PR_NetAddrToString (&addr, hname, 1023);
-
- inet_aton (hname, (struct in_addr *)&transport->localaddr.sin_addr);
- } else {
- sockfd = GPOINTER_TO_INT (camel_tcp_stream_get_socket (CAMEL_TCP_STREAM (tcp_stream)));
-
- getsockname (sockfd, (struct sockaddr *)&transport->localaddr, &addrlen);
- }
-#else
- sockfd = GPOINTER_TO_INT (camel_tcp_stream_get_socket (CAMEL_TCP_STREAM (tcp_stream)));
-
- getsockname (sockfd, (struct sockaddr *)&transport->localaddr, &addrlen);
-#endif /* HAVE_NSS */
+ transport->localaddr = camel_tcp_stream_get_local_address (CAMEL_TCP_STREAM (tcp_stream));
transport->ostream = tcp_stream;
transport->istream = camel_stream_buffer_new (tcp_stream, CAMEL_STREAM_BUFFER_READ);
@@ -608,9 +584,11 @@ smtp_disconnect (CamelService *service, gboolean clean, CamelException *ex)
camel_object_unref (CAMEL_OBJECT (transport->ostream));
camel_object_unref (CAMEL_OBJECT (transport->istream));
-
transport->ostream = NULL;
transport->istream = NULL;
+
+ camel_tcp_address_free (transport->localaddr);
+ transport->localaddr = NULL;
return TRUE;
}
@@ -910,27 +888,31 @@ static gboolean
smtp_helo (CamelSmtpTransport *transport, CamelException *ex)
{
/* say hello to the server */
- char *cmdbuf, *respbuf = NULL;
+ char *name, *cmdbuf, *respbuf = NULL;
const char *token;
struct hostent *host;
camel_operation_start_transient (NULL, _("SMTP Greeting"));
/* get the local host name */
- host = gethostbyaddr ((char *)&transport->localaddr.sin_addr, sizeof (transport->localaddr.sin_addr), AF_INET);
-
- /* hiya server! how are you today? */
- if (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP) {
- if (host && host->h_name)
- cmdbuf = g_strdup_printf ("EHLO %s\r\n", host->h_name);
- else
- cmdbuf = g_strdup_printf ("EHLO [%s]\r\n", inet_ntoa (transport->localaddr.sin_addr));
- } else {
- if (host && host->h_name)
- cmdbuf = g_strdup_printf ("HELO %s\r\n", host->h_name);
- else
- cmdbuf = g_strdup_printf ("HELO [%s]\r\n", inet_ntoa (transport->localaddr.sin_addr));
+ host = gethostbyaddr ((char *)&transport->localaddr->address,
+ transport->localaddr->length, AF_INET);
+ if (host && host->h_name)
+ name = g_strdup (host->h_name);
+ else {
+ name = g_strdup_printf ("[%d.%d.%d.%d]",
+ transport->localaddr->address[0],
+ transport->localaddr->address[1],
+ transport->localaddr->address[2],
+ transport->localaddr->address[3]);
}
+
+ /* hiya server! how are you today? */
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP)
+ cmdbuf = g_strdup_printf ("EHLO %s\r\n", name);
+ else
+ cmdbuf = g_strdup_printf ("HELO %s\r\n", name);
+ g_free (name);
d(fprintf (stderr, "sending : %s", cmdbuf));
if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
diff --git a/camel/providers/smtp/camel-smtp-transport.h b/camel/providers/smtp/camel-smtp-transport.h
index 2f6ac261f4..907906c82b 100644
--- a/camel/providers/smtp/camel-smtp-transport.h
+++ b/camel/providers/smtp/camel-smtp-transport.h
@@ -33,13 +33,8 @@ extern "C" {
#endif /* __cplusplus }*/
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
#include "camel-transport.h"
+#include "camel-tcp-stream.h"
#define CAMEL_SMTP_TRANSPORT_TYPE (camel_smtp_transport_get_type ())
#define CAMEL_SMTP_TRANSPORT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransport))
@@ -65,7 +60,7 @@ typedef struct {
guint32 flags;
- struct sockaddr_in localaddr;
+ CamelTcpAddress *localaddr;
GHashTable *authtypes;