From abd054f4244d020873c031bdc8de0cb7c57ca2c2 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 27 Mar 2000 21:37:49 +0000 Subject: keep separate input and output streams so the output doesn't end up being * providers/pop3/camel-pop3-store.c: keep separate input and output streams so the output doesn't end up being buffered. * providers/pop3/camel-pop3-folder.c (get_message_by_number): finish implementing this. * providers/Makefile.am (SUBDIRS): Add pop3. svn path=/trunk/; revision=2196 --- camel/ChangeLog | 10 ++++++ camel/camel-exception-list.def | 4 ++- camel/providers/Makefile.am | 5 +-- camel/providers/pop3/camel-pop3-folder.c | 22 +++++++++++-- camel/providers/pop3/camel-pop3-store.c | 56 ++++++++++++++++++++++++-------- camel/providers/pop3/camel-pop3-store.h | 2 +- 6 files changed, 79 insertions(+), 20 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 396fdece55..ca0c4aba92 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,13 @@ +2000-03-27 Dan Winship + + * providers/Makefile.am (SUBDIRS): Add pop3. + + * providers/pop3/camel-pop3-store.c: keep separate input and + output streams so the output doesn't end up being buffered. + + * providers/pop3/camel-pop3-folder.c (get_message_by_number): + finish implementing this. + 2000-03-27 Michael Meeks * camel-mime-part.c (my_set_disposition): fix so less broken. diff --git a/camel/camel-exception-list.def b/camel/camel-exception-list.def index 825196920c..fcb99e5a52 100644 --- a/camel/camel-exception-list.def +++ b/camel/camel-exception-list.def @@ -30,4 +30,6 @@ CAMEL_EXCEPTION_STORE_INVALID, /* CamelServiceException */ CAMEL_EXCEPTION_SERVICE_NULL = 300, CAMEL_EXCEPTION_SERVICE_INVALID, -CAMEL_EXCEPTION_SERVICE_URL_INVALID +CAMEL_EXCEPTION_SERVICE_URL_INVALID, +CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, +CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am index ea9b1f3136..fd6df57e10 100644 --- a/camel/providers/Makefile.am +++ b/camel/providers/Makefile.am @@ -1,5 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = mbox sendmail -# this ones are disabled for the moment. +SUBDIRS = mbox pop3 sendmail + +# these ones are disabled for the moment. # MH maildir diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index e87cd97f4d..ad856cc2be 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -26,6 +26,8 @@ #include "camel-pop3-folder.h" #include "camel-pop3-store.h" #include "camel-exception.h" +#include "camel-stream-mem.h" +#include "camel-mime-message.h" #include @@ -118,6 +120,8 @@ get_message_by_number (CamelFolder *folder, gint number, CamelException *ex) { int status; char *result, *body; + CamelStream *msgstream; + CamelMimeMessage *msg; status = camel_pop3_command (CAMEL_POP3_STORE (folder->parent_store), &result, "RETR %d", number); @@ -133,8 +137,22 @@ get_message_by_number (CamelFolder *folder, gint number, CamelException *ex) } g_free (result); - /* XXX finish this */ - return NULL; + body = camel_pop3_command_get_additional_data (CAMEL_POP3_STORE (folder->parent_store)); + if (!body) { + CamelService *service = CAMEL_SERVICE (folder->parent_store); + camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, + "Could not retrieve message from POP " + "server %s.", service->url->host); + return NULL; + } + + msgstream = camel_stream_mem_new_with_buffer (body, strlen (body), + CAMEL_STREAM_MEM_READ); + msg = camel_mime_message_new_with_session (camel_service_get_session (CAMEL_SERVICE (folder->parent_store))); + camel_data_wrapper_set_input_stream (CAMEL_DATA_WRAPPER (msg), + msgstream); + + return msg; } diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index 6935c70c9b..61ff4aaddb 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -39,15 +39,16 @@ #include "camel-pop3-folder.h" #include "camel-stream-buffer.h" #include "camel-stream-fs.h" +#include "camel-session.h" #include "camel-exception.h" #include "md5-utils.h" #include "url-util.h" - +static CamelServiceClass *service_class = NULL; static gboolean pop3_connect (CamelService *service, CamelException *ex); static GList *query_auth_types (CamelService *service); -void free_auth_types (CamelService *service, GList *authtypes); +static void free_auth_types (CamelService *service, GList *authtypes); static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, CamelException *ex); @@ -61,6 +62,8 @@ camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_pop3_store_class); + service_class = gtk_type_class (camel_service_get_type ()); + /* virtual method overload */ camel_service_class->connect = pop3_connect; camel_service_class->query_auth_types = query_auth_types; @@ -142,7 +145,7 @@ pop3_connect (CamelService *service, CamelException *ex) char *buf, *apoptime, *pass; CamelPop3Store *store = CAMEL_POP3_STORE (service); - if (!CAMEL_SERVICE_CLASS (service)->connect (service, ex)) + if (!service_class->connect (service, ex)) return FALSE; h = gethostbyname (service->url->host); @@ -161,8 +164,25 @@ pop3_connect (CamelService *service, CamelException *ex) return FALSE; } + pass = g_strdup (service->url->passwd); + if (!pass) { + char *prompt = g_strdup_printf ("Please enter the POP3 password for %s@%s", + service->url->user, h->h_name); + pass = camel_session_query_authenticator (camel_service_get_session (service), + prompt, TRUE, + service, "password", + ex); + g_free (prompt); + if (!pass) + return FALSE; + } + sin.sin_family = h->h_addrtype; - sin.sin_port = htons (atoi (service->url->port)); /* XXX */ + /* 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); memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr)); fd = socket (h->h_addrtype, SOCK_STREAM, 0); @@ -174,15 +194,20 @@ pop3_connect (CamelService *service, CamelException *ex) strerror(errno)); if (fd > -1) close (fd); + g_free (pass); return FALSE; } - store->stream = CAMEL_STREAM_BUFFER (camel_stream_buffer_new (camel_stream_fs_new_with_fd (fd), CAMEL_STREAM_BUFFER_READ)); + store->ostream = camel_stream_fs_new_with_fd (fd); + store->istream = camel_stream_buffer_new (store->ostream, + CAMEL_STREAM_BUFFER_READ); /* Read the greeting, note APOP timestamp, if any. */ - buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->stream)); - if (!buf) + buf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); + if (!buf) { + g_free (pass); return -1; + } apoptime = strchr (buf, '<'); if (apoptime) { int len = strcspn (apoptime, ">"); @@ -209,7 +234,6 @@ pop3_connect (CamelService *service, CamelException *ex) status = camel_pop3_command(store, NULL, "APOP %s %s", service->url->user, md5asc); } - g_free(buf); if (status != CAMEL_POP3_OK ) { status = camel_pop3_command(store, NULL, "USER %s", @@ -227,6 +251,7 @@ pop3_connect (CamelService *service, CamelException *ex) return FALSE; } + g_free (pass); return TRUE; } @@ -245,7 +270,6 @@ static CamelFolder *get_folder (CamelStore *store, const gchar *folder_name, int camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...) { - CamelStreamBuffer *stream = store->stream; char *cmdbuf, *respbuf; va_list ap; int status; @@ -255,12 +279,12 @@ camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...) va_end (ap); /* Send the command */ - camel_stream_write (CAMEL_STREAM (stream), cmdbuf, strlen (cmdbuf)); + camel_stream_write (store->ostream, cmdbuf, strlen (cmdbuf)); g_free (cmdbuf); - camel_stream_write (CAMEL_STREAM (stream), "\r\n", 2); + camel_stream_write (store->ostream, "\r\n", 2); /* Read the response */ - respbuf = camel_stream_buffer_read_line (stream); + respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); if (!strncmp (respbuf, "+OK", 3)) status = CAMEL_POP3_OK; else if (!strncmp (respbuf, "-ERR", 4)) @@ -284,7 +308,7 @@ camel_pop3_command (CamelPop3Store *store, char **ret, char *fmt, ...) char * camel_pop3_command_get_additional_data (CamelPop3Store *store) { - CamelStreamBuffer *stream = store->stream; + CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); GPtrArray *data; char *buf; int i, status = CAMEL_POP3_OK; @@ -305,12 +329,16 @@ camel_pop3_command_get_additional_data (CamelPop3Store *store) } if (status == CAMEL_POP3_OK) { + /* The empty string is so that we end up with a "\n" + * at the end of the string. + */ + g_ptr_array_add (data, ""); g_ptr_array_add (data, NULL); buf = g_strjoinv ("\n", (char **)data->pdata); } else buf = NULL; - for (i = 0; i < data->len; i++) + for (i = 0; i < data->len - 1; i++) g_free (data->pdata[i]); g_ptr_array_free (data, TRUE); diff --git a/camel/providers/pop3/camel-pop3-store.h b/camel/providers/pop3/camel-pop3-store.h index ecb37250da..23aac3a522 100644 --- a/camel/providers/pop3/camel-pop3-store.h +++ b/camel/providers/pop3/camel-pop3-store.h @@ -46,7 +46,7 @@ extern "C" { typedef struct { CamelStore parent_object; - CamelStreamBuffer *stream; + CamelStream *istream, *ostream; } CamelPop3Store; -- cgit v1.2.3