diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 5 | ||||
-rw-r--r-- | camel/camel-service.c | 88 | ||||
-rw-r--r-- | camel/camel-service.h | 10 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 31 |
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); |