diff options
-rw-r--r-- | camel/ChangeLog | 27 | ||||
-rw-r--r-- | camel/camel-tcp-stream-openssl.c | 34 | ||||
-rw-r--r-- | camel/camel-tcp-stream-raw.c | 36 | ||||
-rw-r--r-- | camel/camel-tcp-stream-ssl.c | 34 | ||||
-rw-r--r-- | camel/camel-tcp-stream.c | 93 | ||||
-rw-r--r-- | camel/camel-tcp-stream.h | 22 | ||||
-rw-r--r-- | camel/providers/smtp/camel-smtp-transport.c | 62 | ||||
-rw-r--r-- | camel/providers/smtp/camel-smtp-transport.h | 9 |
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; |