aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog5
-rw-r--r--camel/camel-service.c88
-rw-r--r--camel/camel-service.h10
-rw-r--r--camel/providers/pop3/camel-pop3-store.c31
4 files changed, 113 insertions, 21 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index b94ab8d079..c8cebe07d1 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,10 @@
2000-03-28 Dan Winship <danw@helixcode.com>
+ * camel-service.c (camel_service_gethost,
+ camel_service_getport): convenience functions to canonicalize
+ the host and port values of a service's URL.
+ * providers/pop3/camel-pop3-store.c: use them
+
* providers/mbox/camel-mbox-folder.c
(_check_get_or_maybe_generate_summary_file): Make this work when
the inbox file doesn't yet exist.
diff --git a/camel/camel-service.c b/camel/camel-service.c
index 394a163ae0..01b72e1a70 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -28,6 +28,9 @@
#include "camel-log.h"
#include "camel-exception.h"
+#include <ctype.h>
+#include <stdlib.h>
+
static GtkObjectClass *parent_class=NULL;
/* Returns the class for a CamelService */
@@ -418,3 +421,88 @@ camel_service_free_auth_types (CamelService *service, GList *authtypes)
{
CSERV_CLASS (service)->free_auth_types (service, authtypes);
}
+
+
+
+/* URL utility routines */
+
+/**
+ * camel_service_gethost: get a hostent for a CamelService's host
+ * @service: a CamelService
+ * @ex: a CamelException
+ *
+ * This is a convenience function to do a gethostbyname on the host
+ * for the service's URL.
+ *
+ * Return value: a (statically-allocated) hostent.
+ **/
+struct hostent *
+camel_service_gethost (CamelService *service, CamelException *ex)
+{
+ struct hostent *h;
+ char *hostname;
+
+ if (service->url->host)
+ hostname = service->url->host;
+ else
+ hostname = "localhost";
+ h = gethostbyname (hostname);
+ if (!h) {
+ extern int h_errno;
+
+ if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
+ "No such host %s.", hostname);
+ } else {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ "Temporarily unable to look up "
+ "hostname %s.", hostname);
+ }
+ return NULL;
+ }
+
+ return h;
+}
+
+/**
+ * camel_service_getport: get the port number for a service's URL
+ * @service: a CamelService
+ * @default_name: the default service name if none is provided by the URL
+ * @default_number: the default port number if the @default_name lookup fails
+ * @proto: the protocol (eg, "tcp") to be used
+ * @ex: a CamelExcption
+ *
+ * This is a convenience function to get the port number for a service
+ * based on the service's URL (which may contain either a numeric
+ * or symbolic port name) and the provided defaults.
+ *
+ * Return value: a port number, or -1 if the user specified a port name
+ * that could not be resolved.
+ **/
+int
+camel_service_getport (CamelService *service, char *default_port,
+ int default_number, char *proto, CamelException *ex)
+{
+ struct servent *s;
+ char *port;
+
+ if (service->url->port)
+ port = service->url->port;
+ else
+ port = default_port;
+
+ if (isdigit (*port))
+ return htons (atoi (port));
+
+ s = getservbyname (port, proto);
+ if (s)
+ return s->s_port;
+
+
+ if (port == service->url->port) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
+ "Unknown port `%s'", port);
+ return -1;
+ } else
+ return default_number;
+}
diff --git a/camel/camel-service.h b/camel/camel-service.h
index 521db58104..2da9c57f69 100644
--- a/camel/camel-service.h
+++ b/camel/camel-service.h
@@ -35,6 +35,7 @@ extern "C" {
#endif /* __cplusplus }*/
#include <gtk/gtk.h>
+#include <netdb.h>
#include "camel-types.h"
#include "url-util.h"
@@ -114,6 +115,15 @@ GList * camel_service_query_auth_types (CamelService *service);
void camel_service_free_auth_types (CamelService *service,
GList *authtypes);
+/* convenience functions */
+struct hostent * camel_service_gethost (CamelService *service,
+ CamelException *ex);
+int camel_service_getport (CamelService *service,
+ char *default_name,
+ int default_number,
+ char *proto,
+ CamelException *ex);
+
/* Standard Gtk function */
GtkType camel_service_get_type (void);
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 8b9ff03fac..543a6ce532 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -29,7 +29,6 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
-#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -44,6 +43,9 @@
#include "md5-utils.h"
#include "url-util.h"
+/* Specified in RFC 1939 */
+#define POP3_PORT 110
+
static CamelServiceClass *service_class = NULL;
static void finalize (GtkObject *object);
@@ -203,28 +205,19 @@ pop3_connect (CamelService *service, CamelException *ex)
{
struct hostent *h;
struct sockaddr_in sin;
- int fd, status, apoplen;
+ int port, fd, status, apoplen;
char *buf, *apoptime, *pass;
CamelPop3Store *store = CAMEL_POP3_STORE (service);
if (!service_class->connect (service, ex))
return FALSE;
- h = gethostbyname (service->url->host);
- if (!h) {
- extern int h_errno;
- if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID,
- "No such host %s.",
- service->url->host);
- } else {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- "Temporarily unable to look up "
- "hostname %s.",
- service->url->host);
- }
+ h = camel_service_gethost (service, ex);
+ if (!h)
+ return FALSE;
+ port = camel_service_getport (service, "pop3", POP3_PORT, "tcp", ex);
+ if (port == -1)
return FALSE;
- }
pass = g_strdup (service->url->passwd);
if (!pass) {
@@ -240,11 +233,7 @@ pop3_connect (CamelService *service, CamelException *ex)
}
sin.sin_family = h->h_addrtype;
- /* XXX this is all bad */
- if (service->url->port && *service->url->port)
- sin.sin_port = htons (atoi (service->url->port));
- else
- sin.sin_port = htons (110);
+ sin.sin_port = port;
memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
fd = socket (h->h_addrtype, SOCK_STREAM, 0);