aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/groupwise/camel-gw-listener.c70
-rw-r--r--camel/providers/imap/camel-imap-command.c14
-rw-r--r--camel/providers/imap/camel-imap-folder.c123
-rw-r--r--camel/providers/imap/camel-imap-store.c232
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c228
-rw-r--r--camel/providers/imap4/camel-imap4-store.c271
-rw-r--r--camel/providers/imapp/camel-imapp-store.c12
-rw-r--r--camel/providers/local/camel-local-folder.c2
-rw-r--r--camel/providers/local/camel-maildir-folder.c5
-rw-r--r--camel/providers/local/camel-mbox-folder.c81
-rw-r--r--camel/providers/local/camel-mbox-store.c3
-rw-r--r--camel/providers/local/camel-mh-folder.c5
-rw-r--r--camel/providers/local/camel-spool-folder.c4
-rw-r--r--camel/providers/local/camel-spool-store.c1
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c3
-rw-r--r--camel/providers/nntp/camel-nntp-private.h2
-rw-r--r--camel/providers/nntp/camel-nntp-store.c155
-rw-r--r--camel/providers/nntp/camel-nntp-stream.c2
-rw-r--r--camel/providers/nntp/camel-nntp-summary.c37
-rw-r--r--camel/providers/pop3/camel-pop3-store.c199
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c198
-rw-r--r--camel/providers/smtp/camel-smtp-transport.h8
22 files changed, 796 insertions, 859 deletions
diff --git a/camel/providers/groupwise/camel-gw-listener.c b/camel/providers/groupwise/camel-gw-listener.c
index 1f6eaf6267..9da66d6b6d 100644
--- a/camel/providers/groupwise/camel-gw-listener.c
+++ b/camel/providers/groupwise/camel-gw-listener.c
@@ -162,7 +162,7 @@ lookup_account_info (const char *key)
#define SELECTED_TASKS "/apps/evolution/calendar/tasks/selected_tasks"
static void
-add_esource (const char *conf_key, const char *group_name, const char *source_name, CamelURL *url)
+add_esource (const char *conf_key, const char *group_name, const char* source_name, const char *username, const char* relative_uri, const char *soap_port, const char *use_ssl)
{
ESourceList *source_list;
ESourceGroup *group;
@@ -170,45 +170,20 @@ add_esource (const char *conf_key, const char *group_name, const char *source_n
GConfClient* client;
GSList *ids, *temp ;
char *source_selection_key;
- char *relative_uri;
- const char *soap_port;
- const char * use_ssl;
- const char *poa_address;
- const char *offline_sync;
-
-
- poa_address = camel_url_get_param (url, "poa");
- if (!poa_address || strlen (poa_address) ==0)
- return;
- soap_port = camel_url_get_param (url, "soap_port");
-
- if (!soap_port || strlen (soap_port) == 0)
- soap_port = "7181";
- use_ssl = camel_url_get_param (url, "soap_ssl");
- if (use_ssl)
- use_ssl = "always";
- else
- use_ssl = NULL;
-
- offline_sync = camel_url_get_param (url, "offline_sync");
-
client = gconf_client_get_default();
source_list = e_source_list_new_for_gconf (client, conf_key);
group = e_source_group_new (group_name, GROUPWISE_URI_PREFIX);
- if (!e_source_list_add_group (source_list, group, -1))
+ if ( !e_source_list_add_group (source_list, group, -1))
return;
- relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
-
+
source = e_source_new (source_name, relative_uri);
e_source_set_property (source, "auth", "1");
- e_source_set_property (source, "username", url->user);
- e_source_set_property (source, "port", camel_url_get_param (url, "soap_port"));
+ e_source_set_property (source, "username", username);
+ e_source_set_property (source, "port", soap_port);
e_source_set_property (source, "auth-domain", "Groupwise");
- e_source_set_property (source, "use_ssl", camel_url_get_param (url, "use_ssl"));
- e_source_set_property (source, "offline_sync", offline_sync);
- // e_source_set_property (source, "offline_sync", );
+ e_source_set_property (source, "use_ssl", use_ssl);
e_source_group_add_source (group, source, -1);
e_source_list_sync (source_list, NULL);
@@ -231,7 +206,6 @@ add_esource (const char *conf_key, const char *group_name, const char *source_n
g_object_unref (group);
g_object_unref (source_list);
g_object_unref (client);
- g_free (relative_uri);
}
@@ -308,7 +282,7 @@ remove_esource (const char *conf_key, const char *group_name, char* source_name,
/* looks up for e-source with having same info as old_account_info and changes its values passed in new values */
static void
-modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const char* new_group_name, CamelURL *new_url)
+modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const char* new_group_name, const char *username, const char* new_relative_uri, const char *soap_port, const char *use_ssl)
{
ESourceList *list;
ESourceGroup *group;
@@ -320,15 +294,11 @@ modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const cha
gboolean found_group;
GConfClient* client;
const char *poa_address;
- char *new_relative_uri;
- const char *new_poa_address;
-
+
url = camel_url_new (old_account_info->source_url, NULL);
poa_address = camel_url_get_param (url, "poa");
if (!poa_address || strlen (poa_address) ==0)
return;
- new_poa_address = camel_url_get_param (new_url, "poa");
-
old_relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
client = gconf_client_get_default ();
list = e_source_list_new_for_gconf (client, conf_key);
@@ -351,16 +321,13 @@ modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const cha
if (strcmp (e_source_peek_relative_uri (source), old_relative_uri) == 0) {
- new_relative_uri = g_strdup_printf ("%s@%s/", new_url->user, new_poa_address);
e_source_group_set_name (group, new_group_name);
e_source_set_relative_uri (source, new_relative_uri);
- e_source_set_property (source, "username", new_url->user);
- e_source_set_property (source, "port", camel_url_get_param (new_url,"soap_port"));
- e_source_set_property (source, "use_ssl", camel_url_get_param (url, "soap_ssl"));
- e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync"));
+ e_source_set_property (source, "username", username);
+ e_source_set_property (source, "port", soap_port);
+ e_source_set_property (source, "use_ssl", use_ssl);
e_source_list_sync (list, NULL);
found_group = TRUE;
- g_free (new_relative_uri);
break;
}
}
@@ -371,7 +338,6 @@ modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const cha
g_object_unref (client);
camel_url_free (url);
g_free (old_relative_uri);
-
}
/* add sources for calendar and tasks if the account added is groupwise account
@@ -402,8 +368,8 @@ add_calendar_tasks_sources (GwAccountInfo *info)
use_ssl = NULL;
relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address);
- add_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), url);
- add_esource ("/apps/evolution/tasks/sources", info->name, _("Tasks"), url);
+ add_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), url->user, relative_uri, soap_port, use_ssl);
+ add_esource ("/apps/evolution/tasks/sources", info->name, _("Tasks"), url->user, relative_uri, soap_port, use_ssl);
camel_url_free (url);
g_free (relative_uri);
@@ -551,7 +517,7 @@ add_addressbook_sources (EAccount *account)
e_source_set_property (source, "auth-domain", "Groupwise");
e_source_set_property (source, "port", soap_port);
e_source_set_property(source, "user", url->user);
- e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync"));
+
if (!e_gw_container_get_is_writable (E_GW_CONTAINER(temp_list->data)))
e_source_set_property (source, "completion", "true");
if (e_gw_container_get_is_frequent_contacts (E_GW_CONTAINER(temp_list->data)))
@@ -593,7 +559,6 @@ modify_addressbook_sources ( EAccount *account, GwAccountInfo *existing_account_
ESource *source;
GConfClient *client;
const char *poa_address;
-
url = camel_url_new (existing_account_info->source_url, NULL);
if (url == NULL) {
@@ -766,6 +731,7 @@ account_changed (EAccountList *account_listener, EAccount *account)
{
gboolean is_gw_account;
CamelURL *old_url, *new_url;
+ char *relative_uri;
const char *old_soap_port, *new_soap_port;
GwAccountInfo *existing_account_info;
const char *old_use_ssl, *new_use_ssl;
@@ -833,9 +799,11 @@ account_changed (EAccountList *account_listener, EAccount *account)
account_added (account_listener, account);
} else if (strcmp (existing_account_info->name, account->name)) {
- modify_esource ("/apps/evolution/calendar/sources", existing_account_info, account->name, new_url);
- modify_esource ("/apps/evolution/tasks/sources", existing_account_info, account->name, new_url);
+ relative_uri = g_strdup_printf ("%s@%s/", new_url->user, new_poa_address);
+ modify_esource ("/apps/evolution/calendar/sources", existing_account_info, account->name, new_url->user, relative_uri, new_soap_port, new_use_ssl);
+ modify_esource ("/apps/evolution/tasks/sources", existing_account_info, account->name, new_url->user, relative_uri, new_soap_port, new_use_ssl);
modify_addressbook_sources (account, existing_account_info);
+ g_free (relative_uri);
}
diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c
index eeb3ecd302..fdba581fbb 100644
--- a/camel/providers/imap/camel-imap-command.c
+++ b/camel/providers/imap/camel-imap-command.c
@@ -43,7 +43,7 @@
#include <camel/camel-private.h>
#include <camel/camel-utf8.h>
#include <camel/camel-session.h>
-#include "camel-i18n.h"
+
extern int camel_verbose_debug;
@@ -499,10 +499,16 @@ imap_read_untagged (CamelImapStore *store, char *line, CamelException *ex)
fulllen += str->len;
g_ptr_array_add (data, str);
-
+
/* Read the next line. */
- if (camel_imap_store_readline (store, &line, ex) < 0)
- goto lose;
+ do {
+ if (camel_imap_store_readline (store, &line, ex) < 0)
+ goto lose;
+
+ /* MAJOR HACK ALERT, gropuwise sometimes sends an extra blank line after literals, check that here */
+ if (line[0] == 0)
+ g_warning("Server sent empty line after a literal, assuming in error");
+ } while (line[0] == 0);
}
/* Now reassemble the data. */
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 6cdd96bcf7..d592b819f1 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -23,6 +23,7 @@
* USA
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -37,8 +38,8 @@
#include <fcntl.h>
#include <ctype.h>
-/*#include "libedataserver/e-path.h"*/
-#include "libedataserver/e-time-utils.h"
+#include "e-util/e-path.h"
+#include "e-util/e-time-utils.h"
#include "camel-imap-folder.h"
#include "camel-imap-command.h"
@@ -69,7 +70,6 @@
#include "camel-string-utils.h"
#include "camel-file-utils.h"
#include "camel-debug.h"
-#include "camel-i18n.h"
#define d(x)
@@ -237,7 +237,7 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name,
camel_folder_construct (folder, parent, folder_name, short_name);
summary_file = g_strdup_printf ("%s/summary", folder_dir);
- folder->summary = camel_imap_summary_new (folder, summary_file);
+ folder->summary = camel_imap_summary_new (summary_file);
g_free (summary_file);
if (!folder->summary) {
camel_object_unref (CAMEL_OBJECT (folder));
@@ -387,7 +387,7 @@ camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response,
info = camel_folder_summary_index (folder->summary, count - 1);
val = strtoul (camel_message_info_uid (info), NULL, 10);
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
if (uid == 0 || uid != val)
imap_folder->need_rescan = TRUE;
}
@@ -470,7 +470,7 @@ imap_rename (CamelFolder *folder, const char *new)
char *folders;
folders = g_strconcat (imap_store->storage_path, "/folders", NULL);
- folder_dir = imap_path_to_physical (folders, new);
+ folder_dir = e_path_to_physical (folders, new);
g_free (folders);
summary_path = g_strdup_printf("%s/summary", folder_dir);
@@ -575,7 +575,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
ok = camel_imap_command_start (store, folder, ex,
"UID FETCH 1:%s (FLAGS)",
camel_message_info_uid (info));
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
if (!ok) {
camel_operation_end (NULL);
return;
@@ -632,7 +632,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
iinfo = (CamelImapMessageInfo *)info;
if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) {
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
seq = i + 1;
g_array_append_val (removed, seq);
i--;
@@ -646,8 +646,8 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
server_set = new[i].flags & ~iinfo->server_flags;
server_cleared = iinfo->server_flags & ~new[i].flags;
-
- iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
+
+ info->flags = (info->flags | server_set) & ~server_cleared;
iinfo->server_flags = new[i].flags;
if (changes == NULL)
@@ -655,7 +655,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex)
camel_folder_change_info_change_uid(changes, new[i].uid);
}
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
g_free (new[i].uid);
}
@@ -697,7 +697,7 @@ static GPtrArray *
get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
{
GPtrArray *matches;
- CamelImapMessageInfo *info;
+ CamelMessageInfo *info;
int i, max, range;
GString *gset;
@@ -706,11 +706,11 @@ get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set)
max = camel_folder_summary_count (folder->summary);
range = -1;
for (i = 0; i < max && !UID_SET_FULL (gset->len, UID_SET_LIMIT); i++) {
- info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i);
+ info = camel_folder_summary_index (folder->summary, i);
if (!info)
continue;
- if ((info->info.flags & mask) != flags) {
- camel_message_info_free((CamelMessageInfo *)info);
+ if ((info->flags & mask) != flags) {
+ camel_folder_summary_info_free (folder->summary, info);
if (range != -1) {
if (range != i - 1) {
info = matches->pdata[matches->len - 1];
@@ -758,7 +758,7 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
{
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
CamelImapResponse *response = NULL;
- CamelImapMessageInfo *info;
+ CamelMessageInfo *info;
CamelException local_ex;
GPtrArray *matches;
char *set, *flaglist;
@@ -779,33 +779,33 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
*/
max = camel_folder_summary_count (folder->summary);
for (i = 0; i < max; i++) {
- if (!(info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i)))
+ if (!(info = camel_folder_summary_index (folder->summary, i)))
continue;
- if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
- camel_message_info_free((CamelMessageInfo *)info);
+ if (!(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
+ camel_folder_summary_info_free (folder->summary, info);
continue;
}
/* Note: Cyrus is broken and will not accept an
empty-set of flags so... if this is true then we
want to unset the previously set flags.*/
- unset = !(info->info.flags & folder->permanent_flags);
+ unset = !(info->flags & folder->permanent_flags);
/* Note: get_matching() uses UID_SET_LIMIT to limit
the size of the uid-set string. We don't have to
loop here to flush all the matching uids because
they will be scooped up later by our parent loop (I
think?). -- Jeff */
- matches = get_matching (folder, info->info.flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
+ matches = get_matching (folder, info->flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED),
folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED, &set);
- camel_message_info_free(info);
+ camel_folder_summary_info_free (folder->summary, info);
if (matches == NULL)
continue;
/* FIXME: since we don't know the previously set flags,
if unset is TRUE then just unset all the flags? */
- flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->info.flags & folder->permanent_flags);
+ flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->flags & folder->permanent_flags);
/* Note: to `unset' flags, use -FLAGS.SILENT (<flag list>) */
response = camel_imap_command (store, folder, &local_ex,
@@ -820,15 +820,16 @@ imap_sync_online (CamelFolder *folder, CamelException *ex)
if (!camel_exception_is_set (&local_ex)) {
for (j = 0; j < matches->len; j++) {
info = matches->pdata[j];
- info->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
- ((CamelImapMessageInfo *) info)->server_flags = info->info.flags & CAMEL_IMAP_SERVER_FLAGS;
+ info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+ ((CamelImapMessageInfo *) info)->server_flags =
+ info->flags & CAMEL_IMAP_SERVER_FLAGS;
}
camel_folder_summary_touch (folder->summary);
}
for (j = 0; j < matches->len; j++) {
info = matches->pdata[j];
- camel_message_info_free(&info->info);
+ camel_folder_summary_info_free (folder->summary, info);
}
g_ptr_array_free (matches, TRUE);
@@ -1166,11 +1167,10 @@ do_append (CamelFolder *folder, CamelMimeMessage *message,
CamelStreamFilter *streamfilter;
GByteArray *ba;
char *flagstr, *end;
- guint32 flags;
-
- flags = camel_message_info_flags(info);
- if (flags)
- flagstr = imap_create_flag_list (flags);
+
+ /* create flag string param */
+ if (info && info->flags)
+ flagstr = imap_create_flag_list (info->flags);
else
flagstr = NULL;
@@ -1357,7 +1357,7 @@ imap_transfer_offline (CamelFolder *source, GPtrArray *uids,
camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi);
camel_imap_message_cache_copy (sc, uid, dc, destuid, ex);
- camel_message_info_free(mi);
+ camel_folder_summary_info_free (source->summary, mi);
camel_folder_change_info_add_uid (changes, destuid);
if (transferred_uids)
@@ -1968,12 +1968,12 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelImapMessageInfo *mi;
+ CamelMessageInfo *mi;
CamelMimeMessage *msg = NULL;
CamelStream *stream = NULL;
int retry;
- mi = (CamelImapMessageInfo *)camel_folder_summary_uid (folder->summary, uid);
+ mi = camel_folder_summary_uid (folder->summary, uid);
if (mi == NULL) {
camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
_("Cannot get message: %s\n %s"), uid, _("No such message"));
@@ -2001,11 +2001,11 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
/* If the message is small or only 1 part, or server doesn't do 4v1 (properly) fetch it in one piece. */
if (store->server_level < IMAP_LEVEL_IMAP4REV1
|| store->braindamaged
- || mi->info.size < IMAP_SMALL_BODY_SIZE
- || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) {
+ || mi->size < IMAP_SMALL_BODY_SIZE
+ || (!content_info_incomplete(mi->content) && !mi->content->childs)) {
msg = get_message_simple (imap_folder, uid, NULL, ex);
} else {
- if (content_info_incomplete (mi->info.content)) {
+ if (content_info_incomplete (mi->content)) {
/* For larger messages, fetch the structure and build a message
* with offline parts. (We check mi->content->type rather than
* mi->content because camel_folder_summary_info_new always creates
@@ -2038,7 +2038,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
}
if (body)
- imap_parse_body ((const char **) &body, folder, mi->info.content);
+ imap_parse_body ((const char **) &body, folder, mi->content);
if (fetch_data)
g_datalist_clear (&fetch_data);
@@ -2049,7 +2049,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
if (camel_debug_start("imap:folder")) {
printf("Folder get message '%s' folder info ->\n", uid);
- camel_message_info_dump((CamelMessageInfo *)mi);
+ camel_message_info_dump(mi);
camel_debug_end();
}
@@ -2059,10 +2059,10 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
* fall back to fetching the entire thing and
* let the mailer's "bad MIME" code handle it.
*/
- if (content_info_incomplete (mi->info.content))
+ if (content_info_incomplete (mi->content))
msg = get_message_simple (imap_folder, uid, NULL, ex);
else
- msg = get_message (imap_folder, uid, mi->info.content, ex);
+ msg = get_message (imap_folder, uid, mi->content, ex);
}
} while (msg == NULL
&& retry < 2
@@ -2072,7 +2072,7 @@ done: /* FIXME, this shouldn't be done this way. */
if (msg)
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url);
fail:
- camel_message_info_free(&mi->info);
+ camel_folder_summary_info_free (folder->summary, mi);
return msg;
}
@@ -2201,7 +2201,7 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
{
CamelMimeMessage *msg;
CamelStream *stream;
- CamelImapMessageInfo *mi;
+ CamelMessageInfo *mi;
const char *idate;
int seq;
@@ -2221,14 +2221,14 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages,
return;
}
- mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
+ mi = camel_folder_summary_info_new_from_message (folder->summary, msg);
camel_object_unref (CAMEL_OBJECT (msg));
if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
- mi->info.date_received = decode_internaldate (idate);
+ mi->date_received = decode_internaldate (idate);
- if (mi->info.date_received == -1)
- mi->info.date_received = mi->info.date_sent;
+ if (mi->date_received == -1)
+ mi->date_received = mi->date_sent;
messages->pdata[seq - first] = mi;
}
@@ -2253,7 +2253,7 @@ imap_update_summary (CamelFolder *folder, int exists,
int i, seq, first, size, got;
CamelImapResponseType type;
const char *header_spec;
- CamelImapMessageInfo *mi, *info;
+ CamelMessageInfo *mi, *info;
CamelStream *stream;
char *uid, *resp;
GData *data;
@@ -2272,9 +2272,9 @@ imap_update_summary (CamelFolder *folder, int exists,
seq = camel_folder_summary_count (folder->summary);
first = seq + 1;
if (seq > 0) {
- mi = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, seq - 1);
+ mi = camel_folder_summary_index (folder->summary, seq - 1);
uidval = strtoul(camel_message_info_uid (mi), NULL, 10);
- camel_message_info_free(&mi->info);
+ camel_folder_summary_info_free (folder->summary, mi);
} else
uidval = 0;
@@ -2433,23 +2433,24 @@ imap_update_summary (CamelFolder *folder, int exists,
continue;
}
- mi = (CamelImapMessageInfo *)camel_message_info_clone(pmi);
+ mi = camel_message_info_new ();
+ camel_message_info_dup_to (pmi, mi);
}
uid = g_datalist_get_data (&data, "UID");
if (uid)
- mi->info.uid = g_strdup (uid);
+ camel_message_info_set_uid (mi, g_strdup (uid));
flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
if (flags) {
((CamelImapMessageInfo *)mi)->server_flags = flags;
/* "or" them in with the existing flags that may
* have been set by summary_info_new_from_message.
*/
- mi->info.flags |= flags;
+ mi->flags |= flags;
}
size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE"));
if (size)
- mi->info.size = size;
+ mi->size = size;
g_datalist_clear (&data);
}
@@ -2473,7 +2474,7 @@ imap_update_summary (CamelFolder *folder, int exists,
i + first);
break;
}
- info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
+ info = camel_folder_summary_uid(folder->summary, uid);
if (info) {
for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) {
if (folder->summary->messages->pdata[seq] == info)
@@ -2485,20 +2486,20 @@ imap_update_summary (CamelFolder *folder, int exists,
_("Unexpected server response: Identical UIDs provided for messages %d and %d"),
seq + 1, i + first);
- camel_message_info_free(&info->info);
+ camel_folder_summary_info_free(folder->summary, info);
break;
}
- camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);
+ camel_folder_summary_add (folder->summary, mi);
camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
- if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT))
+ if ((mi->flags & CAMEL_IMAP_MESSAGE_RECENT))
camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi));
}
for ( ; i < messages->len; i++) {
if ((mi = messages->pdata[i]))
- camel_message_info_free(&mi->info);
+ camel_folder_summary_info_free(folder->summary, mi);
}
g_ptr_array_free (messages, TRUE);
@@ -2516,7 +2517,7 @@ imap_update_summary (CamelFolder *folder, int exists,
if (messages) {
for (i = 0; i < messages->len; i++) {
if (messages->pdata[i])
- camel_message_info_free(messages->pdata[i]);
+ camel_folder_summary_info_free (folder->summary, messages->pdata[i]);
}
g_ptr_array_free (messages, TRUE);
}
@@ -2552,7 +2553,7 @@ camel_imap_folder_changed (CamelFolder *folder, int exists,
camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info));
CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
camel_folder_summary_remove (folder->summary, info);
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
}
}
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 5811b0f691..3f92c2f40a 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -24,6 +24,7 @@
*
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -34,6 +35,8 @@
#include <unistd.h>
#include <errno.h>
+#include "e-util/e-path.h"
+
#include "camel-imap-store.h"
#include "camel-imap-store-summary.h"
#include "camel-imap-folder.h"
@@ -56,11 +59,11 @@
#include "camel-sasl.h"
#include "camel-utf8.h"
#include "camel-string-utils.h"
+
#include "camel-imap-private.h"
#include "camel-private.h"
+
#include "camel-debug.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
#define d(x)
@@ -502,52 +505,87 @@ imap_get_capability (CamelService *service, CamelException *ex)
}
enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
+ USE_SSL_NEVER,
+ USE_SSL_ALWAYS,
+ USE_SSL_WHEN_POSSIBLE
};
#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelException *ex)
{
CamelImapStore *store = (CamelImapStore *) service;
CamelImapResponse *response;
CamelStream *tcp_stream;
CamelSockOptData sockopt;
gboolean force_imap4 = FALSE;
- int clean_quit, ret;
+ int clean_quit;
+ int ret;
char *buf;
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
+
+ /* FIXME: this connect stuff is duplicated everywhere */
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "imap";
+ port = IMAP_PORT;
+ }
- if (ssl_mode != MODE_CLEAR) {
+ if (ssl_mode != USE_SSL_NEVER) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
+ if (try_starttls) {
tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
} else {
+ if (service->url->port == 0) {
+ serv = "imaps";
+ port = IMAPS_PORT;
+ }
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
+ if (!try_starttls && service->url->port == 0) {
+ serv = "imaps";
+ port = IMAPS_PORT;
+ }
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ _("SSL unavailable"));
return FALSE;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ return FALSE;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
if (errno == EINTR)
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("Connection cancelled"));
else
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv, g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -591,7 +629,7 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
if (!strncmp(buf, "* PREAUTH", 9))
store->preauthed = TRUE;
- if (strstr (buf, "Courier-IMAP")) {
+ if (strstr (buf, "Courier-IMAP") || getenv("CAMEL_IMAP_BRAINDAMAGED")) {
/* Courier-IMAP is braindamaged. So far this flag only
* works around the fact that Courier-IMAP is known to
* give invalid BODY responses seemingly because its
@@ -642,18 +680,32 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
store->server_level = IMAP_LEVEL_IMAP4;
}
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
+#ifdef HAVE_SSL
+ if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ if (store->capabilities & IMAP_CAPABILITY_STARTTLS)
+ goto starttls;
+ } else if (ssl_mode == USE_SSL_ALWAYS) {
+ if (try_starttls) {
+ if (store->capabilities & IMAP_CAPABILITY_STARTTLS) {
+ /* attempt to toggle STARTTLS mode */
+ goto starttls;
+ } else {
+ /* server doesn't support STARTTLS, abort */
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to connect to IMAP server %s in secure mode: %s"),
+ service->url->host, _("SSL/TLS extension not supported."));
+ /* we have the possibility of quitting cleanly here */
+ clean_quit = TRUE;
+ goto exception;
+ }
+ }
}
+#endif /* HAVE_SSL */
- if (!(store->capabilities & IMAP_CAPABILITY_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to IMAP server %s in secure mode: %s"),
- service->url->host, _("STARTTLS not supported"));
-
- goto exception;
- }
+ return TRUE;
+
+#ifdef HAVE_SSL
+ starttls:
/* as soon as we send a STARTTLS command, all hope is lost of a clean QUIT if problems arise */
clean_quit = FALSE;
@@ -718,6 +770,7 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
store->connected = FALSE;
return FALSE;
+#endif /* HAVE_SSL */
}
static gboolean
@@ -865,70 +918,60 @@ connect_to_server_process (CamelService *service, const char *cmd, CamelExceptio
static struct {
char *value;
- char *serv;
- char *port;
int mode;
} ssl_options[] = {
- { "", "imaps", IMAPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "imaps", IMAPS_PORT, MODE_SSL },
- { "when-possible", "imap", IMAP_PORT, MODE_TLS },
- { "never", "imap", IMAP_PORT, MODE_CLEAR },
- { NULL, "imap", IMAP_PORT, MODE_CLEAR },
+ { "", USE_SSL_ALWAYS },
+ { "always", USE_SSL_ALWAYS },
+ { "when-possible", USE_SSL_WHEN_POSSIBLE },
+ { "never", USE_SSL_NEVER },
+ { NULL, USE_SSL_NEVER },
};
static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
- const char *command, *ssl_mode;
- struct addrinfo hints, *ai;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((command = camel_url_get_param (service->url, "command")))
+ const char *command;
+#ifdef HAVE_SSL
+ const char *use_ssl;
+ int i, ssl_mode;
+#endif
+ command = camel_url_get_param (service->url, "command");
+ if (command)
return connect_to_server_process (service, command, ex);
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
+
+#ifdef HAVE_SSL
+ use_ssl = camel_url_get_param (service->url, "use_ssl");
+ if (use_ssl) {
for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
+ if (!strcmp (ssl_options[i].value, use_ssl))
break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
+ ssl_mode = ssl_options[i].mode;
+ } else
+ ssl_mode = USE_SSL_NEVER;
+
+ if (ssl_mode == USE_SSL_ALWAYS) {
+ /* First try the ssl port */
+ if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* The ssl port seems to be unavailable, lets try STARTTLS */
+ camel_exception_clear (ex);
+ return connect_to_server (service, ssl_mode, TRUE, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports STARTTLS, use it */
+ return connect_to_server (service, ssl_mode, TRUE, ex);
} else {
- mode = MODE_CLEAR;
- serv = "imap";
- port = IMAP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
+ /* User doesn't care about SSL */
+ return connect_to_server (service, ssl_mode, FALSE, ex);
}
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
+#endif
}
extern CamelServiceAuthType camel_imap_password_authtype;
@@ -1041,7 +1084,7 @@ imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelEx
name = folder_name;
storage_path = g_strdup_printf ("%s/folders", imap_store->storage_path);
- folder_dir = imap_path_to_physical (storage_path, folder_name);
+ folder_dir = e_path_to_physical (storage_path, folder_name);
g_free (storage_path);
if (access (folder_dir, F_OK) != 0) {
g_free (folder_dir);
@@ -1049,7 +1092,7 @@ imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelEx
}
summary_file = g_strdup_printf ("%s/summary", folder_dir);
- summary = camel_imap_summary_new (NULL, summary_file);
+ summary = camel_imap_summary_new (summary_file);
if (!summary) {
g_free (summary_file);
g_free (folder_dir);
@@ -1599,17 +1642,14 @@ imap_disconnect_online (CamelService *service, gboolean clean, CamelException *e
static gboolean
imap_summary_is_dirty (CamelFolderSummary *summary)
{
- CamelImapMessageInfo *info;
+ CamelMessageInfo *info;
int max, i;
- int found = FALSE;
-
+
max = camel_folder_summary_count (summary);
- for (i = 0; i < max && !found; i++) {
- info = (CamelImapMessageInfo *)camel_folder_summary_index (summary, i);
- if (info) {
- found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED;
- camel_message_info_free(info);
- }
+ for (i = 0; i < max; i++) {
+ info = camel_folder_summary_index (summary, i);
+ if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED))
+ return TRUE;
}
return FALSE;
@@ -1982,7 +2022,7 @@ get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, Ca
}
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = imap_path_to_physical (storage_path, folder_name);
+ folder_dir = e_path_to_physical (storage_path, folder_name);
g_free(storage_path);
new_folder = camel_imap_folder_new (store, folder_name, folder_dir, ex);
g_free (folder_dir);
@@ -2025,7 +2065,7 @@ get_folder_offline (CamelStore *store, const char *folder_name,
folder_name = "INBOX";
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- folder_dir = imap_path_to_physical (storage_path, folder_name);
+ folder_dir = e_path_to_physical (storage_path, folder_name);
g_free(storage_path);
if (!folder_dir || access (folder_dir, F_OK) != 0) {
g_free (folder_dir);
@@ -2195,8 +2235,8 @@ rename_folder (CamelStore *store, const char *old_name, const char *new_name_in,
manage_subscriptions(store, new_name_in, TRUE);
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- oldpath = imap_path_to_physical (storage_path, old_name);
- newpath = imap_path_to_physical (storage_path, new_name_in);
+ oldpath = e_path_to_physical (storage_path, old_name);
+ newpath = e_path_to_physical (storage_path, new_name_in);
g_free(storage_path);
/* So do we care if this didn't work? Its just a cache? */
@@ -2631,7 +2671,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
/* This is a lot of work for one path! */
storage_path = g_strdup_printf("%s/folders", ((CamelImapStore *)store)->storage_path);
- folder_dir = imap_path_to_physical(storage_path, fi->full_name);
+ folder_dir = e_path_to_physical(storage_path, fi->full_name);
path = g_strdup_printf("%s/summary", folder_dir);
s = (CamelFolderSummary *)camel_object_new(camel_imap_summary_get_type());
camel_folder_summary_set_build_content(s, TRUE);
@@ -3037,7 +3077,7 @@ get_folder_info_offline (CamelStore *store, const char *top,
/* A kludge to avoid having to pass a struct to the callback */
g_ptr_array_add (folders, imap_store);
storage_path = g_strdup_printf("%s/folders", imap_store->storage_path);
- if (!imap_path_find_folders (storage_path, get_one_folder_offline, folders)) {
+ if (!e_path_find_folders (storage_path, get_one_folder_offline, folders)) {
camel_disco_store_check_online (CAMEL_DISCO_STORE (imap_store), ex);
fi = NULL;
} else {
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
index d6f17532ee..adbf862747 100644
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ b/camel/providers/imap4/camel-imap4-engine.c
@@ -28,7 +28,6 @@
#include <camel/camel-sasl.h>
#include <camel/camel-stream-buffer.h>
-#include <camel/camel-i18n.h>
#include "camel-imap4-summary.h"
#include "camel-imap4-command.h"
@@ -115,6 +114,22 @@ camel_imap4_engine_init (CamelIMAP4Engine *engine, CamelIMAP4EngineClass *klass)
}
static void
+imap4_namespace_clear (CamelIMAP4Namespace **namespace)
+{
+ CamelIMAP4Namespace *node, *next;
+
+ node = *namespace;
+ while (node != NULL) {
+ next = node->next;
+ g_free (node->path);
+ g_free (node);
+ node = next;
+ }
+
+ *namespace = NULL;
+}
+
+static void
camel_imap4_engine_finalize (CamelObject *object)
{
CamelIMAP4Engine *engine = (CamelIMAP4Engine *) object;
@@ -129,9 +144,9 @@ camel_imap4_engine_finalize (CamelObject *object)
g_hash_table_foreach (engine->authtypes, (GHFunc) g_free, NULL);
g_hash_table_destroy (engine->authtypes);
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
+ imap4_namespace_clear (&engine->namespaces.personal);
+ imap4_namespace_clear (&engine->namespaces.other);
+ imap4_namespace_clear (&engine->namespaces.shared);
if (engine->folder)
camel_object_unref (engine->folder);
@@ -148,7 +163,6 @@ camel_imap4_engine_finalize (CamelObject *object)
/**
* camel_imap4_engine_new:
* @service: service
- * @reconnect: reconnect callback function
*
* Returns a new imap4 engine
**/
@@ -334,16 +348,6 @@ camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex)
}
-/**
- * camel_imap4_engine_select_folder:
- * @engine: IMAP4 engine
- * @folder: folder to select
- * @ex: exception
- *
- * Convenience function to select @folder.
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_select_folder (CamelIMAP4Engine *engine, CamelFolder *folder, CamelException *ex)
{
@@ -435,15 +439,11 @@ static struct {
{ "IMAP4", CAMEL_IMAP4_CAPABILITY_IMAP4 },
{ "IMAP4REV1", CAMEL_IMAP4_CAPABILITY_IMAP4REV1 },
{ "STATUS", CAMEL_IMAP4_CAPABILITY_STATUS },
- { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE }, /* rfc2342 */
- { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS }, /* rfc2359 */
- { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS }, /* rfc2088 */
+ { "NAMESPACE", CAMEL_IMAP4_CAPABILITY_NAMESPACE },
+ { "UIDPLUS", CAMEL_IMAP4_CAPABILITY_UIDPLUS },
+ { "LITERAL+", CAMEL_IMAP4_CAPABILITY_LITERALPLUS },
{ "LOGINDISABLED", CAMEL_IMAP4_CAPABILITY_LOGINDISABLED },
{ "STARTTLS", CAMEL_IMAP4_CAPABILITY_STARTTLS },
- { "QUOTA", CAMEL_IMAP4_CAPABILITY_QUOTA }, /* rfc2087 */
- { "ACL", CAMEL_IMAP4_CAPABILITY_ACL }, /* rfc2086 */
- { "IDLE", CAMEL_IMAP4_CAPABILITY_IDLE }, /* rfc2177 */
- { "MULTIAPPEND", CAMEL_IMAP4_CAPABILITY_MULTIAPPEND }, /* rfc3502 */
{ NULL, 0 }
};
@@ -469,7 +469,7 @@ engine_parse_capability (CamelIMAP4Engine *engine, int sentinel, CamelException
return -1;
while (token.token == CAMEL_IMAP4_TOKEN_ATOM) {
- if (!g_ascii_strncasecmp ("AUTH=", token.v.atom, 5)) {
+ if (!strncasecmp ("AUTH=", token.v.atom, 5)) {
CamelServiceAuthType *auth;
if ((auth = camel_sasl_authtype (token.v.atom + 5)) != NULL)
@@ -563,9 +563,9 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
camel_imap4_token_t token;
int i, n = 0;
- camel_imap4_namespace_clear (&engine->namespaces.personal);
- camel_imap4_namespace_clear (&engine->namespaces.other);
- camel_imap4_namespace_clear (&engine->namespaces.shared);
+ imap4_namespace_clear (&engine->namespaces.personal);
+ imap4_namespace_clear (&engine->namespaces.other);
+ imap4_namespace_clear (&engine->namespaces.shared);
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
@@ -604,19 +604,8 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
goto exception;
}
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- node->sep = '\0';
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- if (strlen (token.v.qstring) == 1) {
- node->sep = *token.v.qstring;
- break;
- } else {
- /* invalid, fall thru */
- }
- default:
- d(fprintf (stderr, "Expected to find a nil or a valid qstring token as second element in NAMESPACE pair\n"));
+ if (token.token != CAMEL_IMAP4_TOKEN_QSTRING || strlen (token.v.qstring) > 1) {
+ d(fprintf (stderr, "Expected to find a qstring token as second element in NAMESPACE pair\n"));
camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
g_free (node->path);
g_free (node);
@@ -624,6 +613,7 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
goto exception;
}
+ node->sep = *token.v.qstring;
tail->next = node;
tail = node;
@@ -682,7 +672,7 @@ engine_parse_namespace (CamelIMAP4Engine *engine, CamelException *ex)
exception:
for (i = 0; i <= n; i++)
- camel_imap4_namespace_clear (&namespaces[i]);
+ imap4_namespace_clear (&namespaces[i]);
return -1;
}
@@ -723,15 +713,6 @@ static struct {
};
-/**
- * camel_imap4_engine_parse_resp_code:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Parses a RESP-CODE
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -900,34 +881,26 @@ camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the second argument to the COPYUID RESP-CODE\n"));
+ if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
+ d(fprintf (stderr, "Expected an atom token as the second argument to the COPYUID RESP-CODE\n"));
camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
goto exception;
}
- if (resp != NULL) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.srcset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.srcset = g_strdup (token.v.atom);
- }
+ if (resp != NULL)
+ resp->v.copyuid.srcset = g_strdup (token.v.atom);
if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
return -1;
- if (token.token != CAMEL_IMAP4_TOKEN_ATOM && token.token != CAMEL_IMAP4_TOKEN_NUMBER) {
- d(fprintf (stderr, "Expected an atom or numeric token as the third argument to the APPENDUID RESP-CODE\n"));
+ if (token.token != CAMEL_IMAP4_TOKEN_ATOM) {
+ d(fprintf (stderr, "Expected an atom token as the third argument to the APPENDUID RESP-CODE\n"));
camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
goto exception;
}
- if (resp != NULL) {
- if (token.token == CAMEL_IMAP4_TOKEN_NUMBER)
- resp->v.copyuid.destset = g_strdup_printf ("%u", token.v.number);
- else
- resp->v.copyuid.destset = g_strdup (token.v.atom);
- }
+ if (resp != NULL)
+ resp->v.copyuid.destset = g_strdup (token.v.atom);
break;
default:
@@ -986,17 +959,8 @@ camel_imap4_engine_parse_resp_code (CamelIMAP4Engine *engine, CamelException *ex
}
-/**
- * camel_imap4_engine_handle_untagged_1:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Handles a single untagged response
- *
- * Returns -1 on error or one of
- * CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success
- **/
+
+/* returns -1 on error, or one of CAMEL_IMAP4_UNTAGGED_[OK,NO,BAD,PREAUTH,HANDLED] on success */
int
camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
{
@@ -1149,13 +1113,6 @@ camel_imap4_engine_handle_untagged_1 (CamelIMAP4Engine *engine, camel_imap4_toke
}
-/**
- * camel_imap4_engine_handle_untagged:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Handle a stream of untagged responses.
- **/
void
camel_imap4_engine_handle_untagged (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -1254,7 +1211,6 @@ engine_state_change (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
return retval;
}
-
/**
* camel_imap4_engine_iterate:
* @engine: IMAP4 engine
@@ -1421,13 +1377,6 @@ camel_imap4_engine_prequeue (CamelIMAP4Engine *engine, CamelFolder *folder, cons
}
-/**
- * camel_imap4_engine_dequeue:
- * @engine: IMAP4 engine
- * @ic: IMAP4 command
- *
- * Removes @ic from the processing queue.
- **/
void
camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
{
@@ -1444,18 +1393,6 @@ camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic)
}
-/**
- * camel_imap4_engine_next_token:
- * @engine: IMAP4 engine
- * @token: IMAP4 token
- * @ex: exception
- *
- * Wraps camel_imap4_stream_next_token() to set an exception on
- * failure and updates the engine state to DISCONNECTED if the stream
- * gets disconencted.
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex)
{
@@ -1473,15 +1410,6 @@ camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *to
}
-/**
- * camel_imap4_engine_eat_line:
- * @engine: IMAP4 engine
- * @ex: exception
- *
- * Gobbles up the remainder of the response line.
- *
- * Returns 0 on success or -1 on fail
- **/
int
camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
{
@@ -1514,19 +1442,6 @@ camel_imap4_engine_eat_line (CamelIMAP4Engine *engine, CamelException *ex)
}
-/**
- * camel_imap4_engine_line:
- * @engine: IMAP4 engine
- * @line: line pointer
- * @len: length pointer
- * @ex: exception
- *
- * Reads in a single line of input from the IMAP4 server and updates
- * @line to point to the line buffer. @len is set to the length of the
- * line buffer. @line must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail
- **/
int
camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t *len, CamelException *ex)
{
@@ -1569,20 +1484,6 @@ camel_imap4_engine_line (CamelIMAP4Engine *engine, unsigned char **line, size_t
}
-/**
- * camel_imap4_engine_literal:
- * @engine: IMAP4 engine
- * @literal: literal pointer
- * @len: len pointer
- * @ex: exception
- *
- * Reads in an entire literal string and updates @literal to point to
- * it. @len is set to the length of the literal. @literal will also
- * conveniently be terminated with a nul-byte. @literal must be free'd
- * using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
int
camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, size_t *len, CamelException *ex)
{
@@ -1626,55 +1527,6 @@ camel_imap4_engine_literal (CamelIMAP4Engine *engine, unsigned char **literal, s
}
-/**
- * camel_imap4_engine_nstring:
- * @engine: IMAP4 engine
- * @nstring: nstring pointer
- * @ex: exception
- *
- * Reads in an nstring (NIL, atom, qstring or literal) and updates
- * @nstring to point to it. @nstring must be free'd using g_free().
- *
- * Returns 0 on success or -1 on fail.
- **/
-int
-camel_imap4_engine_nstring (CamelIMAP4Engine *engine, unsigned char **nstring, CamelException *ex)
-{
- camel_imap4_token_t token;
- size_t n;
-
- if (camel_imap4_engine_next_token (engine, &token, ex) == -1)
- return -1;
-
- switch (token.token) {
- case CAMEL_IMAP4_TOKEN_NIL:
- *nstring = NULL;
- break;
- case CAMEL_IMAP4_TOKEN_ATOM:
- *nstring = g_strdup (token.v.atom);
- break;
- case CAMEL_IMAP4_TOKEN_QSTRING:
- *nstring = g_strdup (token.v.qstring);
- break;
- case CAMEL_IMAP4_TOKEN_LITERAL:
- if (camel_imap4_engine_literal (engine, nstring, &n, ex) == -1)
- return -1;
- break;
- default:
- camel_imap4_utils_set_unexpected_token_error (ex, engine, &token);
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * camel_imap4_resp_code_free:
- * @rcode: RESP-CODE
- *
- * Free's the RESP-CODE
- **/
void
camel_imap4_resp_code_free (CamelIMAP4RespCode *rcode)
{
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
index 2e7308d75d..0d33f43c5d 100644
--- a/camel/providers/imap4/camel-imap4-store.c
+++ b/camel/providers/imap4/camel-imap4-store.c
@@ -34,9 +34,6 @@
#include <camel/camel-private.h>
-#include <camel/camel-i18n.h>
-#include <camel/camel-net-utils.h>
-
#include "camel-imap4-store.h"
#include "camel-imap4-engine.h"
#include "camel-imap4-folder.h"
@@ -44,9 +41,7 @@
#include "camel-imap4-command.h"
#include "camel-imap4-utils.h"
#include "camel-imap4-summary.h"
-#include "camel-imap4-store-summary.h"
-#define d(x) x
static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
static void camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass);
@@ -148,7 +143,6 @@ static void
camel_imap4_store_init (CamelIMAP4Store *store, CamelIMAP4StoreClass *klass)
{
store->engine = NULL;
- store->summary = NULL;
}
static void
@@ -156,11 +150,6 @@ camel_imap4_store_finalize (CamelObject *object)
{
CamelIMAP4Store *store = (CamelIMAP4Store *) object;
- if (store->summary) {
- camel_store_summary_save ((CamelStoreSummary *) store->summary);
- camel_object_unref (store->summary);
- }
-
if (store->engine)
camel_object_unref (store->engine);
@@ -172,7 +161,6 @@ static void
imap4_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
{
CamelIMAP4Store *store = (CamelIMAP4Store *) service;
- char *buf;
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
if (camel_exception_is_set (ex))
@@ -180,20 +168,6 @@ imap4_construct (CamelService *service, CamelSession *session, CamelProvider *pr
store->storage_path = camel_session_get_storage_path (session, service, ex);
store->engine = camel_imap4_engine_new (service, imap4_reconnect);
-
- /* setup/load the summary */
- buf = g_alloca (strlen (store->storage_path) + 32);
- sprintf (buf, "%s/.summary", store->storage_path);
- store->summary = camel_imap4_store_summary_new ();
- camel_store_summary_set_filename ((CamelStoreSummary *) store->summary, buf);
-
- buf = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
- url = camel_url_new (buf, NULL);
- g_free (buf);
- camel_store_summary_set_uri_base ((CamelStoreSummary *) store->summary, url);
- camel_url_free (url);
-
- camel_store_summary_load ((CamelStoreSummary *) store->summary);
}
static char *
@@ -226,7 +200,7 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode,
if (ssl_mode != MODE_CLEAR) {
#ifdef HAVE_SSL
if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
+ tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
} else {
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
@@ -262,8 +236,6 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode,
if (camel_imap4_engine_capability (engine, ex) == -1)
return FALSE;
- camel_imap4_store_summary_set_capabilities (((CamelIMAP4Store *) service)->summary, engine->capa);
-
if (ssl_mode != MODE_TLS) {
/* we're done */
return TRUE;
@@ -320,9 +292,9 @@ connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
struct addrinfo *ai, hints;
const char *ssl_mode;
int mode, ret, i;
- const char *port;
char *serv;
-
+ const char *port;
+
if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
for (i = 0; ssl_options[i].value; i++)
if (!strcmp (ssl_options[i].value, ssl_mode))
@@ -353,13 +325,7 @@ connect_to_server_wrapper (CamelIMAP4Engine *engine, CamelException *ex)
if (ai == NULL)
return FALSE;
- if (!(ret = connect_to_server (engine, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (engine, ai, MODE_CLEAR, ex);
- }
+ ret = connect_to_server (engine, ai, mode, ex);
camel_freeaddrinfo (ai);
@@ -389,7 +355,7 @@ sasl_auth (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, const unsigned char
if (!(challenge = camel_sasl_challenge_base64 (sasl, (const char *) linebuf, ex)))
return -1;
- d(fprintf (stderr, "sending : %s\r\n", challenge));
+ fprintf (stderr, "sending : %s\r\n", challenge);
if (camel_stream_printf (engine->ostream, "%s\r\n", challenge) == -1) {
g_free (challenge);
@@ -437,7 +403,7 @@ imap4_try_authenticate (CamelIMAP4Engine *engine, gboolean reprompt, const char
CamelServiceAuthType *mech;
mech = g_hash_table_lookup (engine->authtypes, service->url->authmech);
- sasl = camel_sasl_new ("imap", mech->authproto, service);
+ sasl = camel_sasl_new ("imap4", mech->authproto, service);
ic = camel_imap4_engine_prequeue (engine, NULL, "AUTHENTICATE %s\r\n", service->url->authmech);
ic->plus = sasl_auth;
@@ -501,8 +467,6 @@ imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
g_free (errmsg);
errmsg = g_strdup (lex.desc);
camel_exception_clear (&lex);
- g_free (service->url->passwd);
- service->url->passwd = NULL;
reprompt = TRUE;
}
g_free (errmsg);
@@ -515,25 +479,16 @@ imap4_reconnect (CamelIMAP4Engine *engine, CamelException *ex)
if (camel_imap4_engine_namespace (engine, ex) == -1)
return FALSE;
- camel_imap4_store_summary_set_namespaces (((CamelIMAP4Store *) service)->summary, &engine->namespaces);
-
return TRUE;
}
static gboolean
imap4_connect (CamelService *service, CamelException *ex)
{
- CamelIMAP4Store *store = (CamelIMAP4Store *) service;
gboolean retval;
- if (!camel_session_is_online (service->session))
- return TRUE;
-
CAMEL_SERVICE_LOCK (service, connect_lock);
- if (store->engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED)
- retval = imap4_reconnect (store->engine, ex);
- else
- retval = TRUE;
+ retval = imap4_reconnect (((CamelIMAP4Store *) service)->engine, ex);
CAMEL_SERVICE_UNLOCK (service, connect_lock);
return retval;
@@ -546,18 +501,13 @@ imap4_disconnect (CamelService *service, gboolean clean, CamelException *ex)
CamelIMAP4Command *ic;
int id;
- if (!camel_session_is_online (service->session))
- return TRUE;
-
- CAMEL_SERVICE_LOCK (store, connect_lock);
- if (clean && store->engine->state != CAMEL_IMAP4_ENGINE_DISCONNECTED) {
+ if (clean && !store->engine->istream->disconnected) {
ic = camel_imap4_engine_queue (store->engine, NULL, "LOGOUT\r\n");
while ((id = camel_imap4_engine_iterate (store->engine)) < ic->id && id != -1)
;
camel_imap4_command_unref (ic);
}
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
return 0;
}
@@ -572,9 +522,6 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
GList *sasl_types, *t, *next;
gboolean connected;
- if (!camel_session_is_online (service->session))
- return NULL;
-
CAMEL_SERVICE_LOCK (store, connect_lock);
connected = connect_to_server_wrapper (store->engine, ex);
CAMEL_SERVICE_UNLOCK (store, connect_lock);
@@ -595,30 +542,83 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
return g_list_prepend (sasl_types, &camel_imap4_password_authtype);
}
+
+static char
+imap4_get_path_delim (CamelIMAP4Engine *engine, const char *full_name)
+{
+ /* FIXME: move this to utils so imap4-folder.c can share */
+ CamelIMAP4Namespace *namespace;
+ const char *slash;
+ size_t len;
+ char *top;
+
+ if ((slash = strchr (full_name, '/')))
+ len = (slash - full_name);
+ else
+ len = strlen (full_name);
+
+ top = g_alloca (len + 1);
+ memcpy (top, full_name, len);
+ top[len] = '\0';
+
+ if (!g_ascii_strcasecmp (top, "INBOX"))
+ top = "INBOX";
+
+ retry:
+ namespace = engine->namespaces.personal;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ namespace = engine->namespaces.other;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ namespace = engine->namespaces.shared;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ if (top[0] != '\0') {
+ /* look for a default namespace? */
+ top[0] = '\0';
+ goto retry;
+ }
+
+ return '/';
+}
+
static char *
imap4_folder_utf7_name (CamelStore *store, const char *folder_name, char wildcard)
{
char *real_name, *p;
- char sep = '\0';
+ char sep;
int len;
- if (*folder_name) {
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, folder_name);
-
- if (sep != '/') {
- p = real_name = g_alloca (strlen (folder_name) + 1);
- strcpy (real_name, folder_name);
- while (*p != '\0') {
- if (*p == '/')
- *p = sep;
- p++;
- }
-
- folder_name = real_name;
+ sep = imap4_get_path_delim (((CamelIMAP4Store *) store)->engine, folder_name);
+
+ if (sep != '/') {
+ p = real_name = g_alloca (strlen (folder_name) + 1);
+ strcpy (real_name, folder_name);
+ while (*p != '\0') {
+ if (*p == '/')
+ *p = sep;
+ p++;
}
+ folder_name = real_name;
+ }
+
+ if (*folder_name)
real_name = camel_utf8_utf7 (folder_name);
- } else
+ else
real_name = g_strdup ("");
if (wildcard) {
@@ -639,7 +639,6 @@ static CamelFolder *
imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *folder = NULL;
camel_imap4_list_t *list;
CamelIMAP4Command *ic;
@@ -651,18 +650,6 @@ imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Cam
CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!camel_session_is_online (session)) {
- if ((flags & CAMEL_STORE_FOLDER_CREATE) != 0) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- } else {
- folder = camel_imap4_folder_new (store, folder_name, ex);
- }
-
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
-
- return folder;
- }
-
/* make sure the folder exists - try LISTing it? */
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "LIST \"\" %S\r\n", utf7_name);
@@ -740,7 +727,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
* contain subfolders - delete them and re-create with the
* proper hint */
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolderInfo *fi = NULL;
CamelIMAP4Command *ic;
char *utf7_name;
@@ -750,7 +736,7 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
char sep;
int id;
- sep = camel_imap4_get_path_delim (((CamelIMAP4Store *) store)->summary, parent_name);
+ sep = imap4_get_path_delim (engine, parent_name);
c = folder_name;
while (*c != '\0') {
@@ -765,11 +751,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
c++;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create IMAP folders in offline mode."));
- return NULL;
- }
-
if (parent_name != NULL && *parent_name)
name = g_strdup_printf ("%s/%s", parent_name, folder_name);
else
@@ -807,8 +788,6 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_created", fi);
break;
case CAMEL_IMAP4_RESULT_NO:
@@ -841,7 +820,6 @@ static void
imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *selected = (CamelFolder *) engine->folder;
CamelIMAP4Command *ic, *ic0 = NULL;
CamelFolderInfo *fi;
@@ -858,11 +836,6 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
return;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot delete IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
if (selected && !strcmp (folder_name, selected->full_name))
@@ -909,8 +882,6 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_deleted", fi);
camel_folder_info_free (fi);
@@ -937,7 +908,6 @@ static void
imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
char *old_uname, *new_uname;
CamelIMAP4Command *ic;
int id;
@@ -950,11 +920,6 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
return;
}
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
old_uname = imap4_folder_utf7_name (store, old_name, '\0');
@@ -977,7 +942,6 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
switch (ic->result) {
case CAMEL_IMAP4_RESULT_OK:
/* FIXME: need to update state on the renamed folder object */
- /* FIXME: need to update cached summary info too */
break;
case CAMEL_IMAP4_RESULT_NO:
/* FIXME: would be good to save the NO reason into the err message */
@@ -1091,11 +1055,6 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
url = camel_url_copy (engine->url);
- if (!strcmp (top, "") && (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)) {
- /* clear the folder-info cache */
- camel_store_summary_clear ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
- }
-
for (i = 0; i < array->len; i++) {
list = array->pdata[i];
fi = g_malloc0 (sizeof (CamelFolderInfo));
@@ -1116,20 +1075,34 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
fi->flags = list->flags;
fi->unread = -1;
fi->total = -1;
-
- /* SELECTED folder, just get it from the folder */
- if (folder && !strcmp (folder->full_name, fi->full_name)) {
- camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &fi->total, CAMEL_FOLDER_UNREAD, &fi->unread, 0);
- } else if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
- imap4_status (store, fi);
+
+ if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) {
+ if (folder && !strcmp (folder->full_name, fi->full_name)) {
+ /* can't STATUS this folder since it is SELECTED, besides - it would be wasteful */
+ CamelMessageInfo *info;
+ int index;
+
+ fi->total = camel_folder_summary_count (folder->summary);
+
+ fi->unread = 0;
+ for (index = 0; index < fi->total; index++) {
+ if (!(info = camel_folder_summary_index (folder->summary, index)))
+ continue;
+
+ if ((info->flags & CAMEL_MESSAGE_SEEN) == 0)
+ fi->unread++;
+
+ camel_folder_summary_info_free (folder->summary, info);
+ }
+ } else {
+ imap4_status (store, fi);
+ }
}
g_free (list->name);
g_free (list);
array->pdata[i] = fi;
-
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
}
fi = camel_folder_info_build (array, top, '/', TRUE);
@@ -1138,8 +1111,6 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr
g_ptr_array_free (array, TRUE);
- camel_store_summary_save ((CamelStoreSummary *) ((CamelIMAP4Store *) store)->summary);
-
return fi;
}
@@ -1147,7 +1118,6 @@ static CamelFolderInfo *
imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic, *ic0 = NULL;
CamelFolderInfo *fi = NULL;
camel_imap4_list_t *list;
@@ -1157,30 +1127,23 @@ imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelE
char wildcard;
int id, i;
- if (top == NULL)
- top = "";
-
CAMEL_SERVICE_LOCK (store, connect_lock);
- if (!camel_session_is_online (session) || engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
- fi = camel_imap4_store_summary_get_folder_info (((CamelIMAP4Store *) store)->summary, top, flags);
- if (fi == NULL && camel_session_is_online (session)) {
- /* folder info hasn't yet been cached and the store hasn't been
- * connected yet, but the network is available so we can connect
- * and query the server. */
- goto check_online;
- }
- CAMEL_SERVICE_UNLOCK (store, connect_lock);
- return fi;
+ if (engine->state == CAMEL_IMAP4_ENGINE_DISCONNECTED) {
+ if (!camel_service_connect ((CamelService *) store, ex))
+ return NULL;
+
+ engine = ((CamelIMAP4Store *) store)->engine;
}
- check_online:
-
if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
cmd = "LSUB";
else
cmd = "LIST";
+ if (top == NULL)
+ top = "";
+
wildcard = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? '*' : '%';
pattern = imap4_folder_utf7_name (store, top, wildcard);
array = g_ptr_array_new ();
@@ -1268,7 +1231,6 @@ static void
imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic;
CamelFolderInfo *fi;
char *utf7_name;
@@ -1276,11 +1238,6 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
const char *p;
int id;
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot subscribe to IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
@@ -1314,8 +1271,6 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_note_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_subscribed", fi);
camel_folder_info_free (fi);
break;
@@ -1341,7 +1296,6 @@ static void
imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelIMAP4Command *ic;
CamelFolderInfo *fi;
char *utf7_name;
@@ -1349,11 +1303,6 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
const char *p;
int id;
- if (!camel_session_is_online (session)) {
- camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot unsubscribe from IMAP folders in offline mode."));
- return;
- }
-
CAMEL_SERVICE_LOCK (store, connect_lock);
utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
@@ -1387,8 +1336,6 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
fi->unread = -1;
fi->total = -1;
- camel_imap4_store_summary_unnote_info (((CamelIMAP4Store *) store)->summary, fi);
-
camel_object_trigger_event (store, "folder_unsubscribed", fi);
camel_folder_info_free (fi);
break;
@@ -1414,14 +1361,10 @@ static void
imap4_noop (CamelStore *store, CamelException *ex)
{
CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
- CamelSession *session = ((CamelService *) store)->session;
CamelFolder *folder = (CamelFolder *) engine->folder;
CamelIMAP4Command *ic;
int id;
- if (!camel_session_is_online (session))
- return;
-
CAMEL_SERVICE_LOCK (store, connect_lock);
if (folder) {
diff --git a/camel/providers/imapp/camel-imapp-store.c b/camel/providers/imapp/camel-imapp-store.c
index 03f835da7a..c1c9f50649 100644
--- a/camel/providers/imapp/camel-imapp-store.c
+++ b/camel/providers/imapp/camel-imapp-store.c
@@ -48,7 +48,6 @@
#ifdef HAVE_SSL
#include "camel/camel-tcp-stream-ssl.h"
#endif
-#include "camel/camel-i18n.h"
#include "camel-imapp-store-summary.h"
#include "camel-imapp-store.h"
@@ -57,7 +56,6 @@
#include "camel-imapp-exception.h"
#include "camel-imapp-utils.h"
#include "camel-imapp-driver.h"
-#include "camel-net-utils.h"
/* Specified in RFC 2060 section 2.1 */
#define IMAP_PORT 143
@@ -811,7 +809,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
if (strcmp(finfo->uid, camel_message_info_uid(info)) != 0) {
printf("summary at index %d has uid %s expected %s\n", id, camel_message_info_uid(info), finfo->uid);
/* uid mismatch??? try do it based on uid instead? try to reorder? i dont know? */
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
info = camel_folder_summary_uid(((CamelFolder *)istore->selected)->summary, finfo->uid);
}
}
@@ -860,7 +858,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
CamelMimeParser *mp;
if (pending == NULL)
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
mp = camel_mime_parser_new();
camel_mime_parser_init_with_stream(mp, finfo->header);
info = camel_folder_summary_info_new_from_parser(((CamelFolder *)istore->selected)->summary, mp);
@@ -873,7 +871,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
/* FIXME: use a dlist */
e_dlist_remove((EDListNode *)pending);
g_hash_table_remove(istore->pending_fetch_table, camel_message_info_uid(pending->info));
- camel_message_info_free(pending->info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, pending->info);
/*e_memchunk_free(istore->pending_fetch_chunks, pending);*/
}
} else if (finfo->got & FETCH_FLAGS) {
@@ -885,7 +883,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data)
}
} else {
if (pending == NULL)
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
printf("got unexpected fetch response?\n");
imap_dump_fetch(finfo);
}
@@ -975,7 +973,7 @@ camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *fold
if (info) {
printf("message info [%d] =\n", i);
camel_message_info_dump(info);
- camel_message_info_free(info);
+ camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info);
}
}
} CAMEL_CATCH (e) {
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index 70673d9687..b86d23221a 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -20,6 +20,7 @@
*
*/
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -47,7 +48,6 @@
#include "camel-stream-filter.h"
#include "camel-mime-filter-from.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#include "camel-local-private.h"
diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c
index b74f6e5ace..ba42b75f28 100644
--- a/camel/providers/local/camel-maildir-folder.c
+++ b/camel/providers/local/camel-maildir-folder.c
@@ -39,7 +39,6 @@
#include "camel-data-wrapper.h"
#include "camel-mime-message.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -153,7 +152,7 @@ camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint3
static CamelLocalSummary *maildir_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_maildir_summary_new((CamelFolder *)lf, path, folder, index);
+ return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index);
}
static void
@@ -251,7 +250,7 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar *
/* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */
name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi));
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c
index d213b444fc..fa8f0b645d 100644
--- a/camel/providers/local/camel-mbox-folder.c
+++ b/camel/providers/local/camel-mbox-folder.c
@@ -42,7 +42,6 @@
#include "camel-stream-filter.h"
#include "camel-mime-filter-from.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -56,6 +55,13 @@ static CamelLocalFolderClass *parent_class = NULL;
static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex);
static void mbox_unlock(CamelLocalFolder *lf);
+#ifdef STATUS_PINE
+static gboolean mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set);
+#endif
+
+static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value);
+static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value);
+
static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex);
static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex);
static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index);
@@ -76,6 +82,12 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class)
camel_folder_class->append_message = mbox_append_message;
camel_folder_class->get_message = mbox_get_message;
+#ifdef STATUS_PINE
+ camel_folder_class->set_message_flags = mbox_set_message_flags;
+#endif
+ camel_folder_class->set_message_user_flag = mbox_set_message_user_flag;
+ camel_folder_class->set_message_user_tag = mbox_set_message_user_tag;
+
lclass->get_full_path = camel_mbox_folder_get_full_path;
lclass->get_meta_path = camel_mbox_folder_get_meta_path;
lclass->create_summary = mbox_create_summary;
@@ -194,7 +206,7 @@ camel_mbox_folder_get_meta_path (CamelLocalFolder *lf, const char *toplevel_dir,
static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_mbox_summary_new((CamelFolder *)lf, path, folder, index);
+ return (CamelLocalSummary *)camel_mbox_summary_new(path, folder, index);
}
static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex)
@@ -408,7 +420,7 @@ retry:
g_assert(info->frompos != -1);
frompos = info->frompos;
- camel_message_info_free((CamelMessageInfo *)info);
+ camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info);
/* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache
the whole message in memory if the stream is non-seekable (which it is when built from a parser
@@ -480,3 +492,66 @@ fail:
return message;
}
+
+#ifdef STATUS_PINE
+static gboolean
+mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set)
+{
+ /* Basically, if anything could change the Status line, presume it does */
+ if (((CamelMboxSummary *)folder->summary)->xstatus
+ && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) {
+ flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
+ set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED;
+ }
+
+ return ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set);
+}
+#endif
+
+static void
+mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value)
+{
+ CamelMessageInfo *info;
+
+ g_return_if_fail(folder->summary != NULL);
+
+ info = camel_folder_summary_uid(folder->summary, uid);
+ if (info == NULL)
+ return;
+
+ if (camel_flag_set(&info->user_flags, name, value)) {
+ CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+ info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
+ camel_folder_summary_touch(folder->summary);
+
+ camel_folder_change_info_change_uid(changes, uid);
+ camel_object_trigger_event(folder, "folder_changed", changes);
+ camel_folder_change_info_free(changes);
+ }
+ camel_folder_summary_info_free(folder->summary, info);
+}
+
+static void
+mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value)
+{
+ CamelMessageInfo *info;
+
+ g_return_if_fail(folder->summary != NULL);
+
+ info = camel_folder_summary_uid(folder->summary, uid);
+ if (info == NULL)
+ return;
+
+ if (camel_tag_set(&info->user_tags, name, value)) {
+ CamelFolderChangeInfo *changes = camel_folder_change_info_new();
+
+ info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE;
+ camel_folder_summary_touch(folder->summary);
+
+ camel_folder_change_info_change_uid(changes, uid);
+ camel_object_trigger_event (folder, "folder_changed", changes);
+ camel_folder_change_info_free(changes);
+ }
+ camel_folder_summary_info_free(folder->summary, info);
+}
diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c
index a9e581cdd7..1277407dbb 100644
--- a/camel/providers/local/camel-mbox-store.c
+++ b/camel/providers/local/camel-mbox-store.c
@@ -37,7 +37,6 @@
#include "camel-text-index.h"
#include "camel-exception.h"
#include "camel-url.h"
-#include "camel-i18n.h"
#define d(x)
@@ -618,7 +617,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
path = camel_mbox_folder_get_meta_path(NULL, root, fi->full_name, ".ev-summary");
folderpath = camel_mbox_folder_get_full_path(NULL, root, fi->full_name);
- mbs = (CamelMboxSummary *)camel_mbox_summary_new(NULL, path, folderpath, NULL);
+ mbs = (CamelMboxSummary *)camel_mbox_summary_new(path, folderpath, NULL);
if (camel_folder_summary_header_load((CamelFolderSummary *)mbs) != -1) {
fi->unread = ((CamelFolderSummary *)mbs)->unread_count;
fi->total = ((CamelFolderSummary *)mbs)->saved_count;
diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c
index 1b054a4547..78456b6daf 100644
--- a/camel/providers/local/camel-mh-folder.c
+++ b/camel/providers/local/camel-mh-folder.c
@@ -39,7 +39,6 @@
#include "camel-data-wrapper.h"
#include "camel-mime-message.h"
#include "camel-exception.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -117,7 +116,7 @@ camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 fla
static CamelLocalSummary *mh_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_mh_summary_new((CamelFolder *)lf, path, folder, index);
+ return (CamelLocalSummary *)camel_mh_summary_new(path, folder, index);
}
static void
@@ -205,7 +204,7 @@ static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid,
}
/* we only need it to check the message exists */
- camel_message_info_free(info);
+ camel_folder_summary_info_free(folder->summary, info);
name = g_strdup_printf("%s/%s", lf->folder_path, uid);
if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) {
diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c
index c4c7da91b6..6a1bbf798a 100644
--- a/camel/providers/local/camel-spool-folder.c
+++ b/camel/providers/local/camel-spool-folder.c
@@ -44,8 +44,8 @@
#include "camel-session.h"
#include "camel-file-utils.h"
#include "camel-lock-client.h"
+
#include "camel-local-private.h"
-#include "camel-i18n.h"
#define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
@@ -160,7 +160,7 @@ spool_get_meta_path(CamelLocalFolder *lf, const char *toplevel_dir, const char *
static CamelLocalSummary *
spool_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index)
{
- return (CamelLocalSummary *)camel_spool_summary_new((CamelFolder *)lf, folder);
+ return (CamelLocalSummary *)camel_spool_summary_new(folder);
}
static int
diff --git a/camel/providers/local/camel-spool-store.c b/camel/providers/local/camel-spool-store.c
index 3dc21886c8..2e3d9ea777 100644
--- a/camel/providers/local/camel-spool-store.c
+++ b/camel/providers/local/camel-spool-store.c
@@ -41,7 +41,6 @@
#include "camel-exception.h"
#include "camel-url.h"
#include "camel-private.h"
-#include "camel-i18n.h"
#define d(x)
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index de0f4cd222..ffb1b29742 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -49,7 +49,6 @@
#include "camel/camel-multipart.h"
#include "camel/camel-mime-part.h"
#include "camel/camel-stream-buffer.h"
-#include "camel/camel-i18n.h"
#include "camel/camel-private.h"
#include "camel-nntp-summary.h"
@@ -511,7 +510,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti
g_free(root);
root = g_strdup_printf("%s.ev-summary", nntp_folder->storage_path);
- folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder, root);
+ folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (root);
g_free(root);
camel_folder_summary_load (folder->summary);
diff --git a/camel/providers/nntp/camel-nntp-private.h b/camel/providers/nntp/camel-nntp-private.h
index 520c9db134..253d4e2031 100644
--- a/camel/providers/nntp/camel-nntp-private.h
+++ b/camel/providers/nntp/camel-nntp-private.h
@@ -35,7 +35,7 @@ extern "C" {
#include <config.h>
#endif
-#include "libedataserver/e-msgport.h"
+#include "e-util/e-msgport.h"
struct _CamelNNTPStorePrivate {
int dummy;
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index f9daad8515..3e911ec1c5 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -53,8 +53,6 @@
#include "camel-nntp-folder.h"
#include "camel-nntp-private.h"
#include "camel-nntp-resp-codes.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
#define w(x)
#define dd(x) (camel_debug("nntp")?(x):0)
@@ -85,6 +83,12 @@ nntp_can_work_offline(CamelDiscoStore *store)
return TRUE;
}
+enum {
+ USE_SSL_NEVER,
+ USE_SSL_ALWAYS,
+ USE_SSL_WHEN_POSSIBLE
+};
+
static struct {
const char *name;
int type;
@@ -149,17 +153,8 @@ xover_setup(CamelNNTPStore *store, CamelException *ex)
return ret;
}
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
-#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
-#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
-
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int ssl_mode, CamelException *ex)
{
CamelNNTPStore *store = (CamelNNTPStore *) service;
CamelDiscoStore *disco_store = (CamelDiscoStore*) service;
@@ -169,6 +164,9 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
unsigned int len;
int ret;
char *path;
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
CAMEL_SERVICE_LOCK(store, connect_lock);
@@ -185,34 +183,50 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
camel_data_cache_set_expire_age (store->cache, 60*60*24*14);
camel_data_cache_set_expire_access (store->cache, 60*60*24*5);
}
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "nntp";
+ port = NNTP_PORT;
+ }
- if (ssl_mode != MODE_CLEAR) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
- } else {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
+ if (ssl_mode != USE_SSL_NEVER) {
+ if (service->url->port == 0) {
+ serv = "nntps";
+ port = NNTPS_PORT;
}
-#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
-
- goto fail;
-#endif /* HAVE_SSL */
+ tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3);
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+#else
+ tcp_stream = camel_tcp_stream_raw_new ();
+#endif /* HAVE_SSL */
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ goto fail;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
if (errno == EINTR)
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("Connection cancelled"));
else
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv, g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -254,11 +268,11 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
if (service->url->user != NULL
&& camel_nntp_try_authenticate(store, ex) != NNTP_AUTH_ACCEPTED)
goto fail;
-
- /* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */
+
+ /* set 'reader' mode & ignore return code, also ping the server, inn goes offline very quickly otherwise */
if (camel_nntp_raw_command_auth (store, ex, (char **) &buf, "mode reader") == -1
|| camel_nntp_raw_command_auth (store, ex, (char **) &buf, "date") == -1)
- goto fail;
+ goto fail;
if (xover_setup(store, ex) == -1)
goto fail;
@@ -279,61 +293,54 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
static struct {
char *value;
- char *serv;
- char *port;
int mode;
} ssl_options[] = {
- { "", "nntps", NNTPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "nntps", NNTPS_PORT, MODE_SSL },
- { "when-possible", "nntp", NNTP_PORT, MODE_TLS },
- { "never", "nntp", NNTP_PORT, MODE_CLEAR },
- { NULL, "nntp", NNTP_PORT, MODE_CLEAR },
+ { "", USE_SSL_ALWAYS },
+ { "always", USE_SSL_ALWAYS },
+ { "when-possible", USE_SSL_WHEN_POSSIBLE },
+ { "never", USE_SSL_NEVER },
+ { NULL, USE_SSL_NEVER },
};
static gboolean
nntp_connect_online (CamelService *service, CamelException *ex)
{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
+#ifdef HAVE_SSL
+ const char *use_ssl;
+ int i, ssl_mode;
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
+ use_ssl = camel_url_get_param (service->url, "use_ssl");
+ if (use_ssl) {
for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
+ if (!strcmp (ssl_options[i].value, use_ssl))
break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
+ ssl_mode = ssl_options[i].mode;
+ } else
+ ssl_mode = USE_SSL_NEVER;
+
+ if (ssl_mode == USE_SSL_ALWAYS) {
+ /* Connect via SSL */
+ return connect_to_server (service, ssl_mode, ex);
+ } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports SSL, use it */
+ if (!connect_to_server (service, ssl_mode, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* The ssl port seems to be unavailable, fall back to plain NNTP */
+ camel_exception_clear (ex);
+ return connect_to_server (service, USE_SSL_NEVER, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
} else {
- mode = MODE_CLEAR;
- serv = "nntp";
- port = NNTP_PORT;
+ /* User doesn't care about SSL */
+ return connect_to_server (service, ssl_mode, ex);
}
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- ret = connect_to_server (service, ai, mode, ex);
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, USE_SSL_NEVER, ex);
+#endif
}
static gboolean
diff --git a/camel/providers/nntp/camel-nntp-stream.c b/camel/providers/nntp/camel-nntp-stream.c
index 244b67acb1..74bee9ced5 100644
--- a/camel/providers/nntp/camel-nntp-stream.c
+++ b/camel/providers/nntp/camel-nntp-stream.c
@@ -60,8 +60,6 @@ stream_fill(CamelNNTPStream *is)
is->end[0] = '\n';
return is->end - is->ptr;
} else {
- if (left == 0)
- errno = ECONNRESET;
dd(printf("NNTP_STREAM_FILL(ERROR): %d - '%s'\n", left, strerror(errno)));
return -1;
}
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index e6c02b95af..02589e632e 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -36,7 +36,6 @@
#include "camel/camel-stream-null.h"
#include "camel/camel-operation.h"
#include "camel/camel-data-cache.h"
-#include "camel/camel-i18n.h"
#include "camel/camel-debug.h"
#include "camel-nntp-summary.h"
@@ -60,7 +59,7 @@ struct _CamelNNTPSummaryPrivate {
#define _PRIVATE(o) (((CamelNNTPSummary *)(o))->priv)
-static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
+static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *);
static int summary_header_load(CamelFolderSummary *, FILE *);
static int summary_header_save(CamelFolderSummary *, FILE *);
@@ -94,7 +93,7 @@ camel_nntp_summary_class_init(CamelNNTPSummaryClass *klass)
camel_nntp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type()));
- sklass->message_info_new_from_header = message_info_new_from_header;
+ sklass->message_info_new = message_info_new;
sklass->summary_header_load = summary_header_load;
sklass->summary_header_save = summary_header_save;
}
@@ -108,7 +107,7 @@ camel_nntp_summary_init(CamelNNTPSummary *obj)
p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
/* subclasses need to set the right instance data sizes */
- s->message_info_size = sizeof(CamelMessageInfoBase);
+ s->message_info_size = sizeof(CamelMessageInfo);
s->content_info_size = sizeof(CamelMessageContentInfo);
/* and a unique file version */
@@ -124,12 +123,10 @@ camel_nntp_summary_finalise(CamelObject *obj)
}
CamelNNTPSummary *
-camel_nntp_summary_new(struct _CamelFolder *folder, const char *path)
+camel_nntp_summary_new(const char *path)
{
CamelNNTPSummary *cns = (CamelNNTPSummary *)camel_object_new(camel_nntp_summary_get_type());
- ((CamelFolderSummary *)cns)->folder = folder;
-
camel_folder_summary_set_filename((CamelFolderSummary *)cns, path);
camel_folder_summary_set_build_content((CamelFolderSummary *)cns, FALSE);
@@ -137,9 +134,9 @@ camel_nntp_summary_new(struct _CamelFolder *folder, const char *path)
}
static CamelMessageInfo *
-message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
+message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h)
{
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
CamelNNTPSummary *cns = (CamelNNTPSummary *)s;
/* error to call without this setup */
@@ -149,13 +146,13 @@ message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h)
/* we shouldn't be here if we already have this uid */
g_assert(camel_folder_summary_uid(s, cns->priv->uid) == NULL);
- mi = (CamelMessageInfoBase *)((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new_from_header(s, h);
+ mi = ((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new(s, h);
if (mi) {
- mi->uid = g_strdup(cns->priv->uid);
+ camel_message_info_set_uid(mi, cns->priv->uid);
cns->priv->uid = NULL;
}
- return (CamelMessageInfo *)mi;
+ return mi;
}
static int
@@ -209,7 +206,7 @@ static int
add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex)
{
CamelFolderSummary *s;
- CamelMessageInfoBase *mi;
+ CamelMessageInfo *mi;
struct _camel_header_raw *headers = NULL;
char *line, *tab;
int len, ret;
@@ -273,16 +270,16 @@ add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high,
/* truncated line? ignore? */
if (xover == NULL) {
- mi = (CamelMessageInfoBase *)camel_folder_summary_uid(s, cns->priv->uid);
+ mi = camel_folder_summary_uid(s, cns->priv->uid);
if (mi == NULL) {
- mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header(s, headers);
+ mi = camel_folder_summary_add_from_header(s, headers);
if (mi) {
mi->size = size;
cns->high = n;
camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
}
} else {
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
}
@@ -354,7 +351,7 @@ add_range_head(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high,
camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi));
} else {
/* already have, ignore */
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
if (cns->priv->uid) {
g_free(cns->priv->uid);
@@ -447,7 +444,7 @@ camel_nntp_summary_check(CamelNNTPSummary *cns, CamelNNTPStore *store, char *lin
i--;
}
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
}
cns->low = f;
@@ -475,12 +472,12 @@ update:
count = camel_folder_summary_count(s);
for (i = 0; i < count; i++) {
- CamelMessageInfoBase *mi = (CamelMessageInfoBase *)camel_folder_summary_index(s, i);
+ CamelMessageInfo *mi = camel_folder_summary_index(s, i);
if (mi) {
if ((mi->flags & CAMEL_MESSAGE_SEEN) == 0)
unread++;
- camel_message_info_free(mi);
+ camel_folder_summary_info_free(s, mi);
}
}
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 46a1fd3fe6..f7117b1b31 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -45,7 +45,7 @@
#include "camel-session.h"
#include "camel-exception.h"
#include "camel-url.h"
-#include "libedataserver/md5-utils.h"
+#include "e-util/md5-utils.h"
#include "camel-pop3-engine.h"
#include "camel-sasl.h"
#include "camel-data-cache.h"
@@ -54,12 +54,9 @@
#ifdef HAVE_SSL
#include "camel-tcp-stream-ssl.h"
#endif
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
/* Specified in RFC 1939 */
-#define POP3_PORT "110"
-#define POP3S_PORT "995"
+#define POP3_PORT 110
static CamelStoreClass *parent_class = NULL;
@@ -137,16 +134,16 @@ finalize (CamelObject *object)
}
enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
+ USE_SSL_NEVER,
+ USE_SSL_ALWAYS,
+ USE_SSL_WHEN_POSSIBLE
};
#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelException *ex)
{
CamelPOP3Store *store = CAMEL_POP3_STORE (service);
CamelStream *tcp_stream;
@@ -154,34 +151,67 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
guint32 flags = 0;
int clean_quit;
int ret;
-
- if (ssl_mode != MODE_CLEAR) {
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "pop3";
+ port = "110";
+ }
+
+ if (ssl_mode != USE_SSL_NEVER) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
+ if (try_starttls) {
tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
} else {
+ if (service->url->port == 0) {
+ serv = "pop3s";
+ port = "995";
+ }
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
#else
+ if (!try_starttls && service->url->port == 0) {
+ serv = "pop3s";
+ port = "995";
+ }
+
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ _("SSL unavailable"));
return FALSE;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ return FALSE;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
if (errno == EINTR)
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("Connection cancelled"));
else
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host,
- g_strerror (errno));
+ _("Could not connect to POP server %s (port %s): %s"),
+ service->url->host, serv, g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -199,24 +229,41 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
if (!(store->engine = camel_pop3_engine_new (tcp_stream, flags))) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to read a valid greeting from POP server %s"),
- service->url->host);
- camel_object_unref (tcp_stream);
+ _("Failed to read a valid greeting from POP server %s (port %s)"),
+ service->url->host, serv);
return FALSE;
}
- if (ssl_mode != MODE_TLS) {
- camel_object_unref (tcp_stream);
- return TRUE;
+#ifdef HAVE_SSL
+ if (store->engine) {
+ if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ if (store->engine->capa & CAMEL_POP3_CAP_STLS)
+ goto starttls;
+ } else if (ssl_mode == USE_SSL_ALWAYS) {
+ if (try_starttls) {
+ if (store->engine->capa & CAMEL_POP3_CAP_STLS) {
+ /* attempt to toggle STARTTLS mode */
+ goto starttls;
+ } else {
+ /* server doesn't support STARTTLS, abort */
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to connect to POP server %s in secure mode: %s"),
+ service->url->host, _("SSL/TLS extension not supported."));
+ /* we have the possibility of quitting cleanly here */
+ clean_quit = TRUE;
+ goto stls_exception;
+ }
+ }
+ }
}
+#endif /* HAVE_SSL */
- if (!(store->engine->capa & CAMEL_POP3_CAP_STLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to POP server %s in secure mode: %s"),
- service->url->host, _("STLS not supported"));
- goto stls_exception;
- }
+ camel_object_unref (tcp_stream);
+ return store->engine != NULL;
+
+#ifdef HAVE_SSL
+ starttls:
/* as soon as we send a STLS command, all hope is lost of a clean QUIT if problems arise */
clean_quit = FALSE;
@@ -237,6 +284,8 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
/* Okay, now toggle SSL/TLS mode */
ret = camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream));
+ camel_object_unref (CAMEL_OBJECT (tcp_stream));
+
if (ret == -1) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("Failed to connect to POP server %s in secure mode: %s"),
@@ -244,8 +293,6 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
goto stls_exception;
}
- camel_object_unref (tcp_stream);
-
/* rfc2595, section 4 states that after a successful STLS
command, the client MUST discard prior CAPA responses */
camel_pop3_engine_reget_capabilities (store->engine);
@@ -266,71 +313,59 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
store->engine = NULL;
return FALSE;
+#endif /* HAVE_SSL */
}
static struct {
char *value;
- char *serv;
- char *port;
int mode;
} ssl_options[] = {
- { "", "pop3s", POP3S_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "pop3s", POP3S_PORT, MODE_SSL },
- { "when-possible", "pop3", POP3_PORT, MODE_TLS },
- { "never", "pop3", POP3_PORT, MODE_CLEAR },
- { NULL, "pop3", POP3_PORT, MODE_CLEAR },
+ { "", USE_SSL_ALWAYS },
+ { "always", USE_SSL_ALWAYS },
+ { "when-possible", USE_SSL_WHEN_POSSIBLE },
+ { "never", USE_SSL_NEVER },
+ { NULL, USE_SSL_NEVER },
};
static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
+#ifdef HAVE_SSL
+ const char *use_ssl;
+ int i, ssl_mode;
+
+ use_ssl = camel_url_get_param (service->url, "use_ssl");
+ if (use_ssl) {
for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
+ if (!strcmp (ssl_options[i].value, use_ssl))
break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
+ ssl_mode = ssl_options[i].mode;
+ } else
+ ssl_mode = USE_SSL_NEVER;
+
+ if (ssl_mode == USE_SSL_ALWAYS) {
+ /* First try the ssl port */
+ if (!connect_to_server (service, ssl_mode, FALSE, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* The ssl port seems to be unavailable, lets try STARTTLS */
+ camel_exception_clear (ex);
+ return connect_to_server (service, ssl_mode, TRUE, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (ssl_mode == USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports STARTTLS, use it */
+ return connect_to_server (service, ssl_mode, TRUE, ex);
} else {
- mode = MODE_CLEAR;
- serv = "pop3";
- port = POP3S_PORT;
+ /* User doesn't care about SSL */
+ return connect_to_server (service, ssl_mode, FALSE, ex);
}
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
- }
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- } else if (!ret && mode == MODE_TLS) {
- camel_exception_clear (ex);
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
- }
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, USE_SSL_NEVER, FALSE, ex);
+#endif
}
extern CamelServiceAuthType camel_pop3_password_authtype;
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index 065d79fdac..ea8ca26e49 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -55,15 +55,13 @@
#include "camel-session.h"
#include "camel-exception.h"
#include "camel-sasl.h"
-#include "camel-i18n.h"
-#include "camel-net-utils.h"
+
extern int camel_verbose_debug;
#define d(x) (camel_verbose_debug ? (x) : 0)
/* Specified in RFC 821 */
-#define SMTP_PORT "25"
-#define SMTPS_PORT "465"
+#define SMTP_PORT 25
/* camel smtp transport class prototypes */
static gboolean smtp_send_to (CamelTransport *transport, CamelMimeMessage *message,
@@ -147,7 +145,18 @@ smtp_construct (CamelService *service, CamelSession *session,
CamelProvider *provider, CamelURL *url,
CamelException *ex)
{
+ CamelSmtpTransport *smtp_transport = CAMEL_SMTP_TRANSPORT (service);
+ const char *use_ssl;
+
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
+
+ if ((use_ssl = camel_url_get_param (url, "use_ssl"))) {
+ /* Note: previous versions would use "" to toggle use_ssl to 'on' */
+ if (!*use_ssl || !strcmp (use_ssl, "always"))
+ smtp_transport->flags |= CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS;
+ else if (!strcmp (use_ssl, "when-possible"))
+ smtp_transport->flags |= CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE;
+ }
}
static const char *
@@ -219,56 +228,82 @@ smtp_error_string (int error)
}
}
-enum {
- MODE_CLEAR,
- MODE_SSL,
- MODE_TLS,
-};
-
#define SSL_PORT_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 | CAMEL_TCP_STREAM_SSL_ENABLE_SSL3)
#define STARTTLS_FLAGS (CAMEL_TCP_STREAM_SSL_ENABLE_TLS)
static gboolean
-connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, CamelException *ex)
+connect_to_server (CamelService *service, int try_starttls, CamelException *ex)
{
CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
CamelStream *tcp_stream;
char *respbuf = NULL;
int ret;
+ struct addrinfo *ai, hints = { 0 };
+ char *serv;
+ const char *port = NULL;
if (!CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex))
return FALSE;
/* set some smtp transport defaults */
- transport->flags = 0;
+ transport->flags &= CAMEL_SMTP_TRANSPORT_USE_SSL; /* reset all but ssl flags */
transport->authtypes = NULL;
+
+ if (service->url->port) {
+ serv = g_alloca(16);
+ sprintf(serv, "%d", service->url->port);
+ } else {
+ serv = "smtp";
+ port = "25";
+ }
- if (ssl_mode != MODE_CLEAR) {
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL) {
#ifdef HAVE_SSL
- if (ssl_mode == MODE_TLS) {
- tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, STARTTLS_FLAGS);
+ if (try_starttls) {
+ tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS);
} else {
+ if (service->url->port == 0) {
+ serv = "smtps";
+ port = "465";
+ }
tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS);
}
#else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, _("SSL unavailable"));
+ if (!try_starttls && service->url->port == 0) {
+ serv = "smtps";
+ port = "465";
+ }
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ _("SSL unavailable"));
+
return FALSE;
#endif /* HAVE_SSL */
} else {
tcp_stream = camel_tcp_stream_raw_new ();
}
+
+ hints.ai_socktype = SOCK_STREAM;
+ ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
+ /* fallback to numerical port if the system is misconfigured */
+ if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
+ camel_exception_clear(ex);
+ ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ }
+ if (ai == NULL) {
+ camel_object_unref(tcp_stream);
+ return FALSE;
+ }
- if ((ret = camel_tcp_stream_connect ((CamelTcpStream *) tcp_stream, ai)) == -1) {
- if (errno == EINTR)
- camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
- _("Connection cancelled"));
- else
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- _("Could not connect to %s: %s"),
- service->url->host, g_strerror (errno));
+ ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
+ camel_freeaddrinfo(ai);
+ if (ret == -1) {
+ camel_exception_setv (ex, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ _("Could not connect to %s (port %s): %s"),
+ service->url->host, serv,
+ g_strerror (errno));
camel_object_unref (tcp_stream);
@@ -312,19 +347,30 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
/* clear any EHLO/HELO exception and assume that any SMTP errors encountered were non-fatal */
camel_exception_clear (ex);
- if (ssl_mode != MODE_TLS) {
- /* we're done */
- return TRUE;
+#ifdef HAVE_SSL
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE) {
+ /* try_starttls is always TRUE here */
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS)
+ goto starttls;
+ } else if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS) {
+ if (try_starttls) {
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS) {
+ goto starttls;
+ } else {
+ /* server doesn't support STARTTLS, abort */
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Failed to connect to SMTP server %s in secure mode: %s"),
+ service->url->host, _("server does not appear to support SSL"));
+ goto exception_cleanup;
+ }
+ }
}
+#endif /* HAVE_SSL */
- if (!(transport->flags & CAMEL_SMTP_TRANSPORT_STARTTLS)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to connect to SMTP server %s in secure mode: %s"),
- service->url->host, _("STARTTLS not supported"));
-
- goto exception_cleanup;
- }
+ return TRUE;
+#ifdef HAVE_SSL
+ starttls:
d(fprintf (stderr, "sending : STARTTLS\r\n"));
if (camel_stream_write (tcp_stream, "STARTTLS\r\n", 10) == -1) {
camel_exception_setv (ex, errno == EINTR ? CAMEL_EXCEPTION_USER_CANCEL : CAMEL_EXCEPTION_SYSTEM,
@@ -374,68 +420,38 @@ connect_to_server (CamelService *service, struct addrinfo *ai, int ssl_mode, Cam
transport->connected = FALSE;
return FALSE;
+#endif /* HAVE_SSL */
}
-static struct {
- char *value;
- char *serv;
- char *port;
- int mode;
-} ssl_options[] = {
- { "", "smtps", SMTPS_PORT, MODE_SSL }, /* really old (1.x) */
- { "always", "smtps", SMTPS_PORT, MODE_SSL },
- { "when-possible", "smtp", SMTP_PORT, MODE_TLS },
- { "never", "smtp", SMTP_PORT, MODE_CLEAR },
- { NULL, "smtp", SMTP_PORT, MODE_CLEAR },
-};
-
static gboolean
connect_to_server_wrapper (CamelService *service, CamelException *ex)
{
- struct addrinfo hints, *ai;
- const char *ssl_mode;
- int mode, ret, i;
- char *serv;
- const char *port;
-
- if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
- for (i = 0; ssl_options[i].value; i++)
- if (!strcmp (ssl_options[i].value, ssl_mode))
- break;
- mode = ssl_options[i].mode;
- serv = ssl_options[i].serv;
- port = ssl_options[i].port;
- } else {
- mode = MODE_CLEAR;
- serv = "smtp";
- port = SMTP_PORT;
- }
-
- if (service->url->port) {
- serv = g_alloca (16);
- sprintf (serv, "%d", service->url->port);
- port = NULL;
- }
+#ifdef HAVE_SSL
+ CamelSmtpTransport *transport = (CamelSmtpTransport *) service;
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
- ai = camel_getaddrinfo(service->url->host, serv, &hints, ex);
- if (ai == NULL && port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
- camel_exception_clear (ex);
- ai = camel_getaddrinfo(service->url->host, port, &hints, ex);
+ if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS) {
+ /* First try connecting to the SSL port */
+ if (!connect_to_server (service, FALSE, ex)) {
+ if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE) {
+ /* Seems the SSL port is unavailable, lets try STARTTLS */
+ camel_exception_clear (ex);
+ return connect_to_server (service, TRUE, ex);
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (transport->flags & CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE) {
+ /* If the server supports STARTTLS, use it */
+ return connect_to_server (service, TRUE, ex);
+ } else {
+ /* User doesn't care about SSL */
+ return connect_to_server (service, FALSE, ex);
}
- if (ai == NULL)
- return FALSE;
-
- if (!(ret = connect_to_server (service, ai, mode, ex)) && mode == MODE_SSL)
- ret = connect_to_server (service, ai, MODE_TLS, ex);
- else if (!ret && mode == MODE_TLS)
- ret = connect_to_server (service, ai, MODE_CLEAR, ex);
-
- camel_freeaddrinfo (ai);
-
- return ret;
+#else
+ return connect_to_server (service, FALSE, ex);
+#endif
}
static gboolean
diff --git a/camel/providers/smtp/camel-smtp-transport.h b/camel/providers/smtp/camel-smtp-transport.h
index 7b5ad88f12..87fcafb58b 100644
--- a/camel/providers/smtp/camel-smtp-transport.h
+++ b/camel/providers/smtp/camel-smtp-transport.h
@@ -43,7 +43,13 @@ extern "C" {
#define CAMEL_SMTP_TRANSPORT_ENHANCEDSTATUSCODES (1 << 2)
#define CAMEL_SMTP_TRANSPORT_STARTTLS (1 << 3)
-#define CAMEL_SMTP_TRANSPORT_AUTH_EQUAL (1 << 4) /* set if we are using authtypes from a broken AUTH= */
+#define CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS (1 << 4)
+#define CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE (1 << 5)
+
+#define CAMEL_SMTP_TRANSPORT_USE_SSL (CAMEL_SMTP_TRANSPORT_USE_SSL_ALWAYS | \
+ CAMEL_SMTP_TRANSPORT_USE_SSL_WHEN_POSSIBLE)
+
+#define CAMEL_SMTP_TRANSPORT_AUTH_EQUAL (1 << 6) /* set if we are using authtypes from a broken AUTH= */
typedef struct {
CamelTransport parent_object;