From a18691c17e9d49d75775d32a4d25dab9147b2ead Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Wed, 14 Jun 2000 05:10:53 +0000 Subject: IMAP will now allow you to login, and on some IMAP providers it will actually allow you to get mail - however there are some things that might need to be rewritten in Camel to allow all IMAP providers to work right now, it wants to open /INBOX which isn't always the same as INBOX Camel won't seem to allow me to just have it open "INBOX" if I specify '/' as the separator *sigh* svn path=/trunk/; revision=3557 --- ChangeLog | 4 + camel/ChangeLog | 12 ++- camel/providers/Makefile.am | 2 +- camel/providers/imap/camel-imap-folder.c | 21 ++-- camel/providers/imap/camel-imap-provider.c | 34 +++--- camel/providers/imap/camel-imap-store.c | 160 ++++++++++++++--------------- camel/providers/imap/camel-imap-store.h | 3 +- configure.in | 1 + 8 files changed, 119 insertions(+), 118 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4a24c257e..6268e946a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2000-06-13 Jeffrey Stedfast + + * configure.in: Added IMAP into the build + 2000-06-13 Ettore Perazzoli * notes/Makefile.am (SHELL_OBJS): Removed. diff --git a/camel/ChangeLog b/camel/ChangeLog index d844cfa2d5..b5b3fd4d31 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,7 +1,17 @@ +2000-06-13 Jeffrey Stedfast + + * providers/imap/camel-imap-store.c (camel_imap_store_open): + (camel_imap_store_close): Added. + (camel_imap_command_extended): Fixed a segfault and updated + to use camel_imap_status() + (camel_imap_command): Updated to use camel_imap_status() + (camel_imap_status): New convenience function for parsing + the return status of an IMAP command + 2000-06-12 Jeffrey Stedfast * providers/imap/camel-imap-folder.c (imap_get_message_by_uid): - Works like the POP fetch code, should work for temporarily until + Works like the POP fetch code, should work temporarily until we get around to coding it the way it "Should Be". * providers/pop3/camel-pop3-folder.c (get_message_by_uid): Now uses diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am index 964104adba..dec31c0cb9 100644 --- a/camel/providers/Makefile.am +++ b/camel/providers/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = mbox pop3 sendmail smtp vee +SUBDIRS = mbox pop3 sendmail smtp vee imap # these ones are disabled for the moment. # MH maildir nntp smtp diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index f09cae6039..2f6af670a2 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -46,10 +46,13 @@ #include "camel-mime-message.h" #include "camel-stream-filter.h" #include "camel-mime-filter-from.h" +#include "camel-mime-filter-crlf.h" #include "camel-exception.h" #define d(x) +#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (GTK_OBJECT (o)->klass)) + static CamelFolderClass *parent_class = NULL; static void imap_init (CamelFolder *folder, CamelStore *parent_store, @@ -169,10 +172,10 @@ camel_imap_folder_get_type (void) CamelFolder * camel_imap_folder_new (CamelStore *parent, CamelException *ex) { - /* TODO: code this - do we need this? */ CamelFolder *folder = CAMEL_FOLDER (gtk_object_new (camel_imap_folder_get_type (), NULL)); + + CF_CLASS (folder)->init (folder, parent, NULL, "INBOX", '/', ex); - CAMEL_FOLDER_CLASS (folder)->init (folder, parent, NULL, "inbox", '/', ex); return folder; } @@ -605,7 +608,7 @@ message_changed (CamelMimeMessage *m, int type, CamelImapFolder *mf) static CamelMimeMessage * imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex) { - CamelImapStream *imap_stream; + CamelStream *imap_stream; CamelStream *msgstream; CamelStreamFilter *f_stream; /* will be used later w/ crlf filter */ CamelMimeFilter *filter; /* crlf/dot filter */ @@ -617,7 +620,7 @@ imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException * /* TODO: fetch the correct part, get rid of the hard-coded stuff */ cmdbuf = g_strdup_printf ("UID FETCH %s BODY[TEXT]", uid); - imap_stream = camel_imap_stream_new (folder, cmdbuf); + imap_stream = camel_imap_stream_new (CAMEL_IMAP_FOLDER (folder), cmdbuf); g_free (cmdbuf); @@ -796,13 +799,3 @@ imap_search_by_expression (CamelFolder *folder, const char *expression, CamelExc - - - - - - - - - - diff --git a/camel/providers/imap/camel-imap-provider.c b/camel/providers/imap/camel-imap-provider.c index 92013a9643..0dbfd3f50c 100644 --- a/camel/providers/imap/camel-imap-provider.c +++ b/camel/providers/imap/camel-imap-provider.c @@ -1,28 +1,28 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-imap-provider.c: imap provider registration code */ -/* - * Authors : - * Jeffrey Stedfast +/* + * Authors: Jeffrey Stedfast * - * Copyright (C) 2000 HelixCode (www.helixcode.com). + * Copyright 2000 Helix Code, Inc. (www.helixcode.com) * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA */ + #include "config.h" #include "camel-imap-store.h" #include "camel-provider.h" @@ -49,3 +49,5 @@ camel_provider_module_init (CamelSession *session) camel_session_register_provider (session, &imap_provider); } + + diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index 0bf8dd52e8..96a830e210 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -2,25 +2,24 @@ /* camel-imap-store.c : class for an imap store */ /* - * Authors: Jeffrey Stedfast - * Ross Golder + * Authors: Jeffrey Stedfast * - * Copyright (C) 2000 Helix Code, Inc. + * Copyright 2000 Helix Code, Inc. (www.helixcode.com) * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA */ @@ -58,10 +57,10 @@ static gboolean imap_connect (CamelService *service, CamelException *ex); static gboolean imap_disconnect (CamelService *service, CamelException *ex); static GList *query_auth_types (CamelService *service, CamelException *ex); static void free_auth_types (CamelService *service, GList *authtypes); - static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex); static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); +static int camel_imap_status (char *cmdid, char *respbuf); static void camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) @@ -88,20 +87,17 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) camel_store_class->get_folder_name = get_folder_name; } - static void camel_imap_store_init (gpointer object, gpointer klass) { CamelService *service = CAMEL_SERVICE (object); CamelStore *store = CAMEL_STORE (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); store->folders = g_hash_table_new (g_str_hash, g_str_equal); } - GtkType camel_imap_store_get_type (void) { @@ -226,9 +222,8 @@ imap_connect (CamelService *service, CamelException *ex) service->url->user, h->h_name); service->url->passwd = camel_session_query_authenticator (camel_service_get_session (service), - prompt, TRUE, - service, "password", - ex); + CAMEL_AUTHENTICATOR_ASK, prompt, + TRUE, service, "password", ex); g_free (prompt); if (!service->url->passwd) return FALSE; @@ -286,6 +281,8 @@ imap_connect (CamelService *service, CamelException *ex) gtk_object_unref (GTK_OBJECT (store->ostream)); gtk_object_unref (GTK_OBJECT (store->istream)); return FALSE; + } else { + g_message ("IMAP Service sucessfully authenticated user %s", service->url->user); } service_class->connect (service, ex); @@ -340,7 +337,7 @@ imap_create (CamelFolder *folder, CamelException *ex) /* create the directory for the subfolder */ status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), NULL, &result, "CREATE %s", folder->full_name); - + if (status != CAMEL_IMAP_OK) { CamelService *service = CAMEL_SERVICE (folder->parent_store); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, @@ -360,27 +357,41 @@ imap_create (CamelFolder *folder, CamelException *ex) static CamelFolder * get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex) { - CamelImapFolder *new_imap_folder; - CamelFolder *new_folder; + CamelFolder *new_folder = camel_imap_folder_new (store, ex); - new_imap_folder = gtk_type_new (CAMEL_IMAP_FOLDER_TYPE); - new_folder = CAMEL_FOLDER (new_imap_folder); - CAMEL_FOLDER_CLASS (new_folder)->init (new_folder, store, NULL, - folder_name, '/', ex); - - if (imap_create (new_folder, ex)) + if (imap_create (new_folder, ex)) { return new_folder; - + } + return NULL; } static gchar * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) +get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) { return g_strdup (folder_name); } +static int +camel_imap_status (char *cmdid, char *respbuf) +{ + char *retcode; + + if (respbuf) { + retcode = strstr (respbuf, cmdid); + if (retcode) { + retcode += strlen (cmdid) + 1; + + if (!strncmp (retcode, "OK", 2)) + return CAMEL_IMAP_OK; + else if (!strncmp (retcode, "NO", 2)) + return CAMEL_IMAP_ERR; + } + } + + return CAMEL_IMAP_FAIL; +} + /** * camel_imap_command: Send a command to a IMAP server. * @store: the IMAP store @@ -405,7 +416,7 @@ gint camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char *fmt, ...) { gchar *cmdbuf, *respbuf; - gchar *cmdid, *code; + gchar *cmdid; va_list ap; gint status; @@ -440,7 +451,6 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char return CAMEL_IMAP_FAIL; } g_free(cmdbuf); - g_free(cmdid); /* Read the response */ respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (store->istream)); @@ -452,17 +462,8 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, char **ret, char fprintf(stderr, "received: %s\n", respbuf ? respbuf : "(null)"); - if (respbuf) { - code = strstr(respbuf, cmdid) + strlen(cmdid) + 1; - if (!strncmp(code, "OK", 2)) - status = CAMEL_IMAP_OK; - else if (!strncmp(code, "NO", 2)) - status = CAMEL_IMAP_ERR; - else - status = CAMEL_IMAP_FAIL; - } else { - status = CAMEL_IMAP_FAIL; - } + status = camel_imap_status (cmdid, respbuf); + g_free (cmdid); if (ret) { if (status != CAMEL_IMAP_FAIL) { @@ -507,9 +508,9 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char ** { CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream); GPtrArray *data; - gchar *cmdid, *cmdbuf, *respbuf, *code; + gchar *cmdid, *cmdbuf, *respbuf; va_list app; - gint i, status = CAMEL_IMAP_OK; + gint status = CAMEL_IMAP_OK; if (folder && store->current_folder != folder && strncmp(fmt, "SELECT", 6) && strncmp(fmt, "STATUS", 6) && strncmp(fmt, "CREATE", 5)) { @@ -543,12 +544,12 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char ** return CAMEL_IMAP_FAIL; } g_free(cmdbuf); - g_free(cmdid); data = g_ptr_array_new (); + while (1) { respbuf = camel_stream_buffer_read_line (stream); - if (!respbuf || !strncmp(respbuf, cmdid, strlen(cmdid)) ) { + if (!respbuf || !strncmp(respbuf, cmdid, strlen(cmdid)) ) { /* IMAP's last response starts with our command id */ break; } @@ -558,19 +559,8 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char ** g_ptr_array_add (data, respbuf); } - if (respbuf) { - code = strstr(respbuf, cmdid) + strlen(cmdid) + 1; - if (!strncmp(code, "OK", 2)) - status = CAMEL_IMAP_OK; - else if (!strncmp(code, "NO", 2)) - status = CAMEL_IMAP_ERR; - else - status = CAMEL_IMAP_FAIL; - - g_free(respbuf); - } else { - status = CAMEL_IMAP_FAIL; - } + status = camel_imap_status (cmdid, respbuf); + g_free (cmdid); if (status == CAMEL_IMAP_OK) { /* Append an empty string to the end of the array @@ -581,33 +571,35 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char ** g_ptr_array_add (data, NULL); *ret = g_strjoinv ("\n", (gchar **)data->pdata); } else { - if (status != CAMEL_IMAP_FAIL) + if (status != CAMEL_IMAP_FAIL && respbuf) *ret = g_strdup (strchr (respbuf, ' ' + 1)); else *ret = NULL; } - for (i = 0; i < data->len - 2; i++) - g_free (data->pdata[i]); g_ptr_array_free (data, TRUE); - + return status; } +void +camel_imap_store_open (CamelImapStore *store, CamelException *ex) +{ + CamelService *service = CAMEL_SERVICE (store); + if (!camel_service_is_connected (service)) + imap_connect (service, ex); +} - - - - - - - - - - - - - - - +void +camel_imap_store_close (CamelImapStore *store, gboolean expunge, CamelException *ex) +{ + /* + if (expunge) + camel_imap_command (store, NULL, "QUIT"); + else + camel_imap_command (store, NULL, "RSET"); + */ + + imap_disconnect (CAMEL_SERVICE (store), ex); +} diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h index 587415b153..c0687b9429 100644 --- a/camel/providers/imap/camel-imap-store.h +++ b/camel/providers/imap/camel-imap-store.h @@ -60,8 +60,7 @@ typedef struct { /* public methods */ void camel_imap_store_open (CamelImapStore *store, CamelException *ex); -void camel_imap_store_close (CamelImapStore *store, gboolean expunge, - CamelException *ex); +void camel_imap_store_close (CamelImapStore *store, gboolean expunge, CamelException *ex); /* support functions */ diff --git a/configure.in b/configure.in index 8b7dee9afb..66b31b65f2 100644 --- a/configure.in +++ b/configure.in @@ -441,6 +441,7 @@ camel/providers/pop3/Makefile camel/providers/sendmail/Makefile camel/providers/smtp/Makefile camel/providers/vee/Makefile +camel/providers/imap/Makefile composer/Makefile widgets/Makefile widgets/e-paned/Makefile -- cgit v1.2.3