From b1e66c4c60ca6d52c0a164a510e5199ca201bf98 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Tue, 5 Sep 2000 20:08:10 +0000 Subject: Cleanup of lots of exception handling ; bugfixes svn path=/trunk/; revision=5202 --- camel/ChangeLog | 69 +++++++ camel/camel-remote-store.c | 53 +++-- camel/camel-remote-store.h | 3 +- camel/camel.c | 3 +- camel/providers/imap/camel-imap-folder.c | 10 + camel/providers/imap/camel-imap-store.c | 14 +- camel/providers/imap/camel-imap-store.h | 3 - camel/providers/nntp/camel-nntp-store.c | 6 + camel/providers/pop3/camel-pop3-folder.c | 42 ++-- camel/providers/pop3/camel-pop3-store.c | 325 ++++++++++++------------------- camel/providers/pop3/camel-pop3-store.h | 9 +- 11 files changed, 275 insertions(+), 262 deletions(-) (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index 53a99e5516..b8ee78a393 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,19 @@ +2000-09-05 Peter Williams + + * providers/imap/camel-imap-store.c (imap_folder_exists): Don't free the + result on error; the exception will have the relevant info. + + * providers/imap/camel-imap-folder.c (camel_imap_folder_new): Check for + exceptions here. + + * providers/imap/camel-imap-store.c (imap_connect): Check the exception + on the refresh_folders call. + + * providers/imap/camel-imap-store.h: Clean up some now-unused fields. + + * camel.c (camel_init): Call unicode_init again, now that libunicode + will not initialize itself twice. + 2000-09-02 Lauris Kaplinski * camel-folder-search (search_header_contains): Use e_utf8_strstrcase @@ -7,6 +23,59 @@ * providers/imap/camel-imap-utils.c: Removed some unused functions. +2000-09-01 Peter Williams + + * providers/nntp/camel-nntp-store.c (camel_nntp_command): Initialize + the statically-allocated CamelException so that it doesn't contain + junk data that camel_exception_set() may try to free. + (camel_nntp_store_get_extensions): Same. + (camel_nntp_store_get_overview_fmt): Same. + + * providers/pop3/camel-pop3-store.c (camel_pop3_command): Typo + fix (if (*ret) -> if (ret)). + + * providers/pop3/camel-pop3-store.c (pop3_connect): Set the + port # back to what was specified ASAP, so that the hash of + the URL doesn't change (which causes a failure in + service_cache_remove that leads to a segfault). + + * providers/imap/camel-imap-store.c (imap_connect): Clear the + exception after a failed LOGIN so that it doesn't pass through + to the upper level and make mail think that the login failed. + + * providers/pop3/camel-pop3-store.c (pop3_connect): As above. + +2000-08-31 Peter Williams + + * providers/pop3/camel-pop3-store.c (camel_pop3_store_get_type): + Implement POP3 with the CamelRemoteStore now. + (connect_to_server): Hack this a bit to get KPOP to work. Obey + the new connection semantics of the remote store (implicitly). + (query_auth_types_connected): Clear exceptions after attempts + to connect; the code at the bottom will catch hard errors. + Use camel_service_connect. + (camel_pop3_command): Take a CamelException; now, when an error + occurs, ret is set to NULL and the exception passes back the + appropriate information. + (pop3_get_response): Same as above. + (pop3_try_authenticate): Give camel_pop3_command its exception + and handle it properly. + (pop3_connect): Call the parent classfuncs. Don't disconnect + on error (done for us). + + * providers/pop3/camel-pop3-folder.c: Obey the camel_pop3_command + semantics. + + * camel-remote-store.c (remote_query_auth_types_connected): Don't + warn; just return NULL. + (remote_query_auth_types_generic): Same. + (remote_send_string): Filter out passwords in debugging output. + + * providers/pop3/camel-pop3-store.c (camel_pop3_store_init): Also + set the ALLOW_AUTH flag. + + * providers/imap/camel-imap-store.c (camel_imap_store_init): Same. + 2000-08-31 Chris Toshok * providers/nntp/camel-nntp-store.c (camel_nntp_store_class_init): diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c index d11fd0bcbd..afbd3a71ca 100644 --- a/camel/camel-remote-store.c +++ b/camel/camel-remote-store.c @@ -149,8 +149,8 @@ camel_remote_store_get_type (void) static CamelServiceAuthType password_authtype = { "SSH Tunneling", - "This option will connect to the REMOTE server using a " - "plaintext password.", + "This option will connect to the server using a " + "SSH tunnel.", "", TRUE @@ -160,14 +160,12 @@ static CamelServiceAuthType password_authtype = { static GList * remote_query_auth_types_connected (CamelService *service, CamelException *ex) { - g_warning ("remote::query_auth_types_connected: not implemented. Defaulting."); - return CSRVC (service)->query_auth_types_generic (service, ex); + return NULL; } static GList * remote_query_auth_types_generic (CamelService *service, CamelException *ex) { - g_warning ("remote::query_auth_types_generic: not implemented. Defaulting."); return NULL; } @@ -192,14 +190,6 @@ remote_get_name (CamelService *service, gboolean brief) } } -static void -refresh_folder_info (gpointer key, gpointer value, gpointer data) -{ - CamelFolder *folder = CAMEL_FOLDER (value); - - camel_folder_refresh_info (folder, (CamelException *) data); -} - static gboolean timeout_cb (gpointer data) { @@ -277,9 +267,6 @@ remote_connect (CamelService *service, CamelException *ex) store); } - /* Let's make sure that any of our folders are brought up to speed */ - g_hash_table_foreach (CAMEL_STORE (store)->folders, refresh_folder_info, ex); - return TRUE; } @@ -333,8 +320,15 @@ remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_l /* create the command */ cmdbuf = g_strdup_vprintf (fmt, ap); - - d(fprintf (stderr, "sending : %s", cmdbuf)); + +#if d(!)0 + if (strncmp (cmdbuf, "PASS ", 5) == 0) + fprintf (stderr, "sending : PASS xxxx\n"); + else if (strstr (cmdbuf, "LOGIN \"")) + fprintf (stderr, "sending : ---- LOGIN \"xxxx\" \"xxxx\"\n"); + else + fprintf (stderr, "sending : %s", cmdbuf); +#endif if (camel_stream_printf (store->ostream, "%s", cmdbuf) == -1) { CamelException dex; @@ -493,3 +487,26 @@ camel_remote_store_recv_line (CamelRemoteStore *store, char **dest, return CRSC (store)->recv_line (store, dest, ex); } + +static void +refresh_folder_info (gpointer key, gpointer value, gpointer data) +{ + CamelFolder *folder = CAMEL_FOLDER (value); + + camel_folder_refresh_info (folder, (CamelException *) data); +} + +/** + * camel_remote_store_refresh_folders: Refresh the folders that I + * contain + * @store: a CamelRemoteStore + * @ex: a CamelException + * + * Refreshes the folders listed in the folders hashtable. + **/ + +void +camel_remote_store_refresh_folders (CamelRemoteStore *store, CamelException *ex) +{ + g_hash_table_foreach (CAMEL_STORE (store)->folders, refresh_folder_info, ex); +} diff --git a/camel/camel-remote-store.h b/camel/camel-remote-store.h index 627b012f3b..4530c22f14 100644 --- a/camel/camel-remote-store.h +++ b/camel/camel-remote-store.h @@ -69,7 +69,8 @@ gint camel_remote_store_send_stream (CamelRemoteStore *store, CamelStream *strea CamelException *ex); gint camel_remote_store_recv_line (CamelRemoteStore *store, char **dest, CamelException *ex); - +void camel_remote_store_refresh_folders (CamelRemoteStore *store, + CamelException *ex); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/camel.c b/camel/camel.c index dd46295e63..0121c1082f 100644 --- a/camel/camel.c +++ b/camel/camel.c @@ -40,8 +40,7 @@ camel_init(void) #endif /* G_THREADS_ENABLED */ #endif /* ENABLE_THREADS */ - /* Taken care of by e-util/e-unicode.c */ - /*unicode_init ();*/ + unicode_init (); return 0; } diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index c4c26db300..5b55f6bf9a 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -191,11 +191,21 @@ camel_imap_folder_new (CamelStore *parent, char *folder_name, CamelException *ex CF_CLASS (folder)->init (folder, parent, NULL, folder_name, dir_sep, FALSE, ex); + if (camel_exception_is_set (ex)) { + camel_object_unref (CAMEL_OBJECT (folder)); + return NULL; + } + if (!strcmp (folder_name, url->path + 1)) folder->can_hold_messages = FALSE; CF_CLASS (folder)->refresh_info (folder, ex); + if (camel_exception_is_set (ex)) { + camel_object_unref (CAMEL_OBJECT (folder)); + return NULL; + } + return folder; } diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 820c2453ce..5ffdd51d4b 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -95,7 +95,8 @@ camel_imap_store_init (gpointer object, gpointer klass) service->url_flags |= (CAMEL_SERVICE_URL_NEED_USER | CAMEL_SERVICE_URL_NEED_HOST | - CAMEL_SERVICE_URL_ALLOW_PATH); + CAMEL_SERVICE_URL_ALLOW_PATH | + CAMEL_SERVICE_URL_ALLOW_AUTH); imap_store->dir_sep = g_strdup ("/"); /*default*/ imap_store->current_folder = NULL; @@ -231,6 +232,7 @@ imap_connect (CamelService *service, CamelException *ex) errbuf = g_strdup_printf ("Unable to authenticate to IMAP server.\n" "%s\n\n", camel_exception_get_description (ex)); + camel_exception_clear (ex); } else { g_message ("IMAP Service sucessfully authenticated user %s", service->url->user); authenticated = TRUE; @@ -280,8 +282,10 @@ imap_connect (CamelService *service, CamelException *ex) } g_free (result); - - return TRUE; + + camel_remote_store_refresh_folders (CAMEL_REMOTE_STORE (store), ex); + + return ! camel_exception_is_set (ex); } static gboolean @@ -336,7 +340,6 @@ imap_folder_exists (CamelFolder *folder, CamelException *ex) &result, ex, "EXAMINE %s", folder_path); if (status != CAMEL_IMAP_OK) { - g_free (result); g_free (folder_path); return FALSE; } @@ -439,6 +442,9 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelEx new_folder = camel_imap_folder_new (store, folder_path, ex); + if (camel_exception_is_set (ex)) + return NULL; + /* this is the top-level dir, we already know it exists - it has to! */ if (!strcmp (folder_name, dir_sep)) return new_folder; diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h index 7aa911f394..2b946f065c 100644 --- a/camel/providers/imap/camel-imap-store.h +++ b/camel/providers/imap/camel-imap-store.h @@ -50,7 +50,6 @@ typedef struct { CamelRemoteStore parent_object; CamelFolder *current_folder; - CamelStream *istream, *ostream; guint32 command; @@ -58,8 +57,6 @@ typedef struct { gboolean has_status_capability; gchar *dir_sep; - - guint timeout_id; } CamelImapStore; diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index 521b802c78..75b8ef9409 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -66,6 +66,8 @@ camel_nntp_store_get_extensions (CamelNNTPStore *store) gboolean done = FALSE; CamelException ex; + camel_exception_init (&ex); + while (!done) { char *line; @@ -118,6 +120,8 @@ camel_nntp_store_get_overview_fmt (CamelNNTPStore *store) gboolean done = FALSE; CamelException ex; + camel_exception_init (&ex); + status = camel_nntp_command (store, NULL, "LIST OVERVIEW.FMT"); @@ -407,6 +411,8 @@ camel_nntp_command (CamelNNTPStore *store, char **ret, char *fmt, ...) char *real_fmt; CamelException ex; + camel_exception_init (&ex); + real_fmt = g_strdup_printf ("%s\r\n", fmt); va_start (ap, fmt); diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index 43c8d9a958..f7a86a741c 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -134,24 +134,22 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex) CamelPop3Folder *pop3_folder = (CamelPop3Folder *) folder; CamelPop3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store); - status = camel_pop3_command (pop3_store, &data, "STAT"); - if (status != CAMEL_POP3_OK) { - CamelService *service = CAMEL_SERVICE (pop3_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not get message count from POP " - "server %s: %s.", service->url->host, - data ? data : "Unknown error"); - g_free (data); + status = camel_pop3_command (pop3_store, &data, ex, "STAT"); + if (status != CAMEL_POP3_OK) return; - } count = atoi (data); g_free (data); if (pop3_store->supports_uidl != FALSE) { - status = camel_pop3_command (pop3_store, NULL, "UIDL"); - if (status != CAMEL_POP3_OK) + status = camel_pop3_command (pop3_store, NULL, ex, "UIDL"); + switch (status) { + case CAMEL_POP3_ERR: pop3_store->supports_uidl = FALSE; + break; + case CAMEL_POP3_FAIL: + return; + } } if (pop3_store->supports_uidl == FALSE) { @@ -198,16 +196,10 @@ pop3_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) for (i = 0; i < pop3_folder->uids->len; i++) { if (pop3_folder->flags[i] & CAMEL_MESSAGE_DELETED) { - status = camel_pop3_command (pop3_store, &resp, + status = camel_pop3_command (pop3_store, &resp, ex, "DELE %d", i + 1); - if (status != CAMEL_POP3_OK) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Unable to sync folder" - "%s%s", resp ? ": " : "", - resp ? resp : ""); - g_free (resp); + if (status != CAMEL_POP3_OK) return; - } } } @@ -276,17 +268,9 @@ pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex) } status = camel_pop3_command (CAMEL_POP3_STORE (folder->parent_store), - &result, "RETR %d", num); - if (status != CAMEL_POP3_OK) { - CamelService *service = CAMEL_SERVICE (folder->parent_store); - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not retrieve message from POP " - "server %s: %s.", service->url->host, - status == CAMEL_POP3_ERR ? result : - "Unknown error"); - g_free (result); + &result, ex, "RETR %d", num); + if (status != CAMEL_POP3_OK) return NULL; - } g_free (result); body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store), ex); diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index 6ee7361959..f27c373bab 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -37,6 +37,21 @@ #include #include +#ifdef HAVE_KRB4 +/* Specified nowhere */ +#define KPOP_PORT 1109 + +#include + +#ifdef NEED_KRB_SENDAUTH_PROTO +extern int krb_sendauth(long options, int fd, KTEXT ticket, char *service, + char *inst, char *realm, unsigned KRB4_32 checksum, + MSG_DAT *msg_data, CREDENTIALS *cred, + Key_schedule schedule, struct sockaddr_in *laddr, + struct sockaddr_in *faddr, char *version); +#endif +#endif + #include "camel-pop3-store.h" #include "camel-pop3-folder.h" #include "camel-stream-buffer.h" @@ -49,14 +64,7 @@ /* Specified in RFC 1939 */ #define POP3_PORT 110 -#ifdef HAVE_KRB4 -/* Specified nowhere */ -#define KPOP_PORT 1109 - -#include -#endif - -static CamelServiceClass *service_class = NULL; +static CamelRemoteStoreClass *parent_class = NULL; static void finalize (CamelObject *object); @@ -64,8 +72,6 @@ static gboolean pop3_connect (CamelService *service, CamelException *ex); static gboolean pop3_disconnect (CamelService *service, CamelException *ex); static GList *query_auth_types_connected (CamelService *service, CamelException *ex); static GList *query_auth_types_generic (CamelService *service, CamelException *ex); -static void free_auth_types (CamelService *service, GList *authtypes); -static char *get_name (CamelService *service, gboolean brief); static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex); @@ -73,7 +79,7 @@ static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static int pop3_get_response (CamelPop3Store *store, char **ret); +static int pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex); static void @@ -83,16 +89,18 @@ camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) CAMEL_SERVICE_CLASS (camel_pop3_store_class); CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_pop3_store_class); - - service_class = CAMEL_SERVICE_CLASS(camel_type_get_global_classfuncs (camel_service_get_type ())); + /*CamelRemoteStoreClass *camel_remote_store_class = + * CAMEL_STORE_CLASS (camel_pop3_store_class); + */ + + parent_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs + (camel_remote_store_get_type ())); /* virtual method overload */ - camel_service_class->connect = pop3_connect; - camel_service_class->disconnect = pop3_disconnect; camel_service_class->query_auth_types_connected = query_auth_types_connected; camel_service_class->query_auth_types_generic = query_auth_types_generic; - camel_service_class->free_auth_types = free_auth_types; - camel_service_class->get_name = get_name; + camel_service_class->connect = pop3_connect; + camel_service_class->disconnect = pop3_disconnect; camel_store_class->get_folder = get_folder; camel_store_class->get_folder_name = get_folder_name; @@ -106,7 +114,8 @@ camel_pop3_store_init (gpointer object, gpointer klass) { CamelService *service = CAMEL_SERVICE (object); - service->url_flags = (CAMEL_SERVICE_URL_NEED_USER | CAMEL_SERVICE_URL_NEED_HOST); + service->url_flags |= (CAMEL_SERVICE_URL_NEED_USER | CAMEL_SERVICE_URL_NEED_HOST | + CAMEL_SERVICE_URL_ALLOW_AUTH); } CamelType @@ -115,7 +124,7 @@ camel_pop3_store_get_type (void) static CamelType camel_pop3_store_type = CAMEL_INVALID_TYPE; if (!camel_pop3_store_type) { - camel_pop3_store_type = camel_type_register (CAMEL_STORE_TYPE, "CamelPop3Store", + camel_pop3_store_type = camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelPop3Store", sizeof (CamelPop3Store), sizeof (CamelPop3StoreClass), (CamelObjectClassInitFunc) camel_pop3_store_class_init, @@ -131,12 +140,6 @@ static void finalize (CamelObject *object) { CamelPop3Store *pop3_store = CAMEL_POP3_STORE (object); - /*CamelException ex;*/ - - /*camel_exception_init (&ex); - *pop3_disconnect (CAMEL_SERVICE (object), &ex); - *camel_exception_clear (&ex); - */ if (pop3_store->apop_timestamp) g_free (pop3_store->apop_timestamp); @@ -176,41 +179,15 @@ static CamelServiceAuthType kpop_authtype = { #endif static gboolean -connect_to_server (CamelService *service, gboolean real, CamelException *ex) +connect_to_server (CamelService *service, /*gboolean real, */CamelException *ex) { CamelPop3Store *store = CAMEL_POP3_STORE (service); - struct hostent *h; - struct sockaddr_in sin; - int fd, status; char *buf, *apoptime, *apopend; + gint status; #ifdef HAVE_KRB4 gboolean kpop = (service->url->port == KPOP_PORT); #endif - h = camel_service_gethost (service, ex); - if (!h) - return FALSE; - - sin.sin_family = h->h_addrtype; - if (service->url->port) - sin.sin_port = htons (service->url->port); - else - sin.sin_port = htons (POP3_PORT); - memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); - - fd = socket (h->h_addrtype, SOCK_STREAM, 0); - if (fd == -1 || - connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { - if (real) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "Could not connect to %s: %s", - h->h_name, g_strerror(errno)); - } - if (fd > -1) - close (fd); - return FALSE; - } - #ifdef HAVE_KRB4 if (kpop) { KTEXT_ST ticket_st; @@ -218,25 +195,30 @@ connect_to_server (CamelService *service, gboolean real, CamelException *ex) CREDENTIALS cred; Key_schedule schedule; char *hostname; + struct hostent *h; + int fd; /* Need to copy hostname, because krb_realmofhost will * call gethostbyname as well, and gethostbyname uses * static storage. */ + h = camel_service_gethost (service, ex); hostname = g_strdup (h->h_name); + + fd = CAMEL_STREAM_FS (CAMEL_REMOTE_STORE (service)->ostream)->fd; + status = krb_sendauth (0, fd, &ticket_st, "pop", hostname, krb_realmofhost (hostname), 0, &msg_data, &cred, schedule, NULL, NULL, "KPOPV0.1"); g_free (hostname); if (status != KSUCCESS) { - if (real) { + /*if (real) {*/ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, "Could not authenticate " "to KPOP server: %s", krb_err_txt[status]); - } - close (fd); + /*}*/ return FALSE; } @@ -245,22 +227,10 @@ connect_to_server (CamelService *service, gboolean real, CamelException *ex) } #endif /* HAVE_KRB4 */ - store->ostream = camel_stream_fs_new_with_fd (fd); - store->istream = camel_stream_buffer_new (store->ostream, - CAMEL_STREAM_BUFFER_READ); - /* Read the greeting, check status */ - status = pop3_get_response (store, &buf); - if (status != CAMEL_POP3_OK) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - "%s: %s", status == CAMEL_POP3_ERR ? - "Error connecting to POP server" : - "Error reading greeting from POP server", - buf); - g_free (buf); - pop3_disconnect (service, ex); + status = pop3_get_response (store, &buf, ex); + if (status != CAMEL_POP3_OK) return FALSE; - } apoptime = strchr (buf, '<'); apopend = apoptime ? strchr (apoptime, '>') : NULL; @@ -277,20 +247,14 @@ connect_to_server (CamelService *service, gboolean real, CamelException *ex) store->supports_uidl = -1; store->expires = -1; - /* good enough for us */ - service->connected = TRUE; - - status = camel_pop3_command (store, NULL, "CAPA"); + status = camel_pop3_command (store, NULL, ex, "CAPA"); if (status == CAMEL_POP3_OK) { char *p; int len; buf = camel_pop3_command_get_additional_data (store, ex); - if (camel_exception_is_set (ex)) { - pop3_disconnect (service, ex); - service->connected = FALSE; + if (camel_exception_is_set (ex)) return FALSE; - } p = buf; while (*p) { @@ -332,24 +296,32 @@ query_auth_types_connected (CamelService *service, CamelException *ex) int saved_port; #endif - if (service->url && !service->url->empty) { - passwd = connect_to_server (service, FALSE, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - return NULL; - apop = store->apop_timestamp != NULL; - if (passwd) - pop3_disconnect (service, ex); + ret = CAMEL_SERVICE_CLASS (parent_class)->query_auth_types_connected (service, ex); + + passwd = camel_service_connect (service, ex); + /*ignore the exception here; the server may just not support passwd */ + /*if (camel_exception_is_set (ex) != CAMEL_EXCEPTION_NONE)*/ + /*return NULL;*/ + + /* should we check apop too? */ + apop = store->apop_timestamp != NULL; + if (passwd) + camel_service_disconnect (service, ex); + camel_exception_clear (ex); + #ifdef HAVE_KRB4 - saved_port = service->url->port; - service->url->port = KPOP_PORT; - kpop = connect_to_server (service, FALSE, ex); - service->url->port = saved_port; - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - return NULL; - if (kpop) - pop3_disconnect (service, ex); + saved_port = service->url->port; + service->url->port = KPOP_PORT; + kpop = camel_service_connect (service, ex); + service->url->port = saved_port; + /*ignore the exception here; the server may just not support kpop */ + /*if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE)*/ + /*return NULL;*/ + + if (kpop) + camel_service_disconnect (service, ex); + camel_exception_clear (ex); #endif - } if (passwd) ret = g_list_append (ret, &password_authtype); @@ -383,25 +355,6 @@ query_auth_types_generic (CamelService *service, CamelException *ex) return ret; } -static void -free_auth_types (CamelService *service, GList *authtypes) -{ - g_list_free (authtypes); -} - -static char * -get_name (CamelService *service, gboolean brief) -{ - if (brief) - return g_strdup_printf ("POP server %s", service->url->host); - else { - return g_strdup_printf ("POP service for %s on %s", - service->url->user, - service->url->host); - } -} - - /** * camel_pop3_store_expunge: * @store: the store @@ -414,8 +367,8 @@ get_name (CamelService *service, gboolean brief) void camel_pop3_store_expunge (CamelPop3Store *store, CamelException *ex) { - camel_pop3_command (store, NULL, "QUIT"); - pop3_disconnect (CAMEL_SERVICE (store), ex); + /*camel_pop3_command (store, NULL, ex, "QUIT");*/ + /*camel_service_disconnect (CAMEL_SERVICE (store), ex);*/ } @@ -449,20 +402,23 @@ pop3_try_authenticate (CamelService *service, gboolean kpop, } if (!service->url->authmech || kpop) { - status = camel_pop3_command (store, &msg, "USER %s", + status = camel_pop3_command (store, &msg, ex, "USER %s", service->url->user); - if (status != CAMEL_POP3_OK) { + switch (status) { + case CAMEL_POP3_ERR: camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, "Unable to connect to POP " "server.\nError sending " "username: %s", msg ? msg : "(Unknown)"); g_free (msg); + /*fallll*/ + case CAMEL_POP3_FAIL: return FALSE; } g_free (msg); - status = camel_pop3_command (store, &msg, "PASS %s", + status = camel_pop3_command (store, &msg, ex, "PASS %s", service->url->passwd); } else if (!strcmp (service->url->authmech, "+APOP") && store->apop_timestamp) { @@ -477,7 +433,7 @@ pop3_try_authenticate (CamelService *service, gboolean kpop, for (s = md5sum, d = md5asc; d < md5asc + 32; s++, d += 2) sprintf (d, "%.2x", *s); - status = camel_pop3_command (store, &msg, "APOP %s %s", + status = camel_pop3_command (store, &msg, ex, "APOP %s %s", service->url->user, md5asc); } else { camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, @@ -487,12 +443,12 @@ pop3_try_authenticate (CamelService *service, gboolean kpop, return FALSE; } - if (status != CAMEL_POP3_OK) { + if (status == CAMEL_POP3_ERR) { camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, "Unable to connect to POP server.\n" "Error sending password: %s", msg ? msg : "(Unknown)"); - } + } /*if status == camel_pop3_fail, ex will be set*/ g_free (msg); return camel_exception_is_set (ex); @@ -503,17 +459,42 @@ pop3_connect (CamelService *service, CamelException *ex) { char *errbuf = NULL; gboolean tryagain, kpop = FALSE; + gboolean res; #ifdef HAVE_KRB4 + gboolean set_port = FALSE; + kpop = (service->url->authmech && !strcmp (service->url->authmech, "+KPOP")); - if (kpop && service->url->port == 0) + if (kpop && service->url->port == 0) { + set_port = TRUE; service->url->port = KPOP_PORT; + } +#endif + + res = CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex); + +#ifdef HAVE_KRB4 + /* This is veeery nasty. When we set the port, we're changing the + * hash value of our URL. service_cache_remove() gets called when + * we're done checking the mail, but the hash table lookup fails + * because the url port has changed. Then, a finalized instance of + * the CamelService is stuck in the hash table, and the next time + * we try to look up the service, with a URL of port 0, we look + * up the freed service and a segfault results. + */ + + if (kpop && set_port) + service->url->port = 0; #endif + if (res == FALSE) + return FALSE; + d(printf ("POP3: Connecting to %s\n", service->url->host)); - if (!connect_to_server (service, TRUE, ex)) + /*FIXME integrate these functions */ + if (!connect_to_server (service, ex)) return FALSE; camel_exception_clear (ex); @@ -522,6 +503,7 @@ pop3_connect (CamelService *service, CamelException *ex) errbuf = g_strdup_printf ( "%s\n\n", camel_exception_get_description (ex)); + camel_exception_clear (ex); /* Uncache the password before prompting again. */ camel_session_query_authenticator ( @@ -536,13 +518,10 @@ pop3_connect (CamelService *service, CamelException *ex) g_free (errbuf); } while (tryagain); - if (camel_exception_is_set (ex)) { - pop3_disconnect (service, NULL); - service->connected = FALSE; + if (camel_exception_is_set (ex)) return FALSE; - } - return service_class->connect (service, ex); + return TRUE; } static gboolean @@ -550,25 +529,12 @@ pop3_disconnect (CamelService *service, CamelException *ex) { CamelPop3Store *store = CAMEL_POP3_STORE (service); - if (!service_class->disconnect (service, ex)) + camel_pop3_command (store, NULL, ex, "QUIT"); + + if (!CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, ex)) return FALSE; d(printf ("POP3: Disconnecting from %s\n", service->url->host)); - - if (store->ostream) { - camel_object_unref (CAMEL_OBJECT (store->ostream)); - store->ostream = NULL; - } - if (store->istream) { - camel_object_unref (CAMEL_OBJECT (store->istream)); - store->istream = NULL; - } - - if (store->apop_timestamp) { - g_free (store->apop_timestamp); - store->apop_timestamp = NULL; - } - return TRUE; } @@ -576,14 +542,6 @@ static CamelFolder * get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex) { - /* CamelService *service = CAMEL_SERVICE (store); - * - * if (!camel_service_is_connected (service)) { - * if (!camel_service_connect (service, ex)) - * return NULL; - *} - */ - return camel_pop3_folder_new (store, ex); } @@ -628,45 +586,16 @@ get_root_folder_name (CamelStore *store, CamelException *ex) * result of the command.) **/ int -camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...) +camel_pop3_command (CamelPop3Store *store, char **ret, CamelException *ex, char *fmt, ...) { char *cmdbuf; va_list ap; - /* Check for connectedness. Failed (or cancelled) operations will - * close the connection. */ - if (CAMEL_SERVICE (store)->connected == FALSE) { - CamelException ex; - - d(g_message ("pop3: disconnected, reconnecting.")); - camel_exception_init (&ex); - CAMEL_SERVICE_CLASS (CAMEL_OBJECT_GET_CLASS (store))->connect (store, &ex); - if (camel_exception_is_set (&ex)) { - camel_exception_clear (&ex); - return CAMEL_POP3_FAIL; - } - camel_exception_clear (&ex); - } - - if (!store->ostream) { - /*CamelException ex; - * - *camel_exception_init (&ex); - *if (!camel_service_connect (CAMEL_SERVICE (store), &ex)) { - * if (ret) - * *ret = g_strdup (camel_exception_get_description (&ex)); - * camel_exception_clear (&ex); - */ - - return CAMEL_POP3_FAIL; - /*}*/ - } - va_start (ap, fmt); cmdbuf = g_strdup_vprintf (fmt, ap); va_end (ap); -#if d(!)0 +#if 0 /*remote-store prints output now*/ if (!strncmp (cmdbuf, "PASS", 4)) printf ("POP3: >>> PASS xxx\n"); else @@ -674,33 +603,29 @@ camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...) #endif /* Send the command */ - if (camel_stream_printf (store->ostream, "%s\r\n", cmdbuf) == -1) { + if (camel_remote_store_send_string (CAMEL_REMOTE_STORE (store), ex, "%s\r\n", cmdbuf) < 0) { g_free (cmdbuf); - if (*ret) - *ret = g_strdup (g_strerror (errno)); - d(printf ("POP3: !!! %s\n", g_strerror (errno))); + if (ret) + *ret = NULL; return CAMEL_POP3_FAIL; } g_free (cmdbuf); - return pop3_get_response (store, ret); + return pop3_get_response (store, ret, ex); } static int -pop3_get_response (CamelPop3Store *store, char **ret) +pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex) { char *respbuf; int status; - respbuf = camel_stream_buffer_read_line ( - CAMEL_STREAM_BUFFER (store->istream)); - if (respbuf == NULL) { + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) { if (ret) - *ret = g_strdup (g_strerror (errno)); - d(printf ("POP3: !!! %s\n", g_strerror (errno))); + *ret = NULL; + d(printf ("POP3: !!! %s\n", camel_exception_get_description (ex))); return CAMEL_POP3_FAIL; } - d(printf ("POP3: <<< %s\n", respbuf)); if (!strncmp (respbuf, "+OK", 3)) status = CAMEL_POP3_OK; @@ -739,15 +664,13 @@ pop3_get_response (CamelPop3Store *store, char **ret) char * camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *ex) { - CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); GPtrArray *data; char *buf, *p; int i, len = 0, status = CAMEL_POP3_OK; data = g_ptr_array_new (); while (1) { - buf = camel_stream_buffer_read_line (stream); - if (!buf) { + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &buf, ex) < 0) { status = CAMEL_POP3_FAIL; break; } @@ -758,7 +681,9 @@ camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *e g_ptr_array_add (data, buf); len += strlen (buf) + 1; } - g_free (buf); + + if (buf) + g_free (buf); if (status == CAMEL_POP3_OK) { buf = g_malloc0 (len + 1); @@ -769,7 +694,7 @@ camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *e datap = (char *) data->pdata[i]; ptr = (*datap == '.') ? datap + 1 : datap; len = strlen (ptr); -#if d(!)0 +#if 0 /*remote store prints stuff now */ if (i == data->len - 1) printf ("POP3: <<<<<< %s\n", ptr); else if (i == 0) diff --git a/camel/providers/pop3/camel-pop3-store.h b/camel/providers/pop3/camel-pop3-store.h index f5e447d9ea..cfa28f313f 100644 --- a/camel/providers/pop3/camel-pop3-store.h +++ b/camel/providers/pop3/camel-pop3-store.h @@ -34,7 +34,7 @@ extern "C" { #endif /* __cplusplus }*/ #include "camel-types.h" -#include "camel-store.h" +#include "camel-remote-store.h" #define CAMEL_POP3_STORE_TYPE (camel_pop3_store_get_type ()) #define CAMEL_POP3_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_POP3_STORE_TYPE, CamelPop3Store)) @@ -43,9 +43,8 @@ extern "C" { typedef struct { - CamelStore parent_object; + CamelRemoteStore parent_object; - CamelStream *istream, *ostream; char *apop_timestamp, *implementation; gboolean supports_top, supports_uidl, expires; int login_delay; @@ -55,7 +54,7 @@ typedef struct { typedef struct { - CamelStoreClass parent_class; + CamelRemoteStoreClass parent_class; } CamelPop3StoreClass; @@ -65,7 +64,7 @@ void camel_pop3_store_expunge (CamelPop3Store *store, CamelException *ex); /* support functions */ enum { CAMEL_POP3_OK, CAMEL_POP3_ERR, CAMEL_POP3_FAIL }; -int camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...); +int camel_pop3_command (CamelPop3Store *store, char **ret, CamelException *ex, char *fmt, ...); char *camel_pop3_command_get_additional_data (CamelPop3Store *store, CamelException *ex); -- cgit v1.2.3