Reworked the accounts plug-ins (configuration changes probably crash now)

This commit is contained in:
Pierre Pronchery 2012-01-07 00:27:07 +00:00
parent a0c178ddca
commit 844aeed643
9 changed files with 409 additions and 406 deletions

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -86,20 +86,20 @@ typedef struct _AccountPluginHelper
typedef struct _AccountPlugin AccountPlugin;
struct _AccountPlugin
typedef const struct _AccountPluginDefinition
{
AccountPluginHelper * helper;
char const * type;
char const * name;
char const * icon;
AccountConfig * config;
int (*init)(AccountPlugin * plugin);
char const * description;
AccountConfig const * config;
AccountPlugin * (*init)(AccountPluginHelper * helper);
int (*destroy)(AccountPlugin * plugin);
AccountConfig * (*get_config)(AccountPlugin * plugin);
char * (*get_source)(AccountPlugin * plugin, AccountFolder * folder,
AccountMessage * message);
int (*refresh)(AccountPlugin * plugin, AccountFolder * folder,
AccountMessage * message);
void * priv;
};
} AccountPluginDefinition;
#endif /* !DESKTOP_MAILER_ACCOUNT_H */

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Mailer 0.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-01-05 19:24+0100\n"
"POT-Creation-Date: 2012-01-07 01:19+0100\n"
"PO-Revision-Date: 2010-10-02 23:25+0200\n"
"Last-Translator: Pierre Pronchery <khorben@defora.org>\n"
"Language-Team: French\n"
@ -478,24 +478,24 @@ msgstr "Paramètres"
msgid "An error occured while saving preferences"
msgstr "Une erreur est survenue pendant la sauvegarde des préférences"
#: ../src/mailer.c:3000 ../src/mailer.c:3004
#: ../src/mailer.c:3004 ../src/mailer.c:3008
msgid "Question"
msgstr "Question"
#: ../src/mailer.c:3073
#: ../src/mailer.c:3077
#, c-format
msgid "%s/%s: %d %s"
msgstr "%s/%s: %d %s"
#: ../src/mailer.c:3076
#: ../src/mailer.c:3080
msgid "messages"
msgstr "messages"
#: ../src/mailer.c:3076
#: ../src/mailer.c:3080
msgid "message"
msgstr "message"
#: ../src/mailer.c:3079
#: ../src/mailer.c:3083
msgid "Ready"
msgstr "Prêt"

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2006-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -52,6 +52,7 @@ struct _Account
GtkTreeStore * store;
GtkTreeRowReference * row;
Plugin * plugin;
AccountPluginDefinition * definition;
AccountPlugin * account;
int enabled;
@ -115,9 +116,8 @@ Account * account_new(Mailer * mailer, char const * type, char const * title,
#ifdef DEBUG
fprintf(stderr, "DEBUG: account_new(%p, \"%s\", \"%s\", %p)\n",
(void*)mailer, type, title, (void*)store);
(void *)mailer, type, title, (void *)store);
#endif
/* FIXME copy the AccountConfig structure */
if(type == NULL)
return NULL;
if((account = object_new(sizeof(*account))) == NULL)
@ -129,12 +129,16 @@ Account * account_new(Mailer * mailer, char const * type, char const * title,
account->title = string_new(title);
account->store = store;
account->plugin = plugin_new(LIBDIR, PACKAGE, "account", type);
account->account = (account->plugin != NULL)
account->definition = (account->plugin != NULL)
? plugin_lookup(account->plugin, "account_plugin") : NULL;
if(account->type == NULL || account->plugin == NULL
|| account->account == NULL)
|| account->definition == NULL
|| account->definition->init == NULL
|| account->definition->destroy == NULL
|| account->definition->get_config == NULL)
{
account_delete(account);
error_set_code(1, "%s%s", "Invalid plug-in ", type);
return NULL;
}
if(store != NULL)
@ -153,7 +157,6 @@ Account * account_new(Mailer * mailer, char const * type, char const * title,
memcpy(&account->helper, &_account_plugin_helper,
sizeof(account->helper));
account->helper.account = account;
account->account->helper = &account->helper;
account->enabled = 1;
account->identity = NULL;
return account;
@ -163,26 +166,13 @@ Account * account_new(Mailer * mailer, char const * type, char const * title,
/* account_delete */
void account_delete(Account * account)
{
AccountConfig * p;
if(account->row != NULL)
gtk_tree_row_reference_free(account->row);
if(account->plugin != NULL)
if(account->definition != NULL)
{
if(account->account->destroy != NULL)
account->account->destroy(account->account);
if(account->account->config != NULL)
for(p = account->account->config; p->name != NULL; p++)
switch(p->type)
{
case ACT_STRING:
case ACT_PASSWORD:
case ACT_FILE:
free(p->value);
break;
default:
break;
}
if(account->definition->destroy != NULL
&& account->account != NULL)
account->definition->destroy(account->account);
}
string_delete(account->title);
string_delete(account->type);
@ -196,7 +186,7 @@ void account_delete(Account * account)
/* account_get_config */
AccountConfig * account_get_config(Account * account)
{
return account->account->config;
return account->definition->get_config(account->account);
}
@ -217,7 +207,7 @@ GtkTreeStore * account_get_folders(Account * account)
/* account_get_name */
char const * account_get_name(Account * account)
{
return account->account->name;
return account->definition->name;
}
@ -257,7 +247,7 @@ int account_set_title(Account * account, char const * title)
/* account_config_load */
int account_config_load(Account * account, Config * config)
{
AccountConfig * p = account->account->config;
AccountConfig * p = account_get_config(account);
char const * value;
char * q;
long l;
@ -303,7 +293,7 @@ int account_config_load(Account * account, Config * config)
/* account_config_save */
int account_config_save(Account * account, Config * config)
{
AccountConfig * p = account->account->config;
AccountConfig * p = account_get_config(account);
uint16_t u16;
char buf[6];
@ -354,9 +344,8 @@ int account_init(Account * account)
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%p)\n", __func__, (void*)account);
#endif
if(account->account->init == NULL)
return 0;
return account->account->init(account->account);
return (account->account = account->definition->init(&account->helper))
!= NULL ? 0 : -1;
}
@ -376,9 +365,9 @@ GtkTextBuffer * account_select(Account * account, Folder * folder,
return NULL;
if(message != NULL && (am = message_get_data(message)) == NULL)
return NULL;
if(account->account->refresh != NULL
&& account->account->refresh(account->account, af, am)
!= 0)
if(account->definition->refresh != NULL
&& account->definition->refresh(account->account, af,
am) != 0)
return NULL;
return (message != NULL) ? message_get_body(message) : NULL;
}
@ -395,10 +384,10 @@ GtkTextBuffer * account_select_source(Account * account, Folder * folder,
fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__,
folder_get_name(folder), (void*)message);
#endif
if(account->account->get_source == NULL)
if(account->definition->get_source == NULL)
return NULL;
ret = gtk_text_buffer_new(NULL);
if((p = account->account->get_source(account->account,
if((p = account->definition->get_source(account->account,
folder_get_data(folder),
message_get_data(message))) != NULL)
{

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -135,8 +135,12 @@ typedef struct _IMAP4Command
} data;
} IMAP4Command;
typedef struct _IMAP4
typedef struct _AccountPlugin
{
AccountPluginHelper * helper;
AccountConfig * config;
int fd;
SSL * ssl;
guint source;
@ -159,7 +163,7 @@ typedef struct _IMAP4
static char const _imap4_type[] = "IMAP4";
static char const _imap4_name[] = "IMAP4 server";
AccountConfig _imap4_config[I4CV_COUNT + 1] =
AccountConfig const _imap4_config[I4CV_COUNT + 1] =
{
{ "username", "Username", ACT_STRING, NULL },
{ "password", "Password", ACT_PASSWORD, NULL },
@ -178,29 +182,30 @@ AccountConfig _imap4_config[I4CV_COUNT + 1] =
/* prototypes */
/* plug-in */
static int _imap4_init(AccountPlugin * plugin);
static int _imap4_destroy(AccountPlugin * plugin);
static int _imap4_refresh(AccountPlugin * plugin, AccountFolder * folder,
static IMAP4 * _imap4_init(AccountPluginHelper * helper);
static int _imap4_destroy(IMAP4 * imap4);
static AccountConfig * _imap4_get_config(IMAP4 * imap4);
static int _imap4_refresh(IMAP4 * imap4, AccountFolder * folder,
AccountMessage * message);
/* useful */
static IMAP4Command * _imap4_command(AccountPlugin * plugin,
IMAP4Context context, char const * command);
static int _imap4_parse(AccountPlugin * plugin);
static void _imap4_reset(AccountPlugin * plugin);
static IMAP4Command * _imap4_command(IMAP4 * imap4, IMAP4Context context,
char const * command);
static int _imap4_parse(IMAP4 * imap4);
static void _imap4_reset(IMAP4 * imap4);
static AccountFolder * _imap4_folder_new(AccountPlugin * plugin,
AccountFolder * parent, char const * name);
static void _imap4_folder_delete(AccountPlugin * plugin,
static AccountFolder * _imap4_folder_new(IMAP4 * imap4, AccountFolder * parent,
char const * name);
static void _imap4_folder_delete(IMAP4 * imap4,
AccountFolder * folder);
static AccountFolder * _imap4_folder_get_folder(AccountPlugin * plugin,
static AccountFolder * _imap4_folder_get_folder(IMAP4 * imap4,
AccountFolder * folder, char const * name);
static AccountMessage * _imap4_folder_get_message(AccountPlugin * plugin,
static AccountMessage * _imap4_folder_get_message(IMAP4 * imap4,
AccountFolder * folder, unsigned int id);
static AccountMessage * _imap4_message_new(AccountPlugin * plugin,
static AccountMessage * _imap4_message_new(IMAP4 * imap4,
AccountFolder * folder, unsigned int id);
static void _imap4_message_delete(AccountPlugin * plugin,
static void _imap4_message_delete(IMAP4 * imap4,
AccountMessage * message);
/* callbacks */
@ -223,58 +228,69 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
/* public */
/* variables */
AccountPlugin account_plugin =
AccountPluginDefinition account_plugin =
{
NULL,
_imap4_type,
_imap4_name,
NULL,
NULL,
_imap4_config,
_imap4_init,
_imap4_destroy,
_imap4_get_config,
NULL,
_imap4_refresh,
NULL
_imap4_refresh
};
/* private */
/* imap4_init */
static int _imap4_init(AccountPlugin * plugin)
static IMAP4 * _imap4_init(AccountPluginHelper * helper)
{
IMAP4 * imap4;
if((imap4 = malloc(sizeof(*imap4))) == NULL)
return -1;
return NULL;
memset(imap4, 0, sizeof(*imap4));
plugin->priv = imap4;
imap4->helper = helper;
if((imap4->config = malloc(sizeof(_imap4_config))) == NULL)
{
free(imap4);
return NULL;
}
memcpy(imap4->config, &_imap4_config, sizeof(_imap4_config));
imap4->fd = -1;
imap4->source = g_idle_add(_on_connect, plugin);
return 0;
imap4->source = g_idle_add(_on_connect, imap4);
return imap4;
}
/* imap4_destroy */
static int _imap4_destroy(AccountPlugin * plugin)
static int _imap4_destroy(IMAP4 * imap4)
{
IMAP4 * imap4 = plugin->priv;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(imap4 == NULL) /* XXX _imap4_destroy() may be called uninitialized */
return 0;
_imap4_reset(plugin);
_imap4_reset(imap4);
#if 0 /* XXX do not free() */
_imap4_folder_delete(plugin, &imap4->folders);
_imap4_folder_delete(imap4, &imap4->folders);
#endif
free(imap4);
return 0;
}
/* imap4_get_config */
static AccountConfig * _imap4_get_config(IMAP4 * imap4)
{
return imap4->config;
}
/* imap4_refresh */
static int _imap4_refresh(AccountPlugin * plugin, AccountFolder * folder,
static int _imap4_refresh(IMAP4 * imap4, AccountFolder * folder,
AccountMessage * message)
{
IMAP4Command * cmd;
@ -289,7 +305,7 @@ static int _imap4_refresh(AccountPlugin * plugin, AccountFolder * folder,
|| (buf = malloc(++len)) == NULL)
return -1;
snprintf(buf, len, "EXAMINE \"%s\"", folder->name);
cmd = _imap4_command(plugin, I4C_SELECT, buf);
cmd = _imap4_command(imap4, I4C_SELECT, buf);
free(buf);
if(cmd == NULL)
return -1;
@ -301,10 +317,9 @@ static int _imap4_refresh(AccountPlugin * plugin, AccountFolder * folder,
/* useful */
/* imap4_command */
static IMAP4Command * _imap4_command(AccountPlugin * plugin,
IMAP4Context context, char const * command)
static IMAP4Command * _imap4_command(IMAP4 * imap4, IMAP4Context context,
char const * command)
{
IMAP4 * imap4 = plugin->priv;
IMAP4Command * p;
size_t len;
@ -341,25 +356,24 @@ static IMAP4Command * _imap4_command(AccountPlugin * plugin,
}
imap4->wr_source = g_io_add_watch(imap4->channel, G_IO_OUT,
(imap4->ssl != NULL) ? _on_watch_can_write_ssl
: _on_watch_can_write, plugin);
: _on_watch_can_write, imap4);
}
return p;
}
/* imap4_parse */
static int _parse_context(AccountPlugin * plugin, char const * answer);
static int _context_fetch(AccountPlugin * plugin, char const * answer);
static int _context_init(AccountPlugin * plugin);
static int _context_list(AccountPlugin * plugin, char const * answer);
static int _context_login(AccountPlugin * plugin, char const * answer);
static int _context_select(AccountPlugin * plugin);
static int _context_status(AccountPlugin * plugin, char const * answer);
static int _parse_context(IMAP4 * imap4, char const * answer);
static int _context_fetch(IMAP4 * imap4, char const * answer);
static int _context_init(IMAP4 * imap4);
static int _context_list(IMAP4 * imap4, char const * answer);
static int _context_login(IMAP4 * imap4, char const * answer);
static int _context_select(IMAP4 * imap4);
static int _context_status(IMAP4 * imap4, char const * answer);
static int _imap4_parse(AccountPlugin * plugin)
static int _imap4_parse(IMAP4 * imap4)
{
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
AccountPluginHelper * helper = imap4->helper;
size_t i;
size_t j;
IMAP4Command * cmd;
@ -399,7 +413,7 @@ static int _imap4_parse(AccountPlugin * plugin)
1);
}
}
if(_parse_context(plugin, &imap4->rd_buf[j]) != 0)
if(_parse_context(imap4, &imap4->rd_buf[j]) != 0)
cmd->status = I4CS_ERROR;
}
if(j != 0)
@ -412,10 +426,9 @@ static int _imap4_parse(AccountPlugin * plugin)
return (imap4->queue[0].status != I4CS_ERROR) ? 0 : -1;
}
static int _parse_context(AccountPlugin * plugin, char const * answer)
static int _parse_context(IMAP4 * imap4, char const * answer)
{
int ret = -1;
IMAP4 * imap4 = plugin->priv;
IMAP4Command * cmd = &imap4->queue[0];
#ifdef DEBUG
@ -425,30 +438,29 @@ static int _parse_context(AccountPlugin * plugin, char const * answer)
switch(cmd->context)
{
case I4C_FETCH:
return _context_fetch(plugin, answer);
return _context_fetch(imap4, answer);
case I4C_INIT:
return _context_init(plugin);
return _context_init(imap4);
case I4C_LIST:
return _context_list(plugin, answer);
return _context_list(imap4, answer);
case I4C_LOGIN:
return _context_login(plugin, answer);
return _context_login(imap4, answer);
case I4C_NOOP:
if(cmd->status != I4CS_PARSING)
return 0;
cmd->status = I4CS_OK;
return 0;
case I4C_SELECT:
return _context_select(plugin);
return _context_select(imap4);
case I4C_STATUS:
return _context_status(plugin, answer);
return _context_status(imap4, answer);
}
return ret;
}
static int _context_fetch(AccountPlugin * plugin, char const * answer)
static int _context_fetch(IMAP4 * imap4, char const * answer)
{
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
AccountPluginHelper * helper = imap4->helper;
IMAP4Command * cmd = &imap4->queue[0];
AccountFolder * folder = cmd->data.fetch.folder;
AccountMessage * message = cmd->data.fetch.message;
@ -491,7 +503,7 @@ static int _context_fetch(AccountPlugin * plugin, char const * answer)
answer = p;
if(strncmp(answer, " FETCH ", 7) != 0)
return 0;
if((message = _imap4_folder_get_message(plugin, folder,
if((message = _imap4_folder_get_message(imap4, folder,
id)) != NULL)
{
cmd->data.fetch.status = I4FS_HEADERS;
@ -513,28 +525,26 @@ static int _context_fetch(AccountPlugin * plugin, char const * answer)
return -1;
}
static int _context_init(AccountPlugin * plugin)
static int _context_init(IMAP4 * imap4)
{
IMAP4 * imap4 = plugin->priv;
IMAP4Command * cmd = &imap4->queue[0];
char const * p;
char const * q;
gchar * r;
cmd->status = I4CS_OK;
if((p = plugin->config[I4CV_USERNAME].value) == NULL || *p == '\0')
if((p = imap4->config[I4CV_USERNAME].value) == NULL || *p == '\0')
return -1;
if((q = plugin->config[I4CV_PASSWORD].value) == NULL || *q == '\0')
if((q = imap4->config[I4CV_PASSWORD].value) == NULL || *q == '\0')
return -1;
r = g_strdup_printf("%s %s %s", "LOGIN", p, q);
cmd = _imap4_command(plugin, I4C_LOGIN, r);
cmd = _imap4_command(imap4, I4C_LOGIN, r);
g_free(r);
return (cmd != NULL) ? 0 : -1;
}
static int _context_list(AccountPlugin * plugin, char const * answer)
static int _context_list(IMAP4 * imap4, char const * answer)
{
IMAP4 * imap4 = plugin->priv;
IMAP4Command * cmd = &imap4->queue[0];
AccountFolder * folder;
AccountFolder * parent = cmd->data.list.parent;
@ -585,20 +595,20 @@ static int _context_list(AccountPlugin * plugin, char const * answer)
else
sscanf(p, "%63s", buf);
buf[63] = '\0';
if(buf[0] != '\0' && (folder = _imap4_folder_get_folder(plugin, parent,
if(buf[0] != '\0' && (folder = _imap4_folder_get_folder(imap4, parent,
buf)) != NULL)
{
/* FIXME escape the mailbox name (double quotes...) */
q = g_strdup_printf("%s \"%s\" (%s)", "STATUS", buf,
"MESSAGES RECENT UNSEEN");
if((cmd = _imap4_command(plugin, I4C_STATUS, q)) != NULL)
if((cmd = _imap4_command(imap4, I4C_STATUS, q)) != NULL)
cmd->data.status.folder = folder;
g_free(q);
if(cmd != NULL && recurse == 1 && reference != '\0')
{
q = g_strdup_printf("%s \"\" \"%s%c%%\"", "LIST", buf,
reference);
if((cmd = _imap4_command(plugin, I4C_LIST, q)) != NULL)
if((cmd = _imap4_command(imap4, I4C_LIST, q)) != NULL)
cmd->data.list.parent = folder;
g_free(q);
}
@ -606,12 +616,11 @@ static int _context_list(AccountPlugin * plugin, char const * answer)
return (cmd != NULL) ? 0 : -1;
}
static int _context_login(AccountPlugin * plugin, char const * answer)
static int _context_login(IMAP4 * imap4, char const * answer)
{
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
AccountPluginHelper * helper = imap4->helper;
IMAP4Command * cmd = &imap4->queue[0];
char const * prefix = plugin->config[I4CV_PREFIX].value;
char const * prefix = imap4->config[I4CV_PREFIX].value;
gchar * q;
if(cmd->status != I4CS_PARSING)
@ -623,7 +632,7 @@ static int _context_login(AccountPlugin * plugin, char const * answer)
if((q = g_strdup_printf("%s \"\" \"%s%%\"", "LIST", (prefix != NULL)
? prefix : "")) == NULL)
return -1;
cmd = _imap4_command(plugin, I4C_LIST, q);
cmd = _imap4_command(imap4, I4C_LIST, q);
g_free(q);
if(cmd == NULL)
return -1;
@ -631,9 +640,8 @@ static int _context_login(AccountPlugin * plugin, char const * answer)
return 0;
}
static int _context_select(AccountPlugin * plugin)
static int _context_select(IMAP4 * imap4)
{
IMAP4 * imap4 = plugin->priv;
IMAP4Command * cmd = &imap4->queue[0];
AccountFolder * folder;
AccountMessage * message;
@ -651,7 +659,7 @@ static int _context_select(AccountPlugin * plugin)
else
snprintf(buf, sizeof(buf), "%s %u %s", "FETCH", message->id,
"BODY.PEEK[]");
if((cmd = _imap4_command(plugin, I4C_FETCH, buf)) == NULL)
if((cmd = _imap4_command(imap4, I4C_FETCH, buf)) == NULL)
return -1;
cmd->data.fetch.folder = folder;
cmd->data.fetch.message = message;
@ -660,9 +668,8 @@ static int _context_select(AccountPlugin * plugin)
return 0;
}
static int _context_status(AccountPlugin * plugin, char const * answer)
static int _context_status(IMAP4 * imap4, char const * answer)
{
IMAP4 * imap4 = plugin->priv;
IMAP4Command * cmd = &imap4->queue[0];
char const * p;
char const messages[] = "MESSAGES";
@ -719,9 +726,8 @@ static int _context_status(AccountPlugin * plugin, char const * answer)
/* imap4_reset */
static void _imap4_reset(AccountPlugin * plugin)
static void _imap4_reset(IMAP4 * imap4)
{
IMAP4 * imap4 = plugin->priv;
size_t i;
if(imap4->rd_source != 0)
@ -752,13 +758,12 @@ static void _imap4_reset(AccountPlugin * plugin)
/* imap4_folder_new */
static AccountFolder * _imap4_folder_new(AccountPlugin * plugin,
AccountFolder * parent, char const * name)
static AccountFolder * _imap4_folder_new(IMAP4 * imap4, AccountFolder * parent,
char const * name)
{
AccountPluginHelper * helper = plugin->helper;
AccountPluginHelper * helper = imap4->helper;
AccountFolder * folder;
AccountFolder ** p;
IMAP4 * imap4 = plugin->priv;
FolderType type = FT_FOLDER;
struct
{
@ -801,7 +806,7 @@ static AccountFolder * _imap4_folder_new(AccountPlugin * plugin,
folder->folders_cnt = 0;
if(folder->folder == NULL || folder->name == NULL)
{
_imap4_folder_delete(plugin, folder);
_imap4_folder_delete(imap4, folder);
return NULL;
}
parent->folders[parent->folders_cnt++] = folder;
@ -810,25 +815,25 @@ static AccountFolder * _imap4_folder_new(AccountPlugin * plugin,
/* imap4_folder_delete */
static void _imap4_folder_delete(AccountPlugin * plugin, AccountFolder * folder)
static void _imap4_folder_delete(IMAP4 * imap4, AccountFolder * folder)
{
size_t i;
if(folder->folder != NULL)
plugin->helper->folder_delete(folder->folder);
imap4->helper->folder_delete(folder->folder);
free(folder->name);
for(i = 0; i < folder->messages_cnt; i++)
_imap4_message_delete(plugin, folder->messages[i]);
_imap4_message_delete(imap4, folder->messages[i]);
free(folder->messages);
for(i = 0; i < folder->folders_cnt; i++)
_imap4_folder_delete(plugin, folder->folders[i]);
_imap4_folder_delete(imap4, folder->folders[i]);
free(folder->folders);
object_delete(folder);
}
/* imap4_folder_get_folder */
static AccountFolder * _imap4_folder_get_folder(AccountPlugin * plugin,
static AccountFolder * _imap4_folder_get_folder(IMAP4 * imap4,
AccountFolder * folder, char const * name)
{
size_t i;
@ -840,12 +845,12 @@ static AccountFolder * _imap4_folder_get_folder(AccountPlugin * plugin,
for(i = 0; i < folder->folders_cnt; i++)
if(strcmp(folder->folders[i]->name, name) == 0)
return folder->folders[i];
return _imap4_folder_new(plugin, folder, name);
return _imap4_folder_new(imap4, folder, name);
}
/* imap4_folder_get_message */
static AccountMessage * _imap4_folder_get_message(AccountPlugin * plugin,
static AccountMessage * _imap4_folder_get_message(IMAP4 * imap4,
AccountFolder * folder, unsigned int id)
{
size_t i;
@ -856,15 +861,15 @@ static AccountMessage * _imap4_folder_get_message(AccountPlugin * plugin,
for(i = 0; i < folder->messages_cnt; i++)
if(folder->messages[i]->id == id)
return folder->messages[i];
return _imap4_message_new(plugin, folder, id);
return _imap4_message_new(imap4, folder, id);
}
/* imap4_message_new */
static AccountMessage * _imap4_message_new(AccountPlugin * plugin,
static AccountMessage * _imap4_message_new(IMAP4 * imap4,
AccountFolder * folder, unsigned int id)
{
AccountPluginHelper * helper = plugin->helper;
AccountPluginHelper * helper = imap4->helper;
AccountMessage * message;
AccountMessage ** p;
@ -878,7 +883,7 @@ static AccountMessage * _imap4_message_new(AccountPlugin * plugin,
if((message->message = helper->message_new(helper->account,
folder->folder, message)) == NULL)
{
_imap4_message_delete(plugin, message);
_imap4_message_delete(imap4, message);
return NULL;
}
folder->messages[folder->messages_cnt++] = message;
@ -887,37 +892,35 @@ static AccountMessage * _imap4_message_new(AccountPlugin * plugin,
/* imap4_message_delete */
static void _imap4_message_delete(AccountPlugin * plugin,
static void _imap4_message_delete(IMAP4 * imap4,
AccountMessage * message)
{
if(message->message != NULL)
plugin->helper->message_delete(message->message);
imap4->helper->message_delete(message->message);
object_delete(message);
}
/* callbacks */
/* on_idle */
static int _connect_channel(AccountPlugin * plugin);
static int _connect_channel(IMAP4 * imap4);
static gboolean _on_connect(gpointer data)
{
AccountPlugin * plugin = data;
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
AccountPluginHelper * helper = imap4->helper;
char const * hostname;
char const * p;
struct hostent * he;
unsigned short port;
struct sockaddr_in sa;
int res;
char buf[128];
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
imap4->source = 0;
if((hostname = plugin->config[I4CV_HOSTNAME].value) == NULL)
if((hostname = imap4->config[I4CV_HOSTNAME].value) == NULL)
{
helper->error(NULL, "No hostname set", 1);
return FALSE;
@ -925,15 +928,15 @@ static gboolean _on_connect(gpointer data)
if((he = gethostbyname(hostname)) == NULL)
{
helper->error(NULL, hstrerror(h_errno), 1);
return _on_reset(plugin);
return _on_reset(imap4);
}
if((p = plugin->config[I4CV_PORT].value) == NULL)
if((p = imap4->config[I4CV_PORT].value) == NULL)
return FALSE;
port = (unsigned long)p;
if((imap4->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
helper->error(NULL, strerror(errno), 1);
return _on_reset(plugin);
return _on_reset(imap4);
}
if((res = fcntl(imap4->fd, F_GETFL)) >= 0
&& fcntl(imap4->fd, F_SETFL, res | O_NONBLOCK) == -1)
@ -946,20 +949,19 @@ static gboolean _on_connect(gpointer data)
inet_ntoa(sa.sin_addr), port);
if((connect(imap4->fd, (struct sockaddr *)&sa, sizeof(sa)) != 0
&& errno != EINPROGRESS)
|| _connect_channel(plugin) != 0)
|| _connect_channel(imap4) != 0)
{
helper->error(NULL, strerror(errno), 1);
return _on_reset(plugin);
return _on_reset(imap4);
}
imap4->wr_source = g_io_add_watch(imap4->channel, G_IO_OUT,
_on_watch_can_connect, plugin);
_on_watch_can_connect, imap4);
return FALSE;
}
static int _connect_channel(AccountPlugin * plugin)
static int _connect_channel(IMAP4 * imap4)
{
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
AccountPluginHelper * helper = imap4->helper;
GError * error = NULL;
#ifdef DEBUG
@ -986,10 +988,9 @@ static int _connect_channel(AccountPlugin * plugin)
/* on_noop */
static gboolean _on_noop(gpointer data)
{
AccountPlugin * plugin = data;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
_imap4_command(plugin, I4C_NOOP, "NOOP");
_imap4_command(imap4, I4C_NOOP, "NOOP");
imap4->source = 0;
return FALSE;
}
@ -998,11 +999,10 @@ static gboolean _on_noop(gpointer data)
/* on_reset */
static gboolean _on_reset(gpointer data)
{
AccountPlugin * plugin = data;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
_imap4_reset(plugin);
imap4->source = g_timeout_add(3000, _on_connect, plugin);
_imap4_reset(imap4);
imap4->source = g_timeout_add(3000, _on_connect, imap4);
return FALSE;
}
@ -1011,9 +1011,8 @@ static gboolean _on_reset(gpointer data)
static gboolean _on_watch_can_connect(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
AccountPluginHelper * helper = imap4->helper;
SSL_CTX * ssl_ctx;
char buf[128];
@ -1024,7 +1023,7 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
#endif
imap4->wr_source = 0;
/* setup SSL */
if(plugin->config[I4CV_SSL].value != NULL)
if(imap4->config[I4CV_SSL].value != NULL)
{
if((ssl_ctx = helper->get_ssl_context(helper->account)) == NULL)
/* FIXME report error */
@ -1040,25 +1039,24 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
SSL_set_connect_state(imap4->ssl);
/* perform initial handshake */
imap4->wr_source = g_io_add_watch(imap4->channel, G_IO_OUT,
_on_watch_can_handshake, plugin);
_on_watch_can_handshake, imap4);
return FALSE;
}
/* wait for the server's banner */
imap4->rd_source = g_io_add_watch(imap4->channel, G_IO_IN,
_on_watch_can_read, plugin);
_on_watch_can_read, imap4);
return FALSE;
}
/* on_watch_can_handshake */
static int _handshake_verify(AccountPlugin * plugin);
static int _handshake_verify(IMAP4 * imap4);
static gboolean _on_watch_can_handshake(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
AccountPluginHelper * helper = imap4->helper;
int res;
int err;
char buf[128];
@ -1073,11 +1071,11 @@ static gboolean _on_watch_can_handshake(GIOChannel * source,
imap4->rd_source = 0;
if((res = SSL_do_handshake(imap4->ssl)) == 1)
{
if(_handshake_verify(plugin) != 0)
return _on_reset(plugin);
if(_handshake_verify(imap4) != 0)
return _on_reset(imap4);
/* wait for the server's banner */
imap4->rd_source = g_io_add_watch(imap4->channel, G_IO_IN,
_on_watch_can_read_ssl, plugin);
_on_watch_can_read_ssl, imap4);
return FALSE;
}
err = SSL_get_error(imap4->ssl, res);
@ -1085,26 +1083,25 @@ static gboolean _on_watch_can_handshake(GIOChannel * source,
if(res == 0)
{
helper->error(helper->account, buf, 1);
return _on_reset(plugin);
return _on_reset(imap4);
}
if(err == SSL_ERROR_WANT_WRITE)
imap4->wr_source = g_io_add_watch(imap4->channel, G_IO_OUT,
_on_watch_can_handshake, plugin);
_on_watch_can_handshake, imap4);
else if(err == SSL_ERROR_WANT_READ)
imap4->rd_source = g_io_add_watch(imap4->channel, G_IO_IN,
_on_watch_can_handshake, plugin);
_on_watch_can_handshake, imap4);
else
{
helper->error(helper->account, buf, 1);
return _on_reset(plugin);
return _on_reset(imap4);
}
return FALSE;
}
static int _handshake_verify(AccountPlugin * plugin)
static int _handshake_verify(IMAP4 * imap4)
{
AccountPluginHelper * helper = plugin->helper;
IMAP4 * imap4 = plugin->priv;
AccountPluginHelper * helper = imap4->helper;
X509 * x509;
char buf[256] = "";
@ -1114,7 +1111,7 @@ static int _handshake_verify(AccountPlugin * plugin)
x509 = SSL_get_peer_certificate(imap4->ssl);
X509_NAME_get_text_by_NID(X509_get_subject_name(x509), NID_commonName,
buf, sizeof(buf));
if(strcasecmp(buf, plugin->config[I4CV_HOSTNAME].value) != 0)
if(strcasecmp(buf, imap4->config[I4CV_HOSTNAME].value) != 0)
return helper->confirm(helper->account, "The certificate could"
" not be matched.\nConnect anyway?");
return 0;
@ -1125,8 +1122,7 @@ static int _handshake_verify(AccountPlugin * plugin)
static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
gpointer data)
{
AccountPlugin * plugin = data;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
char * p;
gsize cnt = 0;
GError * error = NULL;
@ -1150,15 +1146,15 @@ static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
case G_IO_STATUS_NORMAL:
break;
case G_IO_STATUS_ERROR:
plugin->helper->error(NULL, error->message, 1);
imap4->helper->error(NULL, error->message, 1);
case G_IO_STATUS_EOF:
default:
imap4->rd_source = g_idle_add(_on_reset, plugin);
imap4->rd_source = g_idle_add(_on_reset, imap4);
return FALSE;
}
if(_imap4_parse(plugin) != 0)
if(_imap4_parse(imap4) != 0)
{
imap4->rd_source = g_idle_add(_on_reset, plugin);
imap4->rd_source = g_idle_add(_on_reset, imap4);
return FALSE;
}
if(imap4->queue_cnt == 0)
@ -1177,10 +1173,10 @@ static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
}
imap4->rd_source = 0;
if(imap4->queue_cnt == 0)
imap4->source = g_timeout_add(30000, _on_noop, plugin);
imap4->source = g_timeout_add(30000, _on_noop, imap4);
else
imap4->wr_source = g_io_add_watch(imap4->channel, G_IO_OUT,
_on_watch_can_write, plugin);
_on_watch_can_write, imap4);
return FALSE;
}
@ -1189,8 +1185,7 @@ static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
static gboolean _on_watch_can_read_ssl(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
char * p;
int cnt;
IMAP4Command * cmd;
@ -1213,7 +1208,7 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
{
imap4->rd_source = g_io_add_watch(imap4->channel,
G_IO_OUT, _on_watch_can_read_ssl,
plugin);
imap4);
return FALSE;
}
else if(cnt < 0 && SSL_get_error(imap4->ssl, cnt)
@ -1221,12 +1216,12 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
{
imap4->rd_source = g_io_add_watch(imap4->channel,
G_IO_IN, _on_watch_can_read_ssl,
plugin);
imap4);
return FALSE;
}
ERR_error_string(SSL_get_error(imap4->ssl, cnt), buf);
plugin->helper->error(NULL, buf, 1);
imap4->rd_source = g_idle_add(_on_reset, plugin);
imap4->helper->error(NULL, buf, 1);
imap4->rd_source = g_idle_add(_on_reset, imap4);
return FALSE;
}
#ifdef DEBUG
@ -1234,9 +1229,9 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
fwrite(&imap4->rd_buf[imap4->rd_buf_cnt], sizeof(*p), cnt, stderr);
#endif
imap4->rd_buf_cnt += cnt;
if(_imap4_parse(plugin) != 0)
if(_imap4_parse(imap4) != 0)
{
imap4->rd_source = g_idle_add(_on_reset, plugin);
imap4->rd_source = g_idle_add(_on_reset, imap4);
return FALSE;
}
if(imap4->queue_cnt == 0)
@ -1255,10 +1250,10 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
}
imap4->rd_source = 0;
if(imap4->queue_cnt == 0)
imap4->source = g_timeout_add(30000, _on_noop, plugin);
imap4->source = g_timeout_add(30000, _on_noop, imap4);
else
imap4->wr_source = g_io_add_watch(imap4->channel, G_IO_OUT,
_on_watch_can_write_ssl, plugin);
_on_watch_can_write_ssl, imap4);
return FALSE;
}
@ -1267,8 +1262,7 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
gpointer data)
{
AccountPlugin * plugin = data;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
IMAP4Command * cmd = &imap4->queue[0];
gsize cnt = 0;
GError * error = NULL;
@ -1301,10 +1295,10 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
case G_IO_STATUS_NORMAL:
break;
case G_IO_STATUS_ERROR:
plugin->helper->error(NULL, error->message, 1);
imap4->helper->error(NULL, error->message, 1);
case G_IO_STATUS_EOF:
default:
imap4->wr_source = g_idle_add(_on_reset, plugin);
imap4->wr_source = g_idle_add(_on_reset, imap4);
return FALSE;
}
if(cmd->buf_cnt > 0)
@ -1313,7 +1307,7 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
imap4->wr_source = 0;
if(imap4->rd_source == 0)
imap4->rd_source = g_io_add_watch(imap4->channel, G_IO_IN,
_on_watch_can_read, plugin);
_on_watch_can_read, imap4);
return FALSE;
}
@ -1322,8 +1316,7 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
static gboolean _on_watch_can_write_ssl(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
IMAP4 * imap4 = plugin->priv;
IMAP4 * imap4 = data;
IMAP4Command * cmd = &imap4->queue[0];
int cnt;
char * p;
@ -1342,7 +1335,7 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
{
imap4->wr_source = g_io_add_watch(imap4->channel,
G_IO_IN, _on_watch_can_write_ssl,
plugin);
imap4);
return FALSE;
}
else if(cnt < 0 && SSL_get_error(imap4->ssl, cnt)
@ -1350,12 +1343,12 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
{
imap4->wr_source = g_io_add_watch(imap4->channel,
G_IO_OUT, _on_watch_can_write_ssl,
plugin);
imap4);
return FALSE;
}
ERR_error_string(SSL_get_error(imap4->ssl, cnt), buf);
plugin->helper->error(NULL, buf, 1);
imap4->wr_source = g_idle_add(_on_reset, plugin);
imap4->helper->error(NULL, buf, 1);
imap4->wr_source = g_idle_add(_on_reset, imap4);
return FALSE;
}
#ifdef DEBUG
@ -1374,6 +1367,6 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
imap4->wr_source = 0;
if(imap4->rd_source == 0)
imap4->rd_source = g_io_add_watch(imap4->channel, G_IO_IN,
_on_watch_can_read_ssl, plugin);
_on_watch_can_read_ssl, imap4);
return FALSE;
}

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -43,10 +43,12 @@ typedef enum _ParserContext
PC_GARBAGE /* inside crap */
} ParserContext;
typedef struct _Mbox Mbox;
typedef struct _AccountPlugin Mbox;
struct _AccountMessage
{
AccountPluginHelper * helper;
Message * message;
/* Mbox */
@ -81,9 +83,11 @@ struct _AccountFolder
char * pixbuf;
};
struct _Mbox
struct _AccountPlugin
{
AccountPlugin * plugin;
AccountPluginHelper * helper;
AccountConfig * config;
AccountFolder folders[_FOLDER_CNT];
@ -95,7 +99,7 @@ struct _Mbox
/* constants */
#define MBOX_REFRESH_TIMEOUT 5000
static AccountConfig _mbox_config[] =
static AccountConfig const _mbox_config[] =
{
{ "mbox", "Inbox file", ACT_FILE, NULL },
{ "spool", "Spool file", ACT_FILE, NULL },
@ -121,25 +125,26 @@ static const struct
/* plug-in */
static int _mbox_init(AccountPlugin * plugin);
static int _mbox_destroy(AccountPlugin * plugin);
static char * _mbox_get_source(AccountPlugin * plugin, AccountFolder * folder,
static Mbox * _mbox_init(AccountPluginHelper * helper);
static int _mbox_destroy(Mbox * mbox);
static AccountConfig * _mbox_get_config(Mbox * mbox);
static char * _mbox_get_source(Mbox * mbox, AccountFolder * folder,
AccountMessage * message);
static int _mbox_refresh(AccountPlugin * plugin, AccountFolder * folder,
static int _mbox_refresh(Mbox * mbox, AccountFolder * folder,
AccountMessage * message);
AccountPlugin account_plugin =
AccountPluginDefinition account_plugin =
{
NULL,
"MBOX",
"Local folders",
NULL,
NULL,
_mbox_config,
_mbox_init,
_mbox_destroy,
_mbox_get_config,
_mbox_get_source,
_mbox_refresh,
NULL
_mbox_refresh
};
@ -153,7 +158,8 @@ static gboolean _folder_watch(GIOChannel * source, GIOCondition condition,
/* AccountMessage */
/* private */
/* prototypes */
static AccountMessage * _message_new(Folder * folder, off_t offset);
static AccountMessage * _message_new(AccountPluginHelper * helper,
Folder * folder, off_t offset);
static void _message_delete(AccountMessage * message);
static int _message_set_body(AccountMessage * message, off_t offset,
@ -164,7 +170,7 @@ static int _message_set_header(AccountMessage * message, char const * header);
/* Mbox */
/* functions */
/* mbox_init */
static int _mbox_init(AccountPlugin * plugin)
static Mbox * _mbox_init(AccountPluginHelper * helper)
{
Mbox * mbox;
size_t i;
@ -174,30 +180,34 @@ static int _mbox_init(AccountPlugin * plugin)
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if((mbox = calloc(1, sizeof(*mbox))) == NULL)
return -1;
plugin->priv = mbox;
mbox->plugin = plugin;
return NULL;
mbox->helper = helper;
mbox->timeout = MBOX_REFRESH_TIMEOUT;
if((mbox->config = malloc(sizeof(_mbox_config))) == NULL)
{
free(mbox);
return NULL;
}
memcpy(mbox->config, &_mbox_config, sizeof(_mbox_config));
for(i = 0; i < _FOLDER_CNT; i++)
{
af = &mbox->folders[i];
af->config = &_mbox_config[_mbox_folder_defaults[i].config];
if(af->config->value == NULL)
continue;
af->folder = plugin->helper->folder_new(plugin->helper->account,
af, NULL, _mbox_folder_defaults[i].type,
af->folder = helper->folder_new(helper->account, af, NULL,
_mbox_folder_defaults[i].type,
_mbox_folder_defaults[i].name);
af->mbox = mbox;
af->source = g_idle_add(_folder_idle, af);
}
return 0;
return mbox;
}
/* mbox_destroy */
static int _mbox_destroy(AccountPlugin * plugin)
static int _mbox_destroy(Mbox * mbox)
{
Mbox * mbox = plugin->priv;
size_t i;
AccountFolder * mf;
size_t j;
@ -221,8 +231,15 @@ static int _mbox_destroy(AccountPlugin * plugin)
}
/* mbox_get_config */
static AccountConfig * _mbox_get_config(Mbox * mbox)
{
return mbox->config;
}
/* mbox_get_source */
static char * _mbox_get_source(AccountPlugin * plugin, AccountFolder * folder,
static char * _mbox_get_source(Mbox * mbox, AccountFolder * folder,
AccountMessage * message)
{
char * ret = NULL;
@ -234,7 +251,7 @@ static char * _mbox_get_source(AccountPlugin * plugin, AccountFolder * folder,
return NULL;
if((fp = fopen(filename, "r")) == NULL)
{
plugin->helper->error(plugin->helper->account, filename, 1);
mbox->helper->error(mbox->helper->account, filename, 1);
return NULL;
}
len = message->body_offset - message->offset + message->body_length;
@ -246,7 +263,7 @@ static char * _mbox_get_source(AccountPlugin * plugin, AccountFolder * folder,
free(ret);
if(fclose(fp) != 0)
{
plugin->helper->error(plugin->helper->account, filename, 1);
mbox->helper->error(mbox->helper->account, filename, 1);
free(ret);
ret = NULL;
}
@ -255,7 +272,7 @@ static char * _mbox_get_source(AccountPlugin * plugin, AccountFolder * folder,
/* mbox_refresh */
static int _mbox_refresh(AccountPlugin * plugin, AccountFolder * folder,
static int _mbox_refresh(Mbox * mbox, AccountFolder * folder,
AccountMessage * message)
{
char const * filename = folder->config->value;
@ -264,21 +281,21 @@ static int _mbox_refresh(AccountPlugin * plugin, AccountFolder * folder,
size_t size;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%p, %p)\n", __func__, (void*)folder,
(void*)message);
fprintf(stderr, "DEBUG: %s(%p, %p)\n", __func__, (void *)folder,
(void *)message);
#endif
if(message == NULL)
return 0;
plugin->helper->message_set_body(message->message, NULL, 0, 0);
mbox->helper->message_set_body(message->message, NULL, 0, 0);
/* XXX we may still be reading the file... */
if((fp = fopen(filename, "r")) == NULL)
return -plugin->helper->error(NULL, strerror(errno), 1);
return -mbox->helper->error(NULL, strerror(errno), 1);
if(message->body_offset != 0 && message->body_length > 0
&& fseek(fp, message->body_offset, SEEK_SET) == 0
&& (buf = malloc(message->body_length)) != NULL)
{
if((size = fread(buf, 1, message->body_length, fp)) > 0)
plugin->helper->message_set_body(message->message, buf,
mbox->helper->message_set_body(message->message, buf,
size, 1);
free(buf);
}
@ -290,7 +307,8 @@ static int _mbox_refresh(AccountPlugin * plugin, AccountFolder * folder,
/* AccountMessage */
/* functions */
/* message_new */
static AccountMessage * _message_new(Folder * folder, off_t offset)
static AccountMessage * _message_new(AccountPluginHelper * helper,
Folder * folder, off_t offset)
{
AccountMessage * message;
@ -299,8 +317,9 @@ static AccountMessage * _message_new(Folder * folder, off_t offset)
/* FIXME catch error */
return NULL;
}
message->message = account_plugin.helper->message_new(
account_plugin.helper->account, folder, message);
message->helper = helper;
message->message = helper->message_new(helper->account, folder,
message);
message->offset = offset;
message->body_offset = 0;
message->body_length = 0;
@ -316,7 +335,7 @@ static AccountMessage * _message_new(Folder * folder, off_t offset)
/* message_delete */
static void _message_delete(AccountMessage * message)
{
account_plugin.helper->message_delete(message->message);
message->helper->message_delete(message->message);
free(message);
}
@ -338,8 +357,7 @@ static int _message_set_body(AccountMessage * message, off_t offset,
/* message_set_header */
static int _message_set_header(AccountMessage * message, char const * header)
{
return account_plugin.helper->message_set_header(message->message,
header);
return message->helper->message_set_header(message->message, header);
}
@ -361,7 +379,7 @@ static gboolean _folder_idle(gpointer data)
return FALSE;
if(stat(filename, &st) != 0)
{
mbox->plugin->helper->error(NULL, strerror(errno), 1);
mbox->helper->error(NULL, strerror(errno), 1);
folder->source = g_timeout_add(mbox->timeout, _folder_idle,
folder);
return FALSE;
@ -377,7 +395,7 @@ static gboolean _folder_idle(gpointer data)
if((folder->channel = g_io_channel_new_file(filename, "r",
&error)) == NULL)
{
mbox->plugin->helper->error(NULL, error->message, 1);
mbox->helper->error(NULL, error->message, 1);
folder->source = g_timeout_add(mbox->timeout, _folder_idle,
folder);
return FALSE;
@ -424,7 +442,7 @@ static gboolean _folder_watch(GIOChannel * source, GIOCondition condition,
switch(status)
{
case G_IO_STATUS_ERROR:
mbox->plugin->helper->error(NULL, error->message, 1);
mbox->helper->error(NULL, error->message, 1);
/* FIXME new timeout 1000 function after invalidating
* mtime */
return FALSE;
@ -596,7 +614,8 @@ static AccountMessage * _folder_message_add(AccountFolder * folder,
return NULL;
}
folder->messages = p;
if((message = _message_new(folder->folder, offset)) == NULL)
if((message = _message_new(folder->mbox->helper, folder->folder,
offset)) == NULL)
{
/* FIXME track error */
return NULL;

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
static char const _nntp_type[] = "NNTP";
static char const _nntp_name[] = "Newsgroups";
static AccountConfig _nntp_config[] =
static AccountConfig const _nntp_config[] =
{
{ "username", "Username", ACT_STRING, NULL },
{ "password", "Password", ACT_PASSWORD, NULL },
@ -37,12 +37,12 @@ static AccountConfig _nntp_config[] =
/* functions */
AccountPlugin account_plugin =
AccountPluginDefinition account_plugin =
{
NULL,
_nntp_type,
_nntp_name,
NULL,
NULL,
_nntp_config,
NULL,
NULL,

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -103,8 +103,12 @@ typedef struct _POP3Command
} data;
} POP3Command;
typedef struct _POP3
typedef struct _AccountPlugin
{
AccountPluginHelper * helper;
AccountConfig * config;
int fd;
SSL * ssl;
guint source;
@ -142,22 +146,23 @@ static AccountConfig _pop3_config[P3CV_COUNT + 1] =
/* prototypes */
/* plug-in */
static int _pop3_init(AccountPlugin * plugin);
static int _pop3_destroy(AccountPlugin * plugin);
static int _pop3_refresh(AccountPlugin * plugin, AccountFolder * folder,
static POP3 * _pop3_init(AccountPluginHelper * helper);
static int _pop3_destroy(POP3 * pop3);
static AccountConfig * _pop3_get_config(POP3 * pop3);
static int _pop3_refresh(POP3 * pop3, AccountFolder * folder,
AccountMessage * message);
/* useful */
static POP3Command * _pop3_command(AccountPlugin * plugin, POP3Context context,
static POP3Command * _pop3_command(POP3 * pop3, POP3Context context,
char const * command);
static int _pop3_parse(AccountPlugin * plugin);
static void _pop3_reset(AccountPlugin * plugin);
static int _pop3_parse(POP3 * pop3);
static void _pop3_reset(POP3 * pop3);
static AccountMessage * _pop3_message_get(AccountPlugin * plugin,
static AccountMessage * _pop3_message_get(POP3 * pop3,
AccountFolder * folder, unsigned int id);
static AccountMessage * _pop3_message_new(AccountPlugin * plugin,
static AccountMessage * _pop3_message_new(POP3 * pop3,
AccountFolder * folder, unsigned int id);
static void _pop3_message_delete(AccountPlugin * plugin,
static void _pop3_message_delete(POP3 * pop3,
AccountMessage * message);
/* callbacks */
@ -180,61 +185,72 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
/* public */
/* variables */
AccountPlugin account_plugin =
AccountPluginDefinition account_plugin =
{
NULL,
_pop3_type,
_pop3_name,
NULL,
NULL,
_pop3_config,
_pop3_init,
_pop3_destroy,
_pop3_get_config,
NULL,
_pop3_refresh,
NULL
_pop3_refresh
};
/* private */
/* functions */
/* pop3_init */
static int _pop3_init(AccountPlugin * plugin)
static POP3 * _pop3_init(AccountPluginHelper * helper)
{
POP3 * pop3;
if((pop3 = malloc(sizeof(*pop3))) == NULL)
return -1;
return NULL;
memset(pop3, 0, sizeof(*pop3));
plugin->priv = pop3;
pop3->helper = helper;
if((pop3->config = malloc(sizeof(_pop3_config))) == NULL)
{
free(pop3);
return NULL;
}
memcpy(pop3->config, &_pop3_config, sizeof(_pop3_config));
pop3->fd = -1;
pop3->inbox.folder = plugin->helper->folder_new(plugin->helper->account,
pop3->inbox.folder = pop3->helper->folder_new(pop3->helper->account,
&pop3->inbox, NULL, FT_INBOX, "Inbox");
pop3->trash.folder = plugin->helper->folder_new(plugin->helper->account,
pop3->trash.folder = pop3->helper->folder_new(pop3->helper->account,
&pop3->trash, NULL, FT_TRASH, "Trash");
pop3->source = g_idle_add(_on_connect, plugin);
return 0;
pop3->source = g_idle_add(_on_connect, pop3);
return pop3;
}
/* pop3_destroy */
static int _pop3_destroy(AccountPlugin * plugin)
static int _pop3_destroy(POP3 * pop3)
{
POP3 * pop3 = plugin->priv;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(pop3 == NULL) /* XXX _pop3_destroy() may be called uninitialized */
return 0;
_pop3_reset(plugin);
_pop3_reset(pop3);
free(pop3);
return 0;
}
/* pop3_get_config */
static AccountConfig * _pop3_get_config(POP3 * pop3)
{
return pop3->config;
}
/* pop3_refresh */
static int _pop3_refresh(AccountPlugin * plugin, AccountFolder * folder,
static int _pop3_refresh(POP3 * pop3, AccountFolder * folder,
AccountMessage * message)
{
char buf[32];
@ -243,7 +259,7 @@ static int _pop3_refresh(AccountPlugin * plugin, AccountFolder * folder,
if(message == NULL)
return 0;
snprintf(buf, sizeof(buf), "%s %u", "RETR", message->id);
if((cmd = _pop3_command(plugin, P3C_TRANSACTION_RETR, buf)) == NULL)
if((cmd = _pop3_command(pop3, P3C_TRANSACTION_RETR, buf)) == NULL)
return -1;
cmd->data.transaction_retr.id = message->id;
return 0;
@ -252,10 +268,9 @@ static int _pop3_refresh(AccountPlugin * plugin, AccountFolder * folder,
/* useful */
/* pop3_command */
static POP3Command * _pop3_command(AccountPlugin * plugin, POP3Context context,
static POP3Command * _pop3_command(POP3 * pop3, POP3Context context,
char const * command)
{
POP3 * pop3 = plugin->priv;
POP3Command * p;
size_t len;
@ -292,22 +307,21 @@ static POP3Command * _pop3_command(AccountPlugin * plugin, POP3Context context,
}
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
(pop3->ssl != NULL) ? _on_watch_can_write_ssl
: _on_watch_can_write, plugin);
: _on_watch_can_write, pop3);
}
return p;
}
/* pop3_parse */
static int _parse_context(AccountPlugin * plugin, char const * answer);
static int _parse_context_transaction_retr(AccountPlugin * plugin,
static int _parse_context(POP3 * pop3, char const * answer);
static int _parse_context_transaction_retr(POP3 * pop3,
char const * answer);
static int _pop3_parse(AccountPlugin * plugin)
static int _pop3_parse(POP3 * pop3)
{
int ret = 0;
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
AccountPluginHelper * helper = pop3->helper;
size_t i;
size_t j;
@ -334,7 +348,7 @@ static int _pop3_parse(AccountPlugin * plugin)
else if(pop3->queue[0].status == P3CS_SENT
&& strncmp("+OK", &pop3->rd_buf[j], 3) == 0)
pop3->queue[0].status = P3CS_PARSING;
if(_parse_context(plugin, &pop3->rd_buf[j]) != 0)
if(_parse_context(pop3, &pop3->rd_buf[j]) != 0)
{
pop3->queue[0].status = P3CS_ERROR;
ret = -1;
@ -348,10 +362,9 @@ static int _pop3_parse(AccountPlugin * plugin)
return ret;
}
static int _parse_context(AccountPlugin * plugin, char const * answer)
static int _parse_context(POP3 * pop3, char const * answer)
{
int ret = -1;
POP3 * pop3 = plugin->priv;
POP3Command * cmd = &pop3->queue[0];
char const * p;
char * q;
@ -368,27 +381,27 @@ static int _parse_context(AccountPlugin * plugin, char const * answer)
if(cmd->status != P3CS_PARSING)
return 0;
cmd->status = P3CS_OK;
if((p = plugin->config[0].value) == NULL)
if((p = pop3->config[0].value) == NULL)
return -1;
q = g_strdup_printf("%s %s", "USER", p);
cmd = _pop3_command(plugin, P3C_AUTHORIZATION_USER, q);
cmd = _pop3_command(pop3, P3C_AUTHORIZATION_USER, q);
g_free(q);
return (cmd != NULL) ? 0 : -1;
case P3C_AUTHORIZATION_USER:
if(cmd->status != P3CS_PARSING)
return 0;
cmd->status = P3CS_OK;
if((p = plugin->config[1].value) == NULL)
if((p = pop3->config[1].value) == NULL)
p = ""; /* assumes an empty password */
q = g_strdup_printf("%s %s", "PASS", p);
cmd = _pop3_command(plugin, P3C_AUTHORIZATION_PASS, q);
cmd = _pop3_command(pop3, P3C_AUTHORIZATION_PASS, q);
g_free(q);
return (cmd != NULL) ? 0 : -1;
case P3C_AUTHORIZATION_PASS:
if(cmd->status != P3CS_PARSING)
return 0;
cmd->status = P3CS_OK;
return (_pop3_command(plugin, P3C_TRANSACTION_STAT,
return (_pop3_command(pop3, P3C_TRANSACTION_STAT,
"STAT") != NULL) ? 0 : -1;
case P3C_NOOP:
if(strncmp(answer, "+OK", 3) == 0)
@ -408,30 +421,29 @@ static int _parse_context(AccountPlugin * plugin, char const * answer)
return -1;
/* FIXME may not be supported by the server */
q = g_strdup_printf("%s %u 0", "TOP", u);
cmd = _pop3_command(plugin, P3C_TRANSACTION_TOP, q);
cmd = _pop3_command(pop3, P3C_TRANSACTION_TOP, q);
free(q);
cmd->data.transaction_top.id = u;
return (cmd != NULL) ? 0 : -1;
case P3C_TRANSACTION_RETR:
case P3C_TRANSACTION_TOP: /* same as RETR without the body */
return _parse_context_transaction_retr(plugin, answer);
return _parse_context_transaction_retr(pop3, answer);
case P3C_TRANSACTION_STAT:
if(cmd->status != P3CS_PARSING)
return 0;
if(sscanf(answer, "+OK %u %u", &u, &v) != 2)
return -1;
cmd->status = P3CS_OK;
return (_pop3_command(plugin, P3C_TRANSACTION_LIST,
return (_pop3_command(pop3, P3C_TRANSACTION_LIST,
"LIST") != NULL) ? 0 : -1;
}
return ret;
}
static int _parse_context_transaction_retr(AccountPlugin * plugin,
static int _parse_context_transaction_retr(POP3 * pop3,
char const * answer)
{
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
AccountPluginHelper * helper = pop3->helper;
POP3Command * cmd = &pop3->queue[0];
AccountMessage * message;
@ -441,7 +453,7 @@ static int _parse_context_transaction_retr(AccountPlugin * plugin,
&& strncmp(answer, "+OK", 3) == 0)
{
cmd->data.transaction_retr.body = FALSE;
message = _pop3_message_get(plugin, &pop3->inbox,
message = _pop3_message_get(pop3, &pop3->inbox,
cmd->data.transaction_retr.id);
cmd->data.transaction_retr.message = message;
return 0;
@ -470,9 +482,8 @@ static int _parse_context_transaction_retr(AccountPlugin * plugin,
/* pop3_reset */
static void _pop3_reset(AccountPlugin * plugin)
static void _pop3_reset(POP3 * pop3)
{
POP3 * pop3 = plugin->priv;
size_t i;
if(pop3->rd_source != 0)
@ -497,7 +508,7 @@ static void _pop3_reset(AccountPlugin * plugin)
/* pop3_message_get */
static AccountMessage * _pop3_message_get(AccountPlugin * plugin,
static AccountMessage * _pop3_message_get(POP3 * pop3,
AccountFolder * folder, unsigned int id)
{
size_t i;
@ -505,15 +516,15 @@ static AccountMessage * _pop3_message_get(AccountPlugin * plugin,
for(i = 0; i < folder->messages_cnt; i++)
if(folder->messages[i]->id == id)
return folder->messages[i];
return _pop3_message_new(plugin, folder, id);
return _pop3_message_new(pop3, folder, id);
}
/* pop3_message_new */
static AccountMessage * _pop3_message_new(AccountPlugin * plugin,
static AccountMessage * _pop3_message_new(POP3 * pop3,
AccountFolder * folder, unsigned int id)
{
AccountPluginHelper * helper = plugin->helper;
AccountPluginHelper * helper = pop3->helper;
AccountMessage * message;
AccountMessage ** p;
@ -527,7 +538,7 @@ static AccountMessage * _pop3_message_new(AccountPlugin * plugin,
if((message->message = helper->message_new(helper->account,
folder->folder, message)) == NULL)
{
_pop3_message_delete(plugin, message);
_pop3_message_delete(pop3, message);
return NULL;
}
folder->messages[folder->messages_cnt++] = message;
@ -536,37 +547,35 @@ static AccountMessage * _pop3_message_new(AccountPlugin * plugin,
/* pop3_message_delete */
static void _pop3_message_delete(AccountPlugin * plugin,
static void _pop3_message_delete(POP3 * pop3,
AccountMessage * message)
{
if(message->message != NULL)
plugin->helper->message_delete(message->message);
pop3->helper->message_delete(message->message);
object_delete(message);
}
/* callbacks */
/* on_idle */
static int _connect_channel(AccountPlugin * plugin);
static int _connect_channel(POP3 * pop3);
static gboolean _on_connect(gpointer data)
{
AccountPlugin * plugin = data;
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
AccountPluginHelper * helper = pop3->helper;
char const * hostname;
char const * p;
struct hostent * he;
unsigned short port;
struct sockaddr_in sa;
int res;
char buf[128];
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
pop3->source = 0;
if((hostname = plugin->config[P3CV_HOSTNAME].value) == NULL)
if((hostname = pop3->config[P3CV_HOSTNAME].value) == NULL)
{
helper->error(NULL, "No hostname set", 1);
return FALSE;
@ -574,15 +583,15 @@ static gboolean _on_connect(gpointer data)
if((he = gethostbyname(hostname)) == NULL)
{
helper->error(NULL, hstrerror(h_errno), 1);
return _on_reset(plugin);
return _on_reset(pop3);
}
if((p = plugin->config[P3CV_PORT].value) == NULL)
if((p = pop3->config[P3CV_PORT].value) == NULL)
return FALSE;
port = (unsigned long)p;
if((pop3->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
helper->error(NULL, strerror(errno), 1);
return _on_reset(plugin);
return _on_reset(pop3);
}
if((res = fcntl(pop3->fd, F_GETFL)) >= 0
&& fcntl(pop3->fd, F_SETFL, res | O_NONBLOCK) == -1)
@ -595,20 +604,19 @@ static gboolean _on_connect(gpointer data)
inet_ntoa(sa.sin_addr), port);
if((connect(pop3->fd, (struct sockaddr *)&sa, sizeof(sa)) != 0
&& errno != EINPROGRESS)
|| _connect_channel(plugin) != 0)
|| _connect_channel(pop3) != 0)
{
helper->error(NULL, strerror(errno), 1);
return _on_reset(plugin);
return _on_reset(pop3);
}
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
_on_watch_can_connect, plugin);
_on_watch_can_connect, pop3);
return FALSE;
}
static int _connect_channel(AccountPlugin * plugin)
static int _connect_channel(POP3 * pop3)
{
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
AccountPluginHelper * helper = pop3->helper;
GError * error = NULL;
#ifdef DEBUG
@ -633,10 +641,9 @@ static int _connect_channel(AccountPlugin * plugin)
/* on_noop */
static gboolean _on_noop(gpointer data)
{
AccountPlugin * plugin = data;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
_pop3_command(plugin, P3C_NOOP, "NOOP");
_pop3_command(pop3, P3C_NOOP, "NOOP");
pop3->source = 0;
return FALSE;
}
@ -645,14 +652,13 @@ static gboolean _on_noop(gpointer data)
/* on_reset */
static gboolean _on_reset(gpointer data)
{
AccountPlugin * plugin = data;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
_pop3_reset(plugin);
pop3->source = g_timeout_add(3000, _on_connect, plugin);
_pop3_reset(pop3);
pop3->source = g_timeout_add(3000, _on_connect, pop3);
return FALSE;
}
@ -661,9 +667,8 @@ static gboolean _on_reset(gpointer data)
static gboolean _on_watch_can_connect(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
AccountPluginHelper * helper = pop3->helper;
SSL_CTX * ssl_ctx;
char buf[128];
@ -674,7 +679,7 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
#endif
pop3->wr_source = 0;
/* setup SSL */
if(plugin->config[P3CV_SSL].value != NULL)
if(pop3->config[P3CV_SSL].value != NULL)
{
if((ssl_ctx = helper->get_ssl_context(helper->account)) == NULL)
/* FIXME report error */
@ -690,25 +695,24 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
SSL_set_connect_state(pop3->ssl);
/* perform initial handshake */
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
_on_watch_can_handshake, plugin);
_on_watch_can_handshake, pop3);
return FALSE;
}
/* wait for the server's banner */
pop3->rd_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_read, plugin);
_on_watch_can_read, pop3);
return FALSE;
}
/* on_watch_can_handshake */
static int _handshake_verify(AccountPlugin * plugin);
static int _handshake_verify(POP3 * pop3);
static gboolean _on_watch_can_handshake(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
AccountPluginHelper * helper = pop3->helper;
int res;
int err;
char buf[128];
@ -723,11 +727,11 @@ static gboolean _on_watch_can_handshake(GIOChannel * source,
pop3->rd_source = 0;
if((res = SSL_do_handshake(pop3->ssl)) == 1)
{
if(_handshake_verify(plugin) != 0)
return _on_reset(plugin);
if(_handshake_verify(pop3) != 0)
return _on_reset(pop3);
/* wait for the server's banner */
pop3->rd_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_read_ssl, plugin);
_on_watch_can_read_ssl, pop3);
return FALSE;
}
err = SSL_get_error(pop3->ssl, res);
@ -735,26 +739,25 @@ static gboolean _on_watch_can_handshake(GIOChannel * source,
if(res == 0)
{
helper->error(helper->account, buf, 1);
return _on_reset(plugin);
return _on_reset(pop3);
}
if(err == SSL_ERROR_WANT_WRITE)
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
_on_watch_can_handshake, plugin);
_on_watch_can_handshake, pop3);
else if(err == SSL_ERROR_WANT_READ)
pop3->rd_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_handshake, plugin);
_on_watch_can_handshake, pop3);
else
{
helper->error(helper->account, buf, 1);
return _on_reset(plugin);
return _on_reset(pop3);
}
return FALSE;
}
static int _handshake_verify(AccountPlugin * plugin)
static int _handshake_verify(POP3 * pop3)
{
AccountPluginHelper * helper = plugin->helper;
POP3 * pop3 = plugin->priv;
AccountPluginHelper * helper = pop3->helper;
X509 * x509;
char buf[256] = "";
@ -764,7 +767,7 @@ static int _handshake_verify(AccountPlugin * plugin)
x509 = SSL_get_peer_certificate(pop3->ssl);
X509_NAME_get_text_by_NID(X509_get_subject_name(x509), NID_commonName,
buf, sizeof(buf));
if(strcasecmp(buf, plugin->config[P3CV_HOSTNAME].value) != 0)
if(strcasecmp(buf, pop3->config[P3CV_HOSTNAME].value) != 0)
return helper->confirm(helper->account, "The certificate could"
" not be matched.\nConnect anyway?");
return 0;
@ -775,8 +778,7 @@ static int _handshake_verify(AccountPlugin * plugin)
static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
gpointer data)
{
AccountPlugin * plugin = data;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
char * p;
gsize cnt = 0;
GError * error = NULL;
@ -800,15 +802,15 @@ static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
case G_IO_STATUS_NORMAL:
break;
case G_IO_STATUS_ERROR:
plugin->helper->error(NULL, error->message, 1);
pop3->helper->error(NULL, error->message, 1);
case G_IO_STATUS_EOF:
default:
pop3->rd_source = g_idle_add(_on_reset, plugin);
pop3->rd_source = g_idle_add(_on_reset, pop3);
return FALSE;
}
if(_pop3_parse(plugin) != 0)
if(_pop3_parse(pop3) != 0)
{
pop3->rd_source = g_idle_add(_on_reset, plugin);
pop3->rd_source = g_idle_add(_on_reset, pop3);
return FALSE;
}
if(pop3->queue_cnt == 0)
@ -827,10 +829,10 @@ static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
}
pop3->rd_source = 0;
if(pop3->queue_cnt == 0)
pop3->source = g_timeout_add(30000, _on_noop, plugin);
pop3->source = g_timeout_add(30000, _on_noop, pop3);
else
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
_on_watch_can_write, plugin);
_on_watch_can_write, pop3);
return FALSE;
}
@ -839,8 +841,7 @@ static gboolean _on_watch_can_read(GIOChannel * source, GIOCondition condition,
static gboolean _on_watch_can_read_ssl(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
char * p;
int cnt;
POP3Command * cmd;
@ -862,20 +863,19 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
== SSL_ERROR_WANT_WRITE)
{
pop3->rd_source = g_io_add_watch(pop3->channel,
G_IO_OUT, _on_watch_can_read_ssl,
plugin);
G_IO_OUT, _on_watch_can_read_ssl, pop3);
return FALSE;
}
else if(cnt < 0 && SSL_get_error(pop3->ssl, cnt)
== SSL_ERROR_WANT_READ)
{
pop3->rd_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_read_ssl, plugin);
_on_watch_can_read_ssl, pop3);
return FALSE;
}
ERR_error_string(SSL_get_error(pop3->ssl, cnt), buf);
plugin->helper->error(NULL, buf, 1);
pop3->rd_source = g_idle_add(_on_reset, plugin);
pop3->helper->error(NULL, buf, 1);
pop3->rd_source = g_idle_add(_on_reset, pop3);
return FALSE;
}
#ifdef DEBUG
@ -883,9 +883,9 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
fwrite(&pop3->rd_buf[pop3->rd_buf_cnt], sizeof(*p), cnt, stderr);
#endif
pop3->rd_buf_cnt += cnt;
if(_pop3_parse(plugin) != 0)
if(_pop3_parse(pop3) != 0)
{
pop3->rd_source = g_idle_add(_on_reset, plugin);
pop3->rd_source = g_idle_add(_on_reset, pop3);
return FALSE;
}
if(pop3->queue_cnt == 0)
@ -904,10 +904,10 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
}
pop3->rd_source = 0;
if(pop3->queue_cnt == 0)
pop3->source = g_timeout_add(30000, _on_noop, plugin);
pop3->source = g_timeout_add(30000, _on_noop, pop3);
else
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
_on_watch_can_write_ssl, plugin);
_on_watch_can_write_ssl, pop3);
return FALSE;
}
@ -916,8 +916,7 @@ static gboolean _on_watch_can_read_ssl(GIOChannel * source,
static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
gpointer data)
{
AccountPlugin * plugin = data;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
POP3Command * cmd = &pop3->queue[0];
gsize cnt = 0;
GError * error = NULL;
@ -947,10 +946,10 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
case G_IO_STATUS_NORMAL:
break;
case G_IO_STATUS_ERROR:
plugin->helper->error(NULL, error->message, 1);
pop3->helper->error(NULL, error->message, 1);
case G_IO_STATUS_EOF:
default:
pop3->wr_source = g_idle_add(_on_reset, plugin);
pop3->wr_source = g_idle_add(_on_reset, pop3);
return FALSE;
}
if(cmd->buf_cnt > 0)
@ -959,7 +958,7 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
pop3->wr_source = 0;
if(pop3->rd_source == 0)
pop3->rd_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_read, plugin);
_on_watch_can_read, pop3);
return FALSE;
}
@ -968,8 +967,7 @@ static gboolean _on_watch_can_write(GIOChannel * source, GIOCondition condition,
static gboolean _on_watch_can_write_ssl(GIOChannel * source,
GIOCondition condition, gpointer data)
{
AccountPlugin * plugin = data;
POP3 * pop3 = plugin->priv;
POP3 * pop3 = data;
POP3Command * cmd = &pop3->queue[0];
int cnt;
char * p;
@ -986,7 +984,7 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
== SSL_ERROR_WANT_READ)
{
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_write_ssl, plugin);
_on_watch_can_write_ssl, pop3);
return FALSE;
}
else if(cnt < 0 && SSL_get_error(pop3->ssl, cnt)
@ -994,12 +992,12 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
{
pop3->wr_source = g_io_add_watch(pop3->channel,
G_IO_OUT, _on_watch_can_write_ssl,
plugin);
pop3);
return FALSE;
}
ERR_error_string(SSL_get_error(pop3->ssl, cnt), buf);
plugin->helper->error(NULL, buf, 1);
pop3->wr_source = g_idle_add(_on_reset, plugin);
pop3->helper->error(NULL, buf, 1);
pop3->wr_source = g_idle_add(_on_reset, pop3);
return FALSE;
}
#ifdef DEBUG
@ -1018,6 +1016,6 @@ static gboolean _on_watch_can_write_ssl(GIOChannel * source,
pop3->wr_source = 0;
if(pop3->rd_source == 0)
pop3->rd_source = g_io_add_watch(pop3->channel, G_IO_IN,
_on_watch_can_read_ssl, plugin);
_on_watch_can_read_ssl, pop3);
return FALSE;
}

View File

@ -1,5 +1,5 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011-2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Mailer */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
static char const _rss_type[] = "RSS";
static char const _rss_name[] = "RSS reader";
static AccountConfig _rss_config[] =
static AccountConfig const _rss_config[] =
{
{ "uri", "Address", ACT_STRING, NULL },
{ NULL, NULL, ACT_NONE, NULL }
@ -33,12 +33,12 @@ static AccountConfig _rss_config[] =
/* functions */
AccountPlugin account_plugin =
AccountPluginDefinition account_plugin =
{
NULL,
_rss_type,
_rss_name,
NULL,
NULL,
_rss_config,
NULL,
NULL,

View File

@ -2981,8 +2981,12 @@ static int _mailer_config_load_account(Mailer * mailer, char const * name)
if((account = account_new(mailer, type, name, mailer->fo_store))
== NULL)
return -mailer_error(mailer, error_get(), 1);
if(mailer_account_add(mailer, account) != 0)
{
account_delete(account);
return -1;
}
account_config_load(account, mailer->config);
mailer_account_add(mailer, account);
return 0;
}