diff options
Diffstat (limited to 'camel/providers/imapp')
23 files changed, 0 insertions, 7308 deletions
diff --git a/camel/providers/imapp/.cvsignore b/camel/providers/imapp/.cvsignore deleted file mode 100644 index 3fa8afaa38..0000000000 --- a/camel/providers/imapp/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -Makefile -Makefile.in -.libs -.deps -*.lo -*.la -*.bb -*.bbg -*.da -*.gcov diff --git a/camel/providers/imapp/Makefile.am b/camel/providers/imapp/Makefile.am deleted file mode 100644 index 7ce8c65fcd..0000000000 --- a/camel/providers/imapp/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -## Process this file with automake to produce Makefile.in - -libcamelimappincludedir = $(privincludedir)/camel - -camel_provider_LTLIBRARIES = libcamelimapp.la -camel_provider_DATA = libcamelimapp.urls - -INCLUDES = -I.. \ - -I$(srcdir)/.. \ - -I$(top_srcdir)/camel \ - -I$(top_srcdir)/intl \ - -I$(top_srcdir)/e-util \ - -I$(top_srcdir) \ - $(CAMEL_CFLAGS) \ - $(GNOME_INCLUDEDIR) \ - $(GTK_INCLUDEDIR) \ - -DG_LOG_DOMAIN=\"camel-imapp-provider\" - -libcamelimapp_la_SOURCES = \ - camel-imapp-utils.c \ - camel-imapp-engine.c \ - camel-imapp-stream.c \ - camel-imapp-store.c \ - camel-imapp-folder.c \ - camel-imapp-provider.c \ - camel-imapp-store-summary.c \ - camel-imapp-driver.c \ - camel-imapp-summary.c - -libcamelimappinclude_HEADERS = \ - camel-imapp-utils.h \ - camel-imapp-engine.h \ - camel-imapp-stream.h \ - camel-imapp-store.h \ - camel-imapp-folder.h \ - camel-imapp-store-summary.h \ - camel-imapp-driver.h \ - camel-imapp-summary.h - -libcamelimapp_la_LDFLAGS = -avoid-version -module - -#noinst_HEADERS = \ -# camel-imap-private.h - -EXTRA_DIST = libcamelimapp.urls diff --git a/camel/providers/imapp/camel-imapp-driver.c b/camel/providers/imapp/camel-imapp-driver.c deleted file mode 100644 index 106e98fbb3..0000000000 --- a/camel/providers/imapp/camel-imapp-driver.c +++ /dev/null @@ -1,771 +0,0 @@ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <ctype.h> - -#include "camel-imapp-driver.h" -#include "camel-imapp-utils.h" -#include "camel-imapp-folder.h" -#include "camel-imapp-engine.h" -#include "camel-imapp-summary.h" -#include "camel-imapp-exception.h" - -#include <camel/camel-stream-mem.h> -#include <camel/camel-stream-null.h> - -#include <camel/camel-folder-summary.h> -#include <camel/camel-store.h> -#include <camel/camel-mime-utils.h> -#include <camel/camel-sasl.h> - -#define d(x) x - -static int driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata); -static int driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata); -static int driver_resp_exists(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata); -static int driver_resp_list(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata); - -static void driver_status(CamelIMAPPEngine *ie, struct _status_info *sinfo, CamelIMAPPDriver *sdata); - -static void -class_init(CamelIMAPPDriverClass *ieclass) -{ -} - -static void -object_init(CamelIMAPPDriver *ie, CamelIMAPPDriverClass *ieclass) -{ - ie->summary = g_ptr_array_new(); - e_dlist_init(&ie->body_fetch); - e_dlist_init(&ie->body_fetch_done); -} - -static void -object_finalise(CamelIMAPPDriver *ie, CamelIMAPPDriverClass *ieclass) -{ - if (ie->folder) - camel_object_unref((CamelObject *)ie->folder); - if (ie->engine) - camel_object_unref((CamelObject *)ie->engine); - if (ie->summary) - g_ptr_array_free(ie->summary, TRUE); -} - -CamelType -camel_imapp_driver_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register ( - camel_object_get_type (), - "CamelIMAPPDriver", - sizeof (CamelIMAPPDriver), - sizeof (CamelIMAPPDriverClass), - (CamelObjectClassInitFunc) class_init, - NULL, - (CamelObjectInitFunc) object_init, - (CamelObjectFinalizeFunc) object_finalise); - } - - return type; -} - -CamelIMAPPDriver * -camel_imapp_driver_new(CamelIMAPPStream *stream) -{ - CamelIMAPPDriver *driver; - CamelIMAPPEngine *ie; - - driver = CAMEL_IMAPP_DRIVER (camel_object_new (CAMEL_IMAPP_DRIVER_TYPE)); - ie = driver->engine = camel_imapp_engine_new(stream); - - camel_imapp_engine_add_handler(ie, "FETCH", (CamelIMAPPEngineFunc)driver_resp_fetch, driver); - camel_imapp_engine_add_handler(ie, "EXPUNGE", (CamelIMAPPEngineFunc)driver_resp_expunge, driver); - camel_imapp_engine_add_handler(ie, "EXISTS", (CamelIMAPPEngineFunc)driver_resp_exists, driver); - camel_imapp_engine_add_handler(ie, "LIST", (CamelIMAPPEngineFunc)driver_resp_list, driver); - camel_object_hook_event(ie, "status", (CamelObjectEventHookFunc)driver_status, driver); - - return driver; -} - -void -camel_imapp_driver_set_sasl_factory(CamelIMAPPDriver *id, CamelIMAPPSASLFunc get_sasl, void *sasl_data) -{ - id->get_sasl = get_sasl; - id->get_sasl_data = sasl_data; -} - -void -camel_imapp_driver_set_login_query(CamelIMAPPDriver *id, CamelIMAPPLoginFunc get_login, void *login_data) -{ - id->get_login = get_login; - id->get_login_data = login_data; -} - -void -camel_imapp_driver_login(CamelIMAPPDriver *id) -/* throws SERVICE_CANT_AUTHENTICATE, SYSTEM_IO */ -{ - CamelIMAPPCommand * volatile ic = NULL; - - /* connect? */ - /* camel_imapp_engine_connect() */ - /* or above? */ - - CAMEL_TRY { - CamelSasl *sasl; - - if (id->get_sasl - && (sasl = id->get_sasl(id, id->get_sasl_data))) { - ic = camel_imapp_engine_command_new(id->engine, "AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl); - camel_object_unref(sasl); - } else { - char *user, *pass; - - g_assert(id->get_login); - id->get_login(id, &user, &pass, id->get_login_data); - ic = camel_imapp_engine_command_new(id->engine, "LOGIN", NULL, "LOGIN %s %s", user, pass); - g_free(user); - g_free(pass); - } - - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic) > 0) - ; - - if (ic->status->result != IMAP_OK) - camel_exception_throw(CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, "Login failed: %s", ic->status->text); - camel_imapp_engine_command_free(id->engine, ic); - } CAMEL_CATCH(ex) { - if (ic) - camel_imapp_engine_command_free(id->engine, ic); - camel_exception_throw_ex(ex); - } CAMEL_DONE; -} - -void -camel_imapp_driver_select(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder) -{ - CamelIMAPPSelectResponse *sr; - CamelIMAPPCommand * volatile ic = NULL; - CamelIMAPPCommand * volatile ic2 = NULL; - guint32 count; - CamelFolderSummary *summary; - - if (id->folder) { - if (folder == id->folder) - return; - camel_imapp_driver_sync(id, FALSE, id->folder); - if (camel_folder_change_info_changed(id->folder->changes)) { - camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes); - camel_folder_change_info_clear(id->folder->changes); - } - camel_object_unref(id->folder); - id->folder = NULL; - } - - summary = ((CamelFolder *)folder)->summary; - - ic = camel_imapp_engine_command_new(id->engine, "SELECT", NULL, "SELECT %t", folder->raw_name); - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - - id->folder = folder; - camel_object_ref(folder); - - count = camel_folder_summary_count(summary); - if (count > 0 && count <= id->exists) { - ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL, - "FETCH 1:%u (UID FLAGS)", count); - camel_imapp_engine_command_queue(id->engine, ic); - if (count < id->exists) { - ic2 = camel_imapp_engine_command_new(id->engine, "FETCH", NULL, - "FETCH %u:* (UID FLAGS ENVELOPE)", count+1); - camel_imapp_engine_command_queue(id->engine, ic2); - } else { - ic2 = NULL; - } - - while (camel_imapp_engine_iterate(id->engine, ic2?ic2:ic)>0) - ; - - camel_imapp_engine_command_free(id->engine, ic); - if (ic2) - camel_imapp_engine_command_free(id->engine, ic2); - } else { - ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL, - "FETCH 1:* (UID FLAGS ENVELOPE)"); - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - } - - /* TODO: need to set exists/etc in summary */ - folder->exists = id->exists; - folder->uidvalidity = id->uidvalidity; - - printf("saving summary '%s'\n", summary->summary_path); - camel_folder_summary_save(summary); - - if (camel_folder_change_info_changed(id->folder->changes)) { - camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes); - camel_folder_change_info_clear(id->folder->changes); - } -} - -static void -imapp_driver_check(CamelIMAPPDriver *id) -{ - guint32 count; - CamelIMAPPCommand *ic; - - /* FIXME: exception handling */ - - if (id->folder->exists != id->exists) { - count = camel_folder_summary_count(((CamelFolder *)id->folder)->summary); - if (count < id->exists) { - printf("fetching new messages\n"); - ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL, - "FETCH %u:* (UID FLAGS ENVELOPE)", count+1); - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - } else if (count > id->exists) { - printf("folder shrank with no expunge notificaitons!? uh, dunno what to do\n"); - } - } - - printf("checking for change info changes\n"); - if (camel_folder_change_info_changed(id->folder->changes)) { - printf("got somechanges! added=%d changed=%d removed=%d\n", - id->folder->changes->uid_added->len, - id->folder->changes->uid_changed->len, - id->folder->changes->uid_removed->len); - camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes); - camel_folder_change_info_clear(id->folder->changes); - } -} - -void -camel_imapp_driver_update(CamelIMAPPDriver *id, CamelIMAPPFolder *folder) -{ - if (id->folder == folder) { - CamelIMAPPCommand *ic; - - /* this will automagically update flags & expunge items */ - ic = camel_imapp_engine_command_new(id->engine, "NOOP", NULL, "NOOP"); - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - - imapp_driver_check(id); - } else { - camel_imapp_driver_select(id, folder); - } -} - -/* FIXME: this is basically a copy of the same in camel-imapp-utils.c */ -static struct { - char *name; - guint32 flag; -} flag_table[] = { - { "\\ANSWERED", CAMEL_MESSAGE_ANSWERED }, - { "\\DELETED", CAMEL_MESSAGE_DELETED }, - { "\\DRAFT", CAMEL_MESSAGE_DRAFT }, - { "\\FLAGGED", CAMEL_MESSAGE_FLAGGED }, - { "\\SEEN", CAMEL_MESSAGE_SEEN }, - /* { "\\RECENT", CAMEL_IMAPP_MESSAGE_RECENT }, */ -}; - -/* - flags 00101000 - sflags 01001000 - ^ 01100000 -~flags 11010111 -& 01000000 - -&flags 00100000 -*/ - -static void -imapp_write_flags(CamelIMAPPDriver *id, guint32 orset, gboolean on, CamelFolderSummary *summary) -{ - guint32 i, j, count; - CamelIMAPPMessageInfo *info; - CamelIMAPPCommand *ic = NULL; - struct _uidset_state ss; - GSList *commands = NULL; - - /* FIXME: exception handling */ - - count = camel_folder_summary_count(summary); - for (j=0;j<sizeof(flag_table)/sizeof(flag_table[0]);j++) { - int flush; - - if ((orset & flag_table[j].flag) == 0) - continue; - - printf("checking/storing %s flags '%s'\n", on?"on":"off", flag_table[j].name); - - flush = 0; - imapp_uidset_init(&ss, id->engine); - for (i=0;i<count;i++) { - info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i); - if (info) { - guint32 flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS; - guint32 sflags = info->server_flags & CAMEL_IMAPP_SERVER_FLAGS; - - if ( (on && (((flags ^ sflags) & flags) & flag_table[j].flag)) - || (!on && (((flags ^ sflags) & ~flags) & flag_table[j].flag))) { - if (ic == NULL) - ic = camel_imapp_engine_command_new(id->engine, "STORE", NULL, "UID STORE "); - flush = imapp_uidset_add(&ss, ic, camel_message_info_uid(info)); - } - camel_folder_summary_info_free(summary, (CamelMessageInfo *)info); - } - - if (i == count-1 && ic != NULL) - flush |= imapp_uidset_done(&ss, ic); - - if (flush) { - flush = 0; - camel_imapp_engine_command_add(id->engine, ic, " %tFLAGS.SILENT (%t)", on?"+":"-", flag_table[j].name); - camel_imapp_engine_command_queue(id->engine, ic); - commands = g_slist_prepend(commands, ic); - ic = NULL; - } - } - } - - /* flush off any requests we may have outstanding */ - /* TODO: for max benefit, should have this routine do both on and off flags in one go */ - while (commands) { - GSList *next = commands->next; - - ic = commands->data; - g_slist_free_1(commands); - commands = next; - - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - } -} - -void -camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder *folder) -{ - CamelFolderSummary *summary; - guint i, count, on_orset, off_orset; - CamelIMAPPMessageInfo *info; - CamelIMAPPCommand *ic; - - /* FIXME: exception handling */ - - camel_imapp_driver_update(id, folder); - - summary = ((CamelFolder *)folder)->summary; - count = camel_folder_summary_count(summary); - /* find out which flags have turned on, which have tunred off */ - off_orset = on_orset = 0; - for (i=0;i<count;i++) { - guint32 flags, sflags; - - info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i); - if (info == NULL) - continue; - flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS; - sflags = info->server_flags & CAMEL_IMAPP_SERVER_FLAGS; - if (flags != sflags) { - off_orset |= ( flags ^ sflags ) & ~flags; - on_orset |= (flags ^ sflags) & flags; - } - camel_folder_summary_info_free(summary, (CamelMessageInfo *)info); - } - - if (on_orset || off_orset) { - /* turn on or off all messages matching */ - if (on_orset) - imapp_write_flags(id, on_orset, TRUE, summary); - if (off_orset) - imapp_write_flags(id, off_orset, FALSE, summary); - - /* success (no exception), make sure we match what we're supposed to */ - for (i=0;i<count;i++) { - guint32 flags, sflags; - - info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, i); - if (info == NULL) - continue; - info->server_flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS; - camel_folder_summary_info_free(summary, (CamelMessageInfo *)info); - } - camel_folder_summary_touch(summary); - /* could save summary here, incase of failure? */ - } - - if (expunge) { - ic = camel_imapp_engine_command_new(id->engine, "EXPUNGE", NULL, "EXPUNGE"); - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - } - - printf("saving summary '%s'\n", summary->summary_path); - camel_folder_summary_save(summary); - - if (camel_folder_change_info_changed(id->folder->changes)) { - camel_object_trigger_event(id->folder, "folder_changed", id->folder->changes); - camel_folder_change_info_clear(id->folder->changes); - } -} - -struct _fetch_data { - struct _fetch_data *next; - struct _fetch_data *prev; - - CamelStream *data; - const char *uid; - const char *section; -}; - -CamelStream * -camel_imapp_driver_fetch(CamelIMAPPDriver *id, CamelIMAPPFolder *folder, const char *uid, const char *section) -{ - struct _fetch_data fd; - CamelIMAPPCommand *ic; - - fd.data = NULL; - fd.uid = uid; - fd.section = section; - e_dlist_addtail(&id->body_fetch, (EDListNode *)&fd); - - CAMEL_TRY { - camel_imapp_driver_select(id, folder); - - ic = camel_imapp_engine_command_new(id->engine, "FETCH", NULL, "UID FETCH %t (BODY.PEEK[%t])", uid, section); - camel_imapp_engine_command_queue(id->engine, ic); - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - imapp_driver_check(id); - } CAMEL_CATCH(e) { - /* FIXME: do exception properly */ - } CAMEL_DONE; - - e_dlist_remove((EDListNode *)&fd); - - return fd.data; -} - -GPtrArray * -camel_imapp_driver_list(CamelIMAPPDriver *id, const char *name, guint32 flags) -{ - CamelIMAPPCommand * volatile ic; - GPtrArray *res; - - g_assert(id->list_commands == NULL); - g_assert(id->list_result == NULL); - - /* FIXME: make sure we only have a single list running at a time */ - /* sem_wait(id->list_sem); */ - - /* FIXME: namespace stuff (done in store code?) */ - - /* FIXME: if name != "", we need to also do list "name.%" (. == sep) */ - - id->list_result = g_ptr_array_new(); - id->list_flags = flags; - CAMEL_TRY { - ic = camel_imapp_engine_command_new(id->engine, "LIST", NULL, "LIST \"\" %f", name[0]?name:"%"); - camel_imapp_engine_command_queue(id->engine, ic); - while (ic) { - while (camel_imapp_engine_iterate(id->engine, ic)>0) - ; - camel_imapp_engine_command_free(id->engine, ic); - - if (id->list_commands) { - GSList *top = id->list_commands; - - id->list_commands = top->next; - ic = top->data; - g_slist_free_1(top); - } else { - ic = NULL; - } - } - } CAMEL_CATCH(e) { - GSList *top = id->list_commands; - int i; - - camel_imapp_engine_command_free(id->engine, ic); - - while (top) { - GSList *topn = top->next; - - camel_imapp_engine_command_free(id->engine, ic); - g_slist_free_1(top); - top = topn; - } - id->list_commands = NULL; - - res = id->list_result; - for (i=0;i<res->len;i++) - imap_free_list(res->pdata[i]); - g_ptr_array_free(res, TRUE); - id->list_result = NULL; - - camel_exception_throw_ex(e); - } CAMEL_DONE; - - res = id->list_result; - id->list_result = NULL; - - /* sem_post(id->list_sem); */ - - return res; -} - -static int -driver_resp_list(CamelIMAPPEngine *ie, guint32 idx, CamelIMAPPDriver *id) -{ - struct _list_info *linfo; - - /* FIXME: exceptions */ - - linfo = imap_parse_list(ie->stream); - printf("store list: '%s' ('%c')\n", linfo->name, linfo->separator); - if (id->list_result) { - if ((linfo->flags & CAMEL_FOLDER_NOINFERIORS) == 0 - && (id->list_flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) - && linfo->separator) { - int depth = 0; - char *p = linfo->name; - char c = linfo->separator; - - /* this is expensive ... but if we've listed this deep we're going slow anyway */ - while (*p && depth < 10) { - if (*p == c) - depth++; - p++; - } - - if (depth < 10 - && (linfo->name[0] == 0 || linfo->name[strlen(linfo->name)-1] != c)) { - CamelIMAPPCommand *ic; - - ic = camel_imapp_engine_command_new(id->engine, "LIST", NULL, "LIST \"\" %t%c%%", linfo->name, c); - id->list_commands = g_slist_prepend(id->list_commands, ic); - camel_imapp_engine_command_queue(id->engine, ic); - } - } - /* FIXME: dont add to list if name ends in separator */ - g_ptr_array_add(id->list_result, linfo); - } else { - g_warning("unexpected list response\n"); - imap_free_list(linfo); - } - - return camel_imapp_engine_skip(ie); -} - -/* ********************************************************************** */ - -static void -driver_status(CamelIMAPPEngine *ie, struct _status_info *sinfo, CamelIMAPPDriver *sdata) -{ - printf("got status response ...\n"); - switch(sinfo->condition) { - case IMAP_READ_WRITE: - printf("folder is read-write\n"); - break; - case IMAP_READ_ONLY: - printf("folder is read-only\n"); - break; - case IMAP_UIDVALIDITY: - sdata->uidvalidity = sinfo->u.uidvalidity; - break; -#if 0 - /* not defined yet ... */ - case IMAP_UIDNEXT: - printf("got uidnext for folder: %d\n", sinfo->u.uidnext); - break; -#endif - case IMAP_UNSEEN: - sdata->unseen = sinfo->u.unseen; - break; - case IMAP_PERMANENTFLAGS: - sdata->permanentflags = sinfo->u.permanentflags; - break; - case IMAP_ALERT: - printf("ALERT!: %s\n", sinfo->text); - break; - case IMAP_PARSE: - printf("PARSE: %s\n", sinfo->text); - break; - default: - break; - } -} - -static int -driver_resp_exists(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) -{ - /* should this be an event instead? */ - - sdata->exists = id; - - return camel_imapp_engine_skip(ie); -} - -static int -driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) -{ - printf("got expunge response %u\n", id); - if (sdata->folder != NULL) { - CamelMessageInfo *info; - CamelFolderSummary *summary = ((CamelFolder *)sdata->folder)->summary; - - info = camel_folder_summary_index(summary, id-1); - if (info) { - printf("expunging msg %d\n", id); - camel_folder_summary_remove(summary, info); - camel_folder_summary_info_free(summary, info); - camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info)); - } else { - printf("can not find msg %u from expunge\n", id); - } - } - - return camel_imapp_engine_skip(ie); -} - -static int -driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) -{ - struct _fetch_info *finfo = NULL; - CamelMessageInfo *info, *uinfo; - unsigned int i; - CamelFolderSummary *summary; - - printf("got fetch response %d\n", id); - - if (sdata->folder == NULL) - goto done; - - summary = ((CamelFolder *)sdata->folder)->summary; - - finfo = imap_parse_fetch(ie->stream); - imap_dump_fetch(finfo); - - info = camel_folder_summary_index(summary, id-1); - if (info == NULL) { - if (finfo->uid == NULL) { - printf("got fetch response for currently unknown message %u\n", id); - goto done; - } - uinfo = camel_folder_summary_uid(summary, finfo->uid); - if (uinfo) { - /* we have a problem ... index mismatch */ - printf("index mismatch, uid '%s' not at index '%u'\n", - finfo->uid, id); - camel_folder_summary_info_free(summary, uinfo); - } - /* pad out the summary till we have enough indexes */ - for (i=camel_folder_summary_count(summary);i<id;i++) { - info = camel_folder_summary_info_new(summary); - if (i == id-1) { - printf("inserting new info @ %u\n", i); - camel_message_info_set_uid(info, g_strdup(finfo->uid)); - } else { - char uidtmp[32]; - - sprintf(uidtmp, "blank-%u", i); - camel_message_info_set_uid(info, g_strdup(uidtmp)); - printf("inserting empty uid %s\n", uidtmp); - } - - camel_folder_summary_add(summary, info); - } - info = camel_folder_summary_index(summary, id-1); - g_assert(info != NULL); - } else { - if (finfo->uid) { - /* FIXME: need to handle blank-* uids, somehow */ - while (info && strcmp(camel_message_info_uid(info), finfo->uid) != 0) { - printf("index mismatch, uid '%s' not at index '%u', got '%s' instead (removing)\n", - finfo->uid, id, camel_message_info_uid(info)); - - camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info)); - camel_folder_summary_remove(summary, info); - camel_folder_summary_info_free(summary, info); - info = camel_folder_summary_index(summary, id-1); - } - } else { - printf("got info for unknown message %u\n", id); - } - } - - if (info) { - if (finfo->got & FETCH_MINFO) { - /* if we only use ENVELOPE? */ - camel_message_info_set_subject(info, g_strdup(camel_message_info_subject(finfo->minfo))); - camel_message_info_set_from(info, g_strdup(camel_message_info_from(finfo->minfo))); - camel_message_info_set_to(info, g_strdup(camel_message_info_to(finfo->minfo))); - camel_message_info_set_cc(info, g_strdup(camel_message_info_cc(finfo->minfo))); - info->date_sent = finfo->minfo->date_sent; - camel_folder_change_info_add_uid(sdata->folder->changes, camel_message_info_uid(info)); - printf("adding change info uid '%s'\n", camel_message_info_uid(info)); - } - - if (finfo->got & FETCH_FLAGS) { - if ((info->flags & CAMEL_IMAPP_SERVER_FLAGS) != (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS)) { - camel_folder_change_info_change_uid(sdata->folder->changes, camel_message_info_uid(info)); - info->flags = (info->flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS); - camel_folder_summary_touch(summary); - } - ((CamelIMAPPMessageInfo *)info)->server_flags = finfo->flags & CAMEL_IMAPP_SERVER_FLAGS; - } - - if ((finfo->got & (FETCH_BODY|FETCH_UID)) == (FETCH_BODY|FETCH_UID)) { - struct _fetch_data *fd, *fn; - - fd = (struct _fetch_data *)sdata->body_fetch.head; - fn = fd->next; - while (fn) { - if (!strcmp(finfo->uid, fd->uid) && !strcmp(finfo->section, fd->section)) { - if (fd->data) - camel_object_unref(fd->data); - fd->data = finfo->body; - camel_object_ref(fd->data); - e_dlist_remove((EDListNode *)fd); - e_dlist_addtail(&sdata->body_fetch_done, (EDListNode *)fd); - break; - } - fd = fn; - fn = fn->next; - } - } - - camel_folder_summary_info_free(summary, info); - } else { - printf("dont know what to do with message\n"); - } - done: - imap_free_fetch(finfo); - - return camel_imapp_engine_skip(ie); -} diff --git a/camel/providers/imapp/camel-imapp-driver.h b/camel/providers/imapp/camel-imapp-driver.h deleted file mode 100644 index 3124700619..0000000000 --- a/camel/providers/imapp/camel-imapp-driver.h +++ /dev/null @@ -1,81 +0,0 @@ - -#ifndef _CAMEL_IMAPP_DRIVER_H -#define _CAMEL_IMAPP_DRIVER_H - -#include <camel/camel-object.h> -#include "camel-imapp-stream.h" -#include <e-util/e-msgport.h> - -#define CAMEL_IMAPP_DRIVER_TYPE (camel_imapp_driver_get_type ()) -#define CAMEL_IMAPP_DRIVER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_DRIVER_TYPE, CamelIMAPPDriver)) -#define CAMEL_IMAPP_DRIVER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_DRIVER_TYPE, CamelIMAPPDriverClass)) -#define CAMEL_IS_IMAP_DRIVER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_DRIVER_TYPE)) - -typedef struct _CamelIMAPPDriver CamelIMAPPDriver; -typedef struct _CamelIMAPPDriverClass CamelIMAPPDriverClass; - -typedef int (*CamelIMAPPDriverFunc)(struct _CamelIMAPPDriver *driver, void *data); -typedef struct _CamelSasl * (*CamelIMAPPSASLFunc)(struct _CamelIMAPPDriver *driver, void *data); -typedef void (*CamelIMAPPLoginFunc)(struct _CamelIMAPPDriver *driver, char **login, char **pass, void *data); - -struct _CamelMimeMessage; - -struct _CamelIMAPPDriver { - CamelObject parent_object; - - struct _CamelIMAPPEngine *engine; - - struct _CamelIMAPPFolder *folder; - - /* current folder stuff */ - GPtrArray *summary; - guint32 uidvalidity; - guint32 exists; - guint32 recent; - guint32 unseen; - guint32 permanentflags; - - /* list stuff */ - GPtrArray *list_result; - GSList *list_commands; - guint32 list_flags; - - /* sem_t list_sem; for controlled access to list variables */ - - /* this is so the node is always in a list - easier exception management */ - EDList body_fetch; - EDList body_fetch_done; - - /* factory to get an appropriate sasl mech */ - CamelIMAPPSASLFunc get_sasl; - void *get_sasl_data; - - /* callbacks, get login username/pass */ - CamelIMAPPLoginFunc get_login; - void *get_login_data; -}; - -struct _CamelIMAPPDriverClass { - CamelObjectClass parent_class; -}; - -CamelType camel_imapp_driver_get_type (void); - -CamelIMAPPDriver * camel_imapp_driver_new(CamelIMAPPStream *stream); - -void camel_imapp_driver_set_sasl_factory(CamelIMAPPDriver *id, CamelIMAPPSASLFunc get_sasl, void *sasl_data); -void camel_imapp_driver_set_login_query(CamelIMAPPDriver *id, CamelIMAPPLoginFunc get_login, void *login_data); - -void camel_imapp_driver_login(CamelIMAPPDriver *id); - -void camel_imapp_driver_select(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder); -void camel_imapp_driver_update(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder); -void camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, struct _CamelIMAPPFolder *folder); - -struct _CamelStream * camel_imapp_driver_fetch(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, const char *uid, const char *body); -GPtrArray * camel_imapp_driver_list(CamelIMAPPDriver *id, const char *name, guint32 flags); - -struct _CamelStream *camel_imapp_driver_get(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, const char *uid); -void camel_imapp_driver_append(CamelIMAPPDriver *id, struct _CamelIMAPPFolder *folder, struct _CamelDataWrapper *); - -#endif diff --git a/camel/providers/imapp/camel-imapp-engine.c b/camel/providers/imapp/camel-imapp-engine.c deleted file mode 100644 index df14903c5a..0000000000 --- a/camel/providers/imapp/camel-imapp-engine.c +++ /dev/null @@ -1,1180 +0,0 @@ - -#include "config.h" - -#include <stdio.h> -#include <string.h> - -#include "camel-imapp-engine.h" -#include "camel-imapp-stream.h" -#include "camel-imapp-utils.h" -#include "camel-imapp-exception.h" - -#include <camel/camel-folder-summary.h> -#include <camel/camel-stream-mem.h> -#include <camel/camel-stream-null.h> -#include <camel/camel-data-wrapper.h> -#include <camel/camel-sasl.h> - -#include <ctype.h> - -#define e(x) -#define c(x) /* command build debug */ - -static void imap_engine_command_addv(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, va_list ap); -static void imap_engine_command_complete(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic); - -struct _handler { - CamelIMAPPEngineFunc func; - void *data; - char name[1]; -}; - -static void -class_init(CamelIMAPPEngineClass *ieclass) -{ - ieclass->tagprefix = 'A'; - - camel_object_class_add_event((CamelObjectClass *)ieclass, "status", NULL); -} - -static void -object_init(CamelIMAPPEngine *ie, CamelIMAPPEngineClass *ieclass) -{ - ie->handlers = g_hash_table_new(g_str_hash, g_str_equal); - e_dlist_init(&ie->active); - e_dlist_init(&ie->queue); - e_dlist_init(&ie->done); - - ie->tagprefix = ieclass->tagprefix; - ieclass->tagprefix++; - if (ieclass->tagprefix > 'Z') - ieclass->tagprefix = 'A'; - ie->tagprefix = 'A'; - - ie->state = IMAP_ENGINE_DISCONNECT; -} - -static void -handler_free(void *key, void *mem, void *data) -{ - g_free(mem); -} - -static void -object_finalise(CamelIMAPPEngine *ie, CamelIMAPPEngineClass *ieclass) -{ - /* FIXME: need to free the commands ... */ - while (camel_imapp_engine_iterate(ie, NULL) > 0) - ; - - g_hash_table_foreach(ie->handlers, (GHFunc)handler_free, NULL); - g_hash_table_destroy(ie->handlers); -} - -CamelType -camel_imapp_engine_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register ( - camel_object_get_type (), - "CamelIMAPPEngine", - sizeof (CamelIMAPPEngine), - sizeof (CamelIMAPPEngineClass), - (CamelObjectClassInitFunc) class_init, - NULL, - (CamelObjectInitFunc) object_init, - (CamelObjectFinalizeFunc) object_finalise); - } - - return type; -} - -/* FIXME: check this, just taken from old code, not rfc */ -struct { - char *name; - guint32 flag; -} capa_table[] = { - { "IMAP4", IMAP_CAPABILITY_IMAP4 }, - { "IMAP4REV1", IMAP_CAPABILITY_IMAP4REV1 }, - { "STATUS", IMAP_CAPABILITY_STATUS } , - { "NAMESPACE", IMAP_CAPABILITY_NAMESPACE }, - { "UIDPLUS", IMAP_CAPABILITY_UIDPLUS }, - { "LITERAL+", IMAP_CAPABILITY_LITERALPLUS }, - { "STARTTLS", IMAP_CAPABILITY_STARTTLS }, -}; - - -/* -capability_data ::= "CAPABILITY" SPACE [1#capability SPACE] "IMAP4rev1" - [SPACE 1#capability] - ;; IMAP4rev1 servers which offer RFC 1730 - ;; compatibility MUST list "IMAP4" as the first - ;; capability. -*/ -static int resp_capability(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - int tok, len, i; - unsigned char *token, *p, c; - - /* FIXME: handle auth types */ - - printf("got capability response:\n"); - while (1) { - tok = camel_imapp_stream_token(ie->stream, &token, &len); - switch(tok) { - case IMAP_TOK_TOKEN: - p = token; - while ((c = *p)) - *p++ = toupper(c); - case IMAP_TOK_INT: - printf(" cap: '%s'\n", token); - for (i=0;i<(int)(sizeof(capa_table)/sizeof(capa_table[0]));i++) - if (strcmp(token, capa_table[i].name)) - ie->capa |= capa_table[i].flag; - break; - case '\n': - return 0; - case IMAP_TOK_ERROR: - case IMAP_TOK_PROTOCOL: - camel_imapp_engine_skip(ie); - return -1; - default: - printf("Unknown Response token %02x '%c'\n", tok, isprint(tok)?tok:'.'); - } - } while (tok != '\n'); - - return 0; -} - -/* expunge command, id is expunged seq number */ -/* message_data ::= nz_number SPACE ("EXPUNGE" / - ("FETCH" SPACE msg_att)) */ -static int resp_expunge(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - printf("message expunged: %d\n", id); - - return camel_imapp_engine_skip(ie); -} - -static int resp_flags(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - guint32 flags; - - imap_parse_flags(ie->stream, &flags); - - printf("flags: %08x\n", flags); - - return camel_imapp_engine_skip(ie); -} - -/* exists count */ -static int resp_exists(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - printf("messages exist: %d\n", id); - - if (ie->select_response) - ie->select_response->exists = id; - - return camel_imapp_engine_skip(ie); -} - -static int resp_recent(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - printf("messages recent: %d\n", id); - - if (ie->select_response) - ie->select_response->recent = id; - - return camel_imapp_engine_skip(ie); -} - -static int resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - struct _fetch_info *finfo; - - finfo = imap_parse_fetch(ie->stream); - imap_dump_fetch(finfo); - imap_free_fetch(finfo); - - return camel_imapp_engine_skip(ie); -} - -#if 0 -static int resp_list(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - struct _list_info *linfo; - - linfo = imap_parse_list(ie->stream); - printf("list: '%s' (%c)\n", linfo->name, linfo->separator); - imap_free_list(linfo); - - return camel_imapp_engine_skip(ie); -} -#endif - -CamelIMAPPEngine * -camel_imapp_engine_new(CamelIMAPPStream *stream) -{ - CamelIMAPPEngine * volatile engine; - - engine = CAMEL_IMAPP_ENGINE (camel_object_new (CAMEL_IMAPP_ENGINE_TYPE)); - engine->stream = stream; - camel_object_ref((CamelObject *)stream); - - camel_imapp_engine_add_handler(engine, "CAPABILITY", resp_capability, engine); - - /* mailbox_data */ - camel_imapp_engine_add_handler(engine, "FLAGS", (CamelIMAPPEngineFunc)resp_flags, engine); - camel_imapp_engine_add_handler(engine, "EXISTS", (CamelIMAPPEngineFunc)resp_exists, engine); - camel_imapp_engine_add_handler(engine, "RECENT", (CamelIMAPPEngineFunc)resp_recent, engine); - -#if 0 - camel_imapp_engine_add_handler(engine, "LIST", (CamelIMAPPEngineFunc)resp_list, engine); - camel_imapp_engine_add_handler(engine, "LSUB", (CamelIMAPPEngineFunc)resp_list, engine); -#endif - /* message_data */ - camel_imapp_engine_add_handler(engine, "EXPUNGE", (CamelIMAPPEngineFunc)resp_expunge, engine); - camel_imapp_engine_add_handler(engine, "FETCH", (CamelIMAPPEngineFunc)resp_fetch, engine); - - /* TODO: move this to a driver:connect call? */ - CAMEL_TRY { - unsigned char *token; - unsigned int len; - int tok; - - tok = camel_imapp_stream_token(stream, &token, &len); - if (tok == '*') { - struct _status_info *sinfo = imap_parse_status(stream); - - switch (sinfo->result) { - case IMAP_OK: - engine->state = IMAP_ENGINE_CONNECT; - printf("Server connected ok: %s\n", sinfo->text); - break; - case IMAP_PREAUTH: - printf("pre-authenticated ...\n"); - engine->state = IMAP_ENGINE_AUTH; - break; - default: - imap_free_status(sinfo); - camel_exception_throw(1, "Server refused connection: %s", sinfo->text); - break; - } - imap_free_status(sinfo); - } else { - engine->state = IMAP_ENGINE_CONNECT; - printf("unknwon server greeting, ignored\n"); - camel_imapp_engine_skip(engine); - } - camel_imapp_engine_capabilities(engine); - } CAMEL_CATCH(ex) { - printf("connection failed: %s\n", ex->desc); - camel_object_unref((CamelObject *)engine); - engine = NULL; - } CAMEL_DONE; - - return engine; -} - -void -camel_imapp_engine_add_handler(CamelIMAPPEngine *imap, const char *response, CamelIMAPPEngineFunc func, void *data) -{ - struct _handler *h; - const unsigned char *p; - unsigned char *o, c; - - h = g_malloc0(sizeof(*h) + strlen(response)); - h->func = func; - h->data = data; - - p = response; - o = h->name; - while ((c = *p++)) - *o++ = toupper(c); - *o = 0; - - g_hash_table_insert(imap->handlers, h->name, h); -} - -int -camel_imapp_engine_capabilities(CamelIMAPPEngine *ie) -{ - CamelIMAPPCommand *ic; - - /* reset capabilities */ - ie->capa = 0; - - ic = camel_imapp_engine_command_new(ie, "CAPABILITY", NULL, "CAPABILITY"); - camel_imapp_engine_command_queue(ie, ic); - while (camel_imapp_engine_iterate(ie, ic)>0) - ; - camel_imapp_engine_command_free(ie, ic); - - return 0; -} - -/* skip the rest of the line of tokens */ -int -camel_imapp_engine_skip(CamelIMAPPEngine *imap) -{ - int tok; - unsigned char *token; - unsigned int len; - - do { - tok = camel_imapp_stream_token(imap->stream, &token, &len); - if (tok == IMAP_TOK_LITERAL) { - camel_imapp_stream_set_literal(imap->stream, len); - while ((tok = camel_imapp_stream_getl(imap->stream, &token, &len)) > 0) { - printf("Skip literal data '%.*s'\n", (int)len, token); - } - } - } while (tok != '\n' && tok >= 0); - - if (tok < 0) - return -1; - - return 0; -} - -/* handle any untagged responses */ -static int -iterate_untagged(CamelIMAPPEngine *imap) -{ - unsigned int id, len; - unsigned char *token, *p, c; - int tok; - struct _handler *h; - struct _status_info *sinfo; - - e(printf("got untagged response\n")); - id = 0; - tok = camel_imapp_stream_token(imap->stream, &token, &len); - if (tok == IMAP_TOK_INT) { - id = strtoul(token, NULL, 10); - tok = camel_imapp_stream_token(imap->stream, &token, &len); - } - - if (tok == '\n') - camel_exception_throw(1, "truncated server response"); - - e(printf("Have token '%s' id %d\n", token, id)); - p = token; - while ((c = *p)) - *p++ = toupper(c); - - /* first, check for generic unsolicited response */ - h = g_hash_table_lookup(imap->handlers, token); - if (h) { - tok = h->func(imap, id, h->data); - if (tok < 0) - return tok; - return 1; - } - - /* TODO: apart from bye/preauth, these could be callbacks/events? */ - - /* now, check for status responses */ - switch (imap_tokenise(token, len)) { - case IMAP_BYE: - case IMAP_OK: - case IMAP_NO: - case IMAP_BAD: - case IMAP_PREAUTH: - /* TODO: validate which ones of these can happen as unsolicited responses */ - /* TODO: handle bye/preauth differently */ - /* FIXME: free sinfo */ - camel_imapp_stream_ungettoken(imap->stream, tok, token, len); - sinfo = imap_parse_status(imap->stream); - camel_object_trigger_event(imap, "status", sinfo); - imap_free_status(sinfo); -#if 0 - switch(sinfo->condition) { - case IMAP_READ_WRITE: - printf("folder is read-write\n"); - break; - case IMAP_READ_ONLY: - printf("folder is read-only\n"); - break; - case IMAP_UIDVALIDITY: - if (imap->select_response) - imap->select_response->uidvalidity = sinfo->u.uidvalidity; - break; -#if 0 - /* not defined yet ... */ - case IMAP_UIDNEXT: - printf("got uidnext for folder: %d\n", sinfo->u.uidnext); - break; -#endif - case IMAP_UNSEEN: - if (imap->select_response) - imap->select_response->unseen = sinfo->u.unseen; - break; - case IMAP_PERMANENTFLAGS: - if (imap->select_response) - imap->select_response->permanentflags = sinfo->u.permanentflags; - break; - case IMAP_ALERT: - printf("ALERT!: %s\n", sinfo->text); - break; - case IMAP_PARSE: - printf("PARSE: %s\n", sinfo->text); - break; - default: - break; - } -#endif - break; - default: - printf("unknown token: %s\n", token); - camel_imapp_engine_skip(imap); - /* unknown response, just ignore it */ - } - - return 1; -} - -/* handle any continuation requests - either data continuations, or auth continuation */ -int -iterate_continuation(CamelIMAPPEngine *imap) -{ - CamelIMAPPCommand *ic; - CamelIMAPPCommandPart *cp; - - printf("got continuation response\n"); - - ic = imap->literal; - imap->literal = NULL; - if (ic == NULL) { - camel_imapp_engine_skip(imap); - printf("got continuation response with no outstanding continuation requests?\n"); - return 1; - } - - printf("got continuation response for data\n"); - cp = ic->current; - switch(cp->type & CAMEL_IMAPP_COMMAND_MASK) { - case CAMEL_IMAPP_COMMAND_DATAWRAPPER: - printf("writing data wrapper to literal\n"); - camel_data_wrapper_write_to_stream((CamelDataWrapper *)cp->ob, (CamelStream *)imap->stream); - break; - case CAMEL_IMAPP_COMMAND_STREAM: - printf("writing stream to literal\n"); - camel_stream_write_to_stream((CamelStream *)cp->ob, (CamelStream *)imap->stream); - break; - case CAMEL_IMAPP_COMMAND_AUTH: { - CamelException *ex = camel_exception_new(); - char *resp; - unsigned char *token; - int tok, len; - - tok = camel_imapp_stream_token(imap->stream, &token, &len); - resp = camel_sasl_challenge_base64((CamelSasl *)cp->ob, token, ex); - if (camel_exception_is_set(ex)) - camel_exception_throw_ex(ex); - camel_exception_free(ex); - - printf("got auth continuation, feeding token '%s' back to auth mech\n", resp); - - camel_stream_write((CamelStream *)imap->stream, resp, strlen(resp)); - - /* we want to keep getting called until we get a status reponse from the server - ignore what sasl tells us */ - imap->literal = ic; - - break; } - default: - /* should we just ignore? */ - camel_exception_throw(1, "continuation response for non-continuation request"); - } - - camel_imapp_engine_skip(imap); - - cp = cp->next; - if (cp->next) { - ic->current = cp; - printf("next part of command \"A%05u: %s\"\n", ic->tag, cp->data); - camel_stream_printf((CamelStream *)imap->stream, "%s\r\n", cp->data); - if (cp->type & CAMEL_IMAPP_COMMAND_CONTINUATION) { - imap->literal = ic; - } else { - g_assert(cp->next->next == NULL); - } - } else { - printf("%p: queueing continuation\n", ic); - camel_stream_printf((CamelStream *)imap->stream, "\r\n"); - } - - if (imap->literal == NULL) { - ic = (CamelIMAPPCommand *)e_dlist_remhead(&imap->queue); - if (ic) { - printf("found outstanding op, queueing\n"); - camel_imapp_engine_command_queue(imap, ic); - } - } - - return 1; -} - -/* handle a completion line */ -int -iterate_completion(CamelIMAPPEngine *imap, unsigned char *token) -{ - CamelIMAPPCommand *ic; - unsigned int tag; - - if (token[0] != imap->tagprefix) - camel_exception_throw(1, "Server sent unexpected response: %s", token); - - tag = strtoul(token+1, NULL, 10); - ic = camel_imapp_engine_command_find_tag(imap, tag); - if (ic) { - printf("Got completion response for command %05u '%s'\n", ic->tag, ic->name); - printf("%p: removing command from qwueue, we were at '%s'\n", ic, ic->current->data); - printf("%p: removing command\n", ic); - e_dlist_remove((EDListNode *)ic); - e_dlist_addtail(&imap->done, (EDListNode *)ic); - if (imap->literal == ic) - imap->literal = NULL; - ic->status = imap_parse_status(imap->stream); - printf("got response code: %s\n", ic->status->text); - - /* TODO: remove this stuff and use a completion handler? */ - /* TODO: handle 'SELECT' command cleanup here */ - /* FIXME: have this use tokeniser, have this handle close/logout/select etc as well */ - /* ok response from login/authenticate, then we're in happy land */ - if ((!strcmp(ic->name, "LOGIN") || !strcmp(ic->name, "AUTHENTICATE")) - && ic->status->result == IMAP_OK) - imap->state = IMAP_ENGINE_AUTH; - - if (ic->complete) - ic->complete(imap, ic, ic->complete_data); - } else { - camel_exception_throw(1, "got response tag unexpectedly: %s", token); - } - - if (imap->literal != NULL) { - printf("Warning: continuation command '%s' finished with outstanding continuation\n", imap->literal->name); - ic = imap->literal; - /* set the command complete with a failure code? */ - e_dlist_remove((EDListNode *)ic); - e_dlist_addtail(&imap->done, (EDListNode *)ic); - imap->literal = NULL; - } - - ic = (CamelIMAPPCommand *)e_dlist_remhead(&imap->queue); - if (ic) { - printf("found outstanding op, queueing\n"); - camel_imapp_engine_command_queue(imap, ic); - } - - return 1; -} - - -/* Do work if there's any to do */ -int -camel_imapp_engine_iterate(CamelIMAPPEngine *imap, CamelIMAPPCommand *icwait) -/* throws IO,PARSE exception */ -{ - unsigned int len; - unsigned char *token; - int tok; - - if ((icwait && icwait->status != NULL) || e_dlist_empty(&imap->active)) - return 0; - - /* handle exceptions here? */ - - /* lock here? */ - - tok = camel_imapp_stream_token(imap->stream, &token, &len); - if (tok == '*') - iterate_untagged(imap); - else if (tok == IMAP_TOK_TOKEN) - iterate_completion(imap, token); - else if (tok == '+') - iterate_continuation(imap); - else - camel_exception_throw(1, "unexpected server response: %s", token); - - if (e_dlist_empty(&imap->active)) - return 0; - - return 1; -} - -CamelIMAPPCommand * -camel_imapp_engine_command_new(CamelIMAPPEngine *imap, const char *name, const char *select, const char *fmt, ...) -{ - CamelIMAPPCommand *ic; - va_list ap; - - ic = g_malloc0(sizeof(*ic)); - ic->tag = imap->tag++; - ic->name = name; - ic->mem = (CamelStreamMem *)camel_stream_mem_new(); - ic->select = g_strdup(select); - e_dlist_init(&ic->parts); - - if (fmt && fmt[0]) { - va_start(ap, fmt); - imap_engine_command_addv(imap, ic, fmt, ap); - va_end(ap); - } - - return ic; -} - -void -camel_imapp_engine_command_add(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, ...) -{ - va_list ap; - - g_assert(ic->mem); /* gets reset on queue */ - - if (fmt && fmt[0]) { - va_start(ap, fmt); - imap_engine_command_addv(imap, ic, fmt, ap); - va_end(ap); - } -} - -void -camel_imapp_engine_command_complete(CamelIMAPPEngine *imap, struct _CamelIMAPPCommand *ic, CamelIMAPPCommandFunc func, void *data) -{ - ic->complete = func; - ic->complete_data = data; -} - -/* FIXME: make imap command's refcounted */ -void -camel_imapp_engine_command_free (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic) -{ - CamelIMAPPCommandPart *cp, *cn; - - if (ic == NULL) - return; - - /* validity check - we cant' free items still in any queue ... */ - /* maybe we should just have another queue to keep them? */ - { - CamelIMAPPCommand *iw; - int found = 0; - - iw = (CamelIMAPPCommand *)imap->active.head; - while (iw->next) { - if (iw == ic) { - found = 1; - g_warning("command '%s' still in active queue", iw->name); - break; - } - iw = iw->next; - } - iw = (CamelIMAPPCommand *)imap->queue.head; - while (iw->next) { - if (iw == ic) { - found = 1; - g_warning("command '%s' still in waiting queue", iw->name); - break; - } - iw = iw->next; - } - iw = (CamelIMAPPCommand *)imap->done.head; - while (iw->next) { - if (iw == ic) { - found = 1; - break; - } - iw = iw->next; - } - if (!found) { - g_warning("command '%s' not found anywhere", ic->name); - abort(); - } - } - - e_dlist_remove((EDListNode *)ic); - - if (ic->mem) - camel_object_unref((CamelObject *)ic->mem); - imap_free_status(ic->status); - g_free(ic->select); - - cp = (CamelIMAPPCommandPart *)ic->parts.head; - cn = cp->next; - while (cn) { - g_free(cp->data); - if (cp->ob) - camel_object_unref(cp->ob); - g_free(cp); - cp = cn; - cn = cn->next; - } - - g_free(ic); -} - -/* FIXME: error handling */ -void -camel_imapp_engine_command_queue(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic) -{ - CamelIMAPPCommandPart *cp; - - if (ic->mem) - imap_engine_command_complete(imap, ic); - - /* FIXME: remove select stuff */ - - /* see if we need to pre-queue a select command to select the right folder first */ - if (ic->select && (imap->last_select == NULL || strcmp(ic->select, imap->last_select) != 0)) { - CamelIMAPPCommand *select; - - /* of course ... we can't do anything like store/search if we have to select - first, because it'll mess up all the sequence numbers ... hrm ... bugger */ - - select = camel_imapp_engine_command_new(imap, "SELECT", NULL, "SELECT %s", ic->select); - g_free(imap->last_select); - imap->last_select = g_strdup(ic->select); - camel_imapp_engine_command_queue(imap, select); - /* how does it get freed? handle inside engine? */ - } - - /* first, check if command can be sent yet ... queue if not */ - if (imap->literal != NULL) { - printf("%p: queueing while literal active\n", ic); - e_dlist_addtail(&imap->queue, (EDListNode *)ic); - return; - } - - cp = (CamelIMAPPCommandPart *)ic->parts.head; - g_assert(cp); - ic->current = cp; - - /* how to handle exceptions here? */ - - printf("queueing command \"%c%05u %s\"\n", imap->tagprefix, ic->tag, cp->data); - camel_stream_printf((CamelStream *)imap->stream, "%c%05u %s\r\n", imap->tagprefix, ic->tag, cp->data); - - if (cp->type & CAMEL_IMAPP_COMMAND_CONTINUATION) { - printf("%p: active literal\n", ic); - g_assert(cp->next); - imap->literal = ic; - e_dlist_addtail(&imap->active, (EDListNode *)ic); - } else { - printf("%p: active non-literal\n", ic); - g_assert(cp->next && cp->next->next == NULL); - e_dlist_addtail(&imap->active, (EDListNode *)ic); - } -} - -CamelIMAPPCommand * -camel_imapp_engine_command_find (CamelIMAPPEngine *imap, const char *name) -{ - CamelIMAPPCommand *ic, *in; - - ic = imap->literal; - if (ic && strcmp(ic->name, name) == 0) - return ic; - - /* first, try active */ - ic = (CamelIMAPPCommand *)imap->active.head; - in = ic->next; - while (in) { - if (strcmp(ic->name, name) == 0) - return ic; - ic = in; - in = in->next; - } - - return NULL; -} - -CamelIMAPPCommand * -camel_imapp_engine_command_find_tag(CamelIMAPPEngine *imap, unsigned int tag) -{ - CamelIMAPPCommand *ic, *in; - - ic = imap->literal; - if (ic && ic->tag == tag) - return ic; - - ic = (CamelIMAPPCommand *)imap->active.head; - in = ic->next; - while (in) { - if (ic->tag == tag) - return ic; - ic = in; - in = in->next; - } - - return NULL; -} - -/* ********************************************************************** */ - -CamelIMAPPSelectResponse * -camel_imapp_engine_select(CamelIMAPPEngine *imap, const char *name) -{ - CamelIMAPPSelectResponse * volatile resp; - CamelIMAPPCommand * volatile ic = NULL; - - resp = g_malloc0(sizeof(*resp)); - imap->select_response = resp; - - CAMEL_TRY { - ic = camel_imapp_engine_command_new(imap, "SELECT", NULL, "SELECT %s", name); - camel_imapp_engine_command_queue(imap, ic); - while (camel_imapp_engine_iterate(imap, ic) > 0) - ; - - if (ic->status->result != IMAP_OK) - camel_exception_throw(1, "select failed: %s", ic->status->text); - resp->status = ic->status; - ic->status = NULL; - } CAMEL_CATCH (e) { - camel_imapp_engine_command_free(imap, ic); - camel_imapp_engine_select_free(imap, resp); - imap->select_response = NULL; - camel_exception_throw_ex(e); - } CAMEL_DONE; - - camel_imapp_engine_command_free(imap, ic); - imap->select_response = NULL; - - return resp; -} - -void -camel_imapp_engine_select_free(CamelIMAPPEngine *imap, CamelIMAPPSelectResponse *select) -{ - if (select) { - imap_free_status(select->status); - g_free(select); - } -} - -/* ********************************************************************** */ - -static void -imap_engine_command_add_part(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, camel_imapp_command_part_t type, CamelObject *ob) -{ - CamelIMAPPCommandPart *cp; - CamelStreamNull *null; - unsigned int ob_size = 0; - - switch(type & CAMEL_IMAPP_COMMAND_MASK) { - case CAMEL_IMAPP_COMMAND_DATAWRAPPER: - case CAMEL_IMAPP_COMMAND_STREAM: - null = (CamelStreamNull *)camel_stream_null_new(); - if ( (type & CAMEL_IMAPP_COMMAND_MASK) == CAMEL_IMAPP_COMMAND_DATAWRAPPER) { - camel_data_wrapper_write_to_stream((CamelDataWrapper *)ob, (CamelStream *)null); - } else { - camel_stream_reset((CamelStream *)ob); - camel_stream_write_to_stream((CamelStream *)ob, (CamelStream *)null); - camel_stream_reset((CamelStream *)ob); - } - type |= CAMEL_IMAPP_COMMAND_CONTINUATION; - camel_object_ref(ob); - ob_size = null->written; - camel_object_unref((CamelObject *)null); - camel_stream_printf((CamelStream *)ic->mem, "{%u}", ob_size); - break; - case CAMEL_IMAPP_COMMAND_AUTH: - /* we presume we'll need to get additional data only if we're not authenticated yet */ - camel_object_ref(ob); - camel_stream_printf((CamelStream *)ic->mem, "%s", ((CamelSasl *)ob)->mech); - if (!camel_sasl_authenticated((CamelSasl *)ob)) - type |= CAMEL_IMAPP_COMMAND_CONTINUATION; - break; - default: - ob_size = 0; - } - - cp = g_malloc0(sizeof(*cp)); - cp->type = type; - cp->ob_size = ob_size; - cp->ob = ob; - cp->data_size = ic->mem->buffer->len; - cp->data = g_malloc(cp->data_size+1); - memcpy(cp->data, ic->mem->buffer->data, cp->data_size); - cp->data[cp->data_size] = 0; - - camel_stream_reset((CamelStream *)ic->mem); - /* FIXME: hackish? */ - g_byte_array_set_size(ic->mem->buffer, 0); - - e_dlist_addtail(&ic->parts, (EDListNode *)cp); -} - -static int len(EDList *list) -{ - int count = 0; - EDListNode *n = list->head; - - while (n->next) { - n = n->next; - count++; - } - return count; -} - -static void -imap_engine_command_complete(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic) -{ - c(printf("completing command buffer is [%d] '%.*s'\n", ic->mem->buffer->len, (int)ic->mem->buffer->len, ic->mem->buffer->data)); - c(printf("command has %d parts\n", len(&ic->parts))); - if (ic->mem->buffer->len > 0) - imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_SIMPLE, NULL); - - c(printf("command has %d parts\n", len(&ic->parts))); - - camel_object_unref((CamelObject *)ic->mem); - ic->mem = NULL; -} - -static void -imap_engine_command_addv(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, va_list ap) -{ - const unsigned char *p, *ps, *start; - unsigned char c; - unsigned int width; - char ch; - int llong; - int left; - int fill; - int zero; - char *s; - int d; - long int l; - guint32 f; - CamelStream *S; - CamelDataWrapper *D; - CamelSasl *A; - char buffer[16]; - - c(printf("adding command, fmt = '%s'\n", fmt)); - - p = fmt; - ps = fmt; - while ( ( c = *p++ ) ) { - switch(c) { - case '%': - if (*p == '%') { - camel_stream_write((CamelStream *)ic->mem, ps, p-ps); - p++; - ps = p; - } else { - camel_stream_write((CamelStream *)ic->mem, ps, p-ps-1); - start = p-1; - width = 0; - left = FALSE; - fill = FALSE; - zero = FALSE; - llong = FALSE; - - do { - c = *p++; - if (c == '0') - zero = TRUE; - else if ( c== '-') - left = TRUE; - else - break; - } while (c); - - do { - if (isdigit(c)) - width = width * 10 + (c-'0'); - else - break; - } while ((c = *p++)); - - if (c == 'l') { - llong = TRUE; - c = *p++; - } - - switch(c) { - case 'A': /* auth object - sasl auth, treat as special kind of continuation */ - A = va_arg(ap, CamelSasl *); - imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_AUTH, (CamelObject *)A); - break; - case 'S': /* stream */ - S = va_arg(ap, CamelStream *); - c(printf("got stream '%p'\n", S)); - imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_STREAM, (CamelObject *)S); - break; - case 'D': /* datawrapper */ - D = va_arg(ap, CamelDataWrapper *); - c(printf("got data wrapper '%p'\n", D)); - imap_engine_command_add_part(imap, ic, CAMEL_IMAPP_COMMAND_DATAWRAPPER, (CamelObject *)D); - break; - case 't': /* token */ - s = va_arg(ap, char *); - camel_stream_write((CamelStream *)ic->mem, s, strlen(s)); - break; - case 's': /* simple string */ - s = va_arg(ap, char *); - c(printf("got string '%s'\n", s)); - /* FIXME: escpae chars, convert to literal or literal+, etc */ - camel_stream_printf((CamelStream *)ic->mem, "\"%s\"", s); - break; - case 'f': /* imap folder name */ - s = va_arg(ap, char *); - c(printf("got folder '%s'\n", s)); - /* FIXME: encode folder name */ - /* FIXME: namespace? */ - camel_stream_printf((CamelStream *)ic->mem, "\"%s\"", s?s:""); - break; - case 'F': /* IMAP flags set */ - f = va_arg(ap, guint32); - imap_write_flags((CamelStream *)ic->mem, f); - break; - case 'c': - d = va_arg(ap, int); - ch = d; - camel_stream_write((CamelStream *)ic->mem, &ch, 1); - break; - case 'd': /* int/unsigned */ - case 'u': - if (llong) { - l = va_arg(ap, long int); - c(printf("got long int '%d'\n", (int)l)); - memcpy(buffer, start, p-start); - buffer[p-start] = 0; - camel_stream_printf((CamelStream *)ic->mem, buffer, l); - } else { - d = va_arg(ap, int); - c(printf("got int '%d'\n", d)); - memcpy(buffer, start, p-start); - buffer[p-start] = 0; - camel_stream_printf((CamelStream *)ic->mem, buffer, d); - } - break; - } - - ps = p; - } - break; - case '\\': /* only for \\ really, we dont support \n\r etc at all */ - c = *p; - if (c) { - g_assert(c == '\\'); - camel_stream_write((CamelStream *)ic->mem, ps, p-ps); - p++; - ps = p; - } - } - } - - camel_stream_write((CamelStream *)ic->mem, ps, p-ps-1); -} - - -/* here temporarily while its experimental */ - - -#ifdef ENABLE_THREADS -#include <pthread.h> - -static pthread_key_t handler_key = 0; - -void camel_exception_setup(void) -{ - pthread_key_create(&handler_key, NULL); -} - -#else -/* this is per-thread in threaded mode */ -static struct _CamelExceptionEnv *handler = NULL; - -void camel_exception_setup(void) -{ -} -#endif - -void -camel_exception_try(struct _CamelExceptionEnv *env) -{ -#ifdef ENABLE_THREADS - struct _CamelExceptionEnv *handler; - - handler = pthread_getspecific(handler_key); -#endif - env->parent = handler; - handler = env; - env->ex = NULL; - -#ifdef ENABLE_THREADS - pthread_setspecific(handler_key, handler); -#endif -} - -void -camel_exception_throw_ex(CamelException *ex) -{ - struct _CamelExceptionEnv *env; -#ifdef ENABLE_THREADS - struct _CamelExceptionEnv *handler; - - handler = pthread_getspecific(handler_key); -#endif - printf("throwing exception '%s'\n", ex->desc); - - env = handler; - if (env != NULL) { - env->ex = ex; - handler = env->parent; -#ifdef ENABLE_THREADS - pthread_setspecific(handler_key, handler); -#endif - longjmp(env->env, ex->id); - } else { - g_warning("Uncaught exception: %s\n", ex->desc); - /* we just crash and burn, this is a code problem */ - /* we dont use g_assert_not_reached() since its not a noreturn function */ - abort(); - } -} - -void -camel_exception_throw(int id, char *fmt, ...) -{ - CamelException *ex; - va_list ap; - - ex = camel_exception_new(); - ex->id = id; - va_start(ap, fmt); - ex->desc = g_strdup_vprintf(fmt, ap); - va_end(ap); - - camel_exception_throw_ex(ex); -} - -void -camel_exception_drop(struct _CamelExceptionEnv *env) -{ -#ifdef ENABLE_THREADS - pthread_setspecific(handler_key, env->parent); -#else - handler = env->parent; -#endif -} - -void -camel_exception_done(struct _CamelExceptionEnv *env) -{ -#ifdef ENABLE_THREADS - pthread_setspecific(handler_key, env->parent); -#else - handler = env->parent; -#endif - if (env->ex != NULL) { - camel_exception_free(env->ex); - } -} diff --git a/camel/providers/imapp/camel-imapp-engine.h b/camel/providers/imapp/camel-imapp-engine.h deleted file mode 100644 index 5f74d0654a..0000000000 --- a/camel/providers/imapp/camel-imapp-engine.h +++ /dev/null @@ -1,155 +0,0 @@ - -#ifndef _CAMEL_IMAPP_ENGINE_H -#define _CAMEL_IMAPP_ENGINE_H - -#include <camel/camel-object.h> - -#include "camel-imapp-stream.h" -#include <e-util/e-msgport.h> -#include "camel-imapp-folder.h" - -#define CAMEL_IMAPP_ENGINE_TYPE (camel_imapp_engine_get_type ()) -#define CAMEL_IMAPP_ENGINE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_ENGINE_TYPE, CamelIMAPPEngine)) -#define CAMEL_IMAPP_ENGINE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_ENGINE_TYPE, CamelIMAPPEngineClass)) -#define CAMEL_IS_IMAP_ENGINE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_ENGINE_TYPE)) - -typedef struct _CamelIMAPPEngine CamelIMAPPEngine; -typedef struct _CamelIMAPPEngineClass CamelIMAPPEngineClass; - -typedef struct _CamelIMAPPCommandPart CamelIMAPPCommandPart; -typedef struct _CamelIMAPPCommand CamelIMAPPCommand; - -typedef enum { - CAMEL_IMAPP_COMMAND_SIMPLE = 0, - CAMEL_IMAPP_COMMAND_DATAWRAPPER, - CAMEL_IMAPP_COMMAND_STREAM, - CAMEL_IMAPP_COMMAND_AUTH, - CAMEL_IMAPP_COMMAND_MASK = 0xff, - CAMEL_IMAPP_COMMAND_CONTINUATION = 0x8000 /* does this command expect continuation? */ -} camel_imapp_command_part_t; - -struct _CamelIMAPPCommandPart { - struct _CamelIMAPPCommandPart *next; - struct _CamelIMAPPCommandPart *prev; - - struct _CamelIMAPPCommand *parent; - - int data_size; - char *data; - - camel_imapp_command_part_t type; - - int ob_size; - CamelObject *ob; -}; - -typedef int (*CamelIMAPPEngineFunc)(struct _CamelIMAPPEngine *engine, guint32 id, void *data); -typedef void (*CamelIMAPPCommandFunc)(struct _CamelIMAPPEngine *engine, struct _CamelIMAPPCommand *, void *data); - -/* FIXME: make this refcounted */ -struct _CamelIMAPPCommand { - struct _CamelIMAPPCommand *next; - struct _CamelIMAPPCommand *prev; - - const char *name; /* command name/type (e.g. FETCH) */ - - /* FIXME: remove this select stuff */ - char *select; /* if we need to run against a specific folder */ - struct _status_info *status; /* status for command, indicates it is complete if != NULL */ - - unsigned int tag; - - struct _CamelStreamMem *mem; /* for building the part */ - EDList parts; - CamelIMAPPCommandPart *current; - - CamelIMAPPCommandFunc complete; - void *complete_data; -}; - -typedef struct _CamelIMAPPSelectResponse CamelIMAPPSelectResponse; - -struct _CamelIMAPPSelectResponse { - struct _status_info *status; - guint32 exists; - guint32 recent; - guint32 uidvalidity; - guint32 unseen; - guint32 permanentflags; -}; - -enum { - IMAP_CAPABILITY_IMAP4 = (1 << 0), - IMAP_CAPABILITY_IMAP4REV1 = (1 << 1), - IMAP_CAPABILITY_STATUS = (1 << 2), - IMAP_CAPABILITY_NAMESPACE = (1 << 3), - IMAP_CAPABILITY_UIDPLUS = (1 << 4), - IMAP_CAPABILITY_LITERALPLUS = (1 << 5), - IMAP_CAPABILITY_STARTTLS = (1 << 6), -}; - -/* currently selected states */ -typedef enum _camel_imapp_engine_state_t { - IMAP_ENGINE_DISCONNECT, /* only happens during shutdown */ - IMAP_ENGINE_CONNECT, /* connected, not authenticated */ - IMAP_ENGINE_AUTH, /* connected, and authenticated */ - IMAP_ENGINE_SELECT, /* and selected, select holds selected folder */ -} camel_imapp_engine_state_t; - -struct _CamelIMAPPEngine { - CamelObject parent_object; - - CamelIMAPPStream *stream; - - camel_imapp_engine_state_t state; - - guint32 capa; /* capabilities for this server, refresh with :capabilities() */ - - GHashTable *handlers; - - unsigned char tagprefix; /* out tag prefix 'A' 'B' ... 'Z' */ - unsigned int tag; /* next command tag */ - - char *select; /* *currently* selected folder */ - char *last_select; /* last selected or to-be selected folder (e.g. outstanding queued select) */ - CamelIMAPPCommand *literal;/* current literal op */ - EDList active; /* active queue */ - EDList queue; /* outstanding queue */ - EDList done; /* done queue, awaiting reclamation */ - - /* keep track of running a select */ - struct _CamelIMAPPSelectResponse *select_response; -}; - -struct _CamelIMAPPEngineClass { - CamelObjectClass parent_class; - - unsigned char tagprefix; - - /* Events: - status(struct _status_info *); - */ -}; - -CamelType camel_imapp_engine_get_type (void); - -CamelIMAPPEngine *camel_imapp_engine_new(CamelIMAPPStream *stream); - -void camel_imapp_engine_add_handler(CamelIMAPPEngine *imap, const char *response, CamelIMAPPEngineFunc func, void *data); -int camel_imapp_engine_iterate(CamelIMAPPEngine *imap, CamelIMAPPCommand *wait); /* throws PARSE,IO exception */ -int camel_imapp_engine_skip(CamelIMAPPEngine *imap); -int camel_imapp_engine_capabilities(CamelIMAPPEngine *imap); - -CamelIMAPPCommand *camel_imapp_engine_command_new (CamelIMAPPEngine *imap, const char *name, const char *select, const char *fmt, ...); -void camel_imapp_engine_command_complete(CamelIMAPPEngine *imap, struct _CamelIMAPPCommand *, CamelIMAPPCommandFunc func, void *data); -void camel_imapp_engine_command_add (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic, const char *fmt, ...); -void camel_imapp_engine_command_free (CamelIMAPPEngine *imap, CamelIMAPPCommand *ic); -void camel_imapp_engine_command_queue(CamelIMAPPEngine *imap, CamelIMAPPCommand *ic); /* throws IO exception */ -CamelIMAPPCommand *camel_imapp_engine_command_find (CamelIMAPPEngine *imap, const char *name); -CamelIMAPPCommand *camel_imapp_engine_command_find_tag(CamelIMAPPEngine *imap, unsigned int tag); - -/* util functions */ -CamelIMAPPSelectResponse *camel_imapp_engine_select(CamelIMAPPEngine *imap, const char *name); -void camel_imapp_engine_select_free(CamelIMAPPEngine *imap, CamelIMAPPSelectResponse *select); - -#endif diff --git a/camel/providers/imapp/camel-imapp-exception.h b/camel/providers/imapp/camel-imapp-exception.h deleted file mode 100644 index 5e18b6c815..0000000000 --- a/camel/providers/imapp/camel-imapp-exception.h +++ /dev/null @@ -1,35 +0,0 @@ - -/* This implements 'real' exceptions that work a bit like c++/java exceptions */ - -/* Still experimental code */ - -#ifndef __CAMEL_IMAPP_EXCEPTION_H -#define __CAMEL_IMAPP_EXCEPTION_H - -#include <setjmp.h> -#include "camel/camel-exception.h" - -struct _CamelExceptionEnv { - struct _CamelExceptionEnv *parent; - CamelException *ex; - jmp_buf env; -}; - -#define CAMEL_TRY { struct _CamelExceptionEnv __env; camel_exception_try(&__env); if (setjmp(__env.env) == 0) -#define CAMEL_IGNORE camel_exception_done(&__env); } -#define CAMEL_CATCH(x) { CamelException *x; x=__env.ex; if (x != NULL) -#define CAMEL_DONE } camel_exception_done(&__env); } -#define CAMEL_DROP() camel_exception_drop(&__env) - -void camel_exception_setup(void); - -/* internal functions, use macro's above */ -void camel_exception_try(struct _CamelExceptionEnv *env); -void camel_exception_done(struct _CamelExceptionEnv *env); -void camel_exception_drop(struct _CamelExceptionEnv *env); - -/* user functions */ -void camel_exception_throw_ex(CamelException *ex) __attribute__ ((noreturn)); -void camel_exception_throw(int id, char *fmt, ...) __attribute__ ((noreturn)); - -#endif diff --git a/camel/providers/imapp/camel-imapp-fetch-stream.c b/camel/providers/imapp/camel-imapp-fetch-stream.c deleted file mode 100644 index bf18aac57b..0000000000 --- a/camel/providers/imapp/camel-imapp-fetch-stream.c +++ /dev/null @@ -1,183 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Author: - * Michael Zucchi <notzed@ximian.com> - * - * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> - -#include <glib.h> - -#include <camel/camel-stream-mem.h> - -#include "camel-imapp-stream.h" -#include "camel-imapp-exception.h" - -#define t(x) -#define io(x) x - -static CamelObjectClass *parent_class = NULL; - -/* Returns the class for a CamelStream */ -#define CS_CLASS(so) CAMEL_IMAPP_FETCH_STREAM_CLASS(CAMEL_OBJECT_GET_CLASS(so)) - -static ssize_t -stream_read(CamelStream *stream, char *buffer, size_t n) -{ - CamelIMAPPFetchStream *is = (CamelIMAPPFetchStream *)stream; - ssize_t max; - - /* make sure we have all the data read in */ - while (camel_imapp_engine_iterate(is->engine, is->command)>0) - ; - - if (is->literal == 0 || n == 0) - return 0; - - max = is->end - is->ptr; - if (max > 0) { - max = MIN(max, is->literal); - max = MIN(max, n); - memcpy(buffer, is->ptr, max); - is->ptr += max; - } else { - max = MIN(is->literal, n); - max = camel_stream_read(is->source, buffer, max); - if (max <= 0) - return max; - } - - is->literal -= max; - - return max; -} - -static ssize_t -stream_write(CamelStream *stream, const char *buffer, size_t n) -{ - CamelIMAPPFetchStream *is = (CamelIMAPPFetchStream *)stream; - - return camel_stream_write(is->source, buffer, n); -} - -static int -stream_close(CamelStream *stream) -{ - /* nop? */ - return 0; -} - -static int -stream_flush(CamelStream *stream) -{ - /* nop? */ - return 0; -} - -static gboolean -stream_eos(CamelStream *stream) -{ - CamelIMAPPFetchStream *is = (CamelIMAPPFetchStream *)stream; - - return is->literal == 0; -} - -static int -stream_reset(CamelStream *stream) -{ - /* nop? reset literal mode? */ - return 0; -} - -static void -camel_imapp_fetch_stream_class_init (CamelStreamClass *camel_imapp_fetch_stream_class) -{ - CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_imapp_fetch_stream_class; - - parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE ); - - /* virtual method definition */ - camel_stream_class->read = stream_read; - camel_stream_class->write = stream_write; - camel_stream_class->close = stream_close; - camel_stream_class->flush = stream_flush; - camel_stream_class->eos = stream_eos; - camel_stream_class->reset = stream_reset; -} - -static void -camel_imapp_fetch_stream_init(CamelIMAPPFetchStream *is, CamelIMAPPFetchStreamClass *isclass) -{ - ; -} - -static void -camel_imapp_fetch_stream_finalise(CamelIMAPPFetchStream *is) -{ - if (is->engine) - camel_object_unref(is->engine); -} - -CamelType -camel_imapp_fetch_stream_get_type (void) -{ - static CamelType camel_imapp_fetch_stream_type = CAMEL_INVALID_TYPE; - - if (camel_imapp_fetch_stream_type == CAMEL_INVALID_TYPE) { - setup_table(); - camel_imapp_fetch_stream_type = camel_type_register( camel_stream_get_type(), - "CamelIMAPPFetchStream", - sizeof( CamelIMAPPFetchStream ), - sizeof( CamelIMAPPFetchStreamClass ), - (CamelObjectClassInitFunc) camel_imapp_fetch_stream_class_init, - NULL, - (CamelObjectInitFunc) camel_imapp_fetch_stream_init, - (CamelObjectFinalizeFunc) camel_imapp_fetch_stream_finalise ); - } - - return camel_imapp_fetch_stream_type; -} - -/** - * camel_imapp_fetch_stream_new: - * - * Return value: the stream - **/ -CamelStream * -camel_imapp_fetch_stream_new(CamelIMAPPEngine *ie, const char *uid, const char *body) -{ - CamelIMAPPFetchStream *is; - - is = (CamelIMAPPFetchStream *)camel_object_new(camel_imapp_fetch_stream_get_type ()); - is->engine = ie; - camel_object_ref(ie); - - is->command = camel_imapp_engine_command_new(ie, "FETCH", NULL, "FETCH %t (BODY[%t]<0.4096>", uid, body); - camel_imapp_engine_command_queue(ie, command); - - return (CamelStream *)is; -} - diff --git a/camel/providers/imapp/camel-imapp-fetch-stream.h b/camel/providers/imapp/camel-imapp-fetch-stream.h deleted file mode 100644 index c9281ff64f..0000000000 --- a/camel/providers/imapp/camel-imapp-fetch-stream.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_IMAPP_FETCH_STREAM_H -#define _CAMEL_IMAPP_FETCH_STREAM_H - -#include <camel/camel-stream.h> - -#define CAMEL_IMAPP_FETCH_STREAM(obj) CAMEL_CHECK_CAST (obj, camel_imapp_fetch_stream_get_type (), CamelIMAPPFetchStream) -#define CAMEL_IMAPP_FETCH_STREAM_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_fetch_stream_get_type (), CamelIMAPPFetchStreamClass) -#define CAMEL_IS_IMAP_FETCH_STREAM(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_fetch_stream_get_type ()) - -typedef struct _CamelIMAPPFetchStreamClass CamelIMAPPFetchStreamClass; -typedef struct _CamelIMAPPFetchStream CamelIMAPPFetchStream; - -struct _CamelIMAPPFetchStream { - CamelStream parent; - - struct _CamelIMAPPEngine *engine; -}; - -struct _CamelIMAPPFetchStreamClass { - CamelStreamClass parent_class; -}; - -CamelType camel_imapp_fetch_stream_get_type (void); - -CamelStream *camel_imapp_fetch_stream_new (struct _CamelIMAPPEngine *src, const char *uid, const char *spec); - -#endif /* ! _CAMEL_IMAPP_FETCH_STREAM_H */ diff --git a/camel/providers/imapp/camel-imapp-folder.c b/camel/providers/imapp/camel-imapp-folder.c deleted file mode 100644 index 967ab541f6..0000000000 --- a/camel/providers/imapp/camel-imapp-folder.c +++ /dev/null @@ -1,269 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-folder.c : class for a imap folder */ - -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2002 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> - -#include "camel/camel-exception.h" -#include "camel/camel-stream-mem.h" -#include "camel/camel-stream-filter.h" -#include "camel/camel-mime-message.h" -#include "camel/camel-operation.h" -#include "camel/camel-data-cache.h" -#include "camel/camel-session.h" -#include "camel/camel-file-utils.h" - -#include "camel-imapp-store.h" -#include "camel-imapp-folder.h" -#include "camel-imapp-summary.h" -#include "camel-imapp-exception.h" - -#include <e-util/md5-utils.h> - -#include <stdlib.h> -#include <string.h> - -#define d(x) - -#define CF_CLASS(o) (CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(o))) -static CamelFolderClass *parent_class; - -static void imap_finalize (CamelObject *object); -static void imap_refresh_info (CamelFolder *folder, CamelException *ex); -static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex); -static CamelMimeMessage *imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex); - -static void -imap_folder_class_init (CamelIMAPPFolderClass *camel_imapp_folder_class) -{ - CamelFolderClass *camel_folder_class = CAMEL_FOLDER_CLASS(camel_imapp_folder_class); - - parent_class = CAMEL_FOLDER_CLASS(camel_folder_get_type()); - - /* virtual method overload */ - camel_folder_class->refresh_info = imap_refresh_info; - camel_folder_class->sync = imap_sync; - - camel_folder_class->get_message = imap_get_message; - /*camel_folder_class->set_message_flags = imap_set_message_flags;*/ -} - -static void -imap_folder_init(CamelObject *o, CamelObjectClass *klass) -{ - CamelFolder *folder = (CamelFolder *)o; - CamelIMAPPFolder *ifolder = (CamelIMAPPFolder *)o; - - folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | - CAMEL_FOLDER_HAS_SEARCH_CAPABILITY); - - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_USER; - - /* FIXME: this is just a skeleton */ - - ifolder->changes = camel_folder_change_info_new(); -} - -CamelType -camel_imapp_folder_get_type (void) -{ - static CamelType camel_imapp_folder_type = CAMEL_INVALID_TYPE; - - if (!camel_imapp_folder_type) { - camel_imapp_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelIMAPPFolder", - sizeof (CamelIMAPPFolder), - sizeof (CamelIMAPPFolderClass), - (CamelObjectClassInitFunc) imap_folder_class_init, - NULL, - imap_folder_init, - (CamelObjectFinalizeFunc) imap_finalize); - } - - return camel_imapp_folder_type; -} - -void -imap_finalize (CamelObject *object) -{ - CamelIMAPPFolder *folder = (CamelIMAPPFolder *)object; - - camel_folder_change_info_free(folder->changes); -} - -CamelFolder * -camel_imapp_folder_new(CamelStore *store, const char *path) -{ - CamelFolder *folder; - char *root; - - d(printf("opening imap folder '%s'\n", path)); - - folder = CAMEL_FOLDER (camel_object_new (CAMEL_IMAPP_FOLDER_TYPE)); - camel_folder_construct(folder, store, path, path); - - ((CamelIMAPPFolder *)folder)->raw_name = g_strdup(path); - - folder->summary = camel_imapp_summary_new(); - - root = camel_session_get_storage_path(((CamelService *)store)->session, (CamelService *)store, NULL); - if (root) { - char *base = g_build_filename(root, path, NULL); - char *file = g_build_filename(base, ".ev-summary", NULL); - - camel_mkdir(base, 0777); - g_free(base); - - camel_folder_summary_set_filename(folder->summary, file); - printf("loading summary from '%s' (root=%s)\n", file, root); - g_free(file); - camel_folder_summary_load(folder->summary); - g_free(root); - } - - return folder; -} - -void -camel_imapp_folder_open(CamelIMAPPFolder *folder, CamelException *ex) -{ - /* */ -} - -void -camel_imapp_folder_delete(CamelIMAPPFolder *folder, CamelException *ex) -{ -} - -void -camel_imapp_folder_rename(CamelIMAPPFolder *folder, const char *new, CamelException *ex) -{ -} - -void -camel_imapp_folder_close(CamelIMAPPFolder *folder, CamelException *ex) -{ -} - -static void -imap_refresh_info (CamelFolder *folder, CamelException *ex) -{ - printf("imapp refresh info?\n"); -} - -static void -imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) -{ - camel_imapp_driver_sync(((CamelIMAPPStore *)(folder->parent_store))->driver, expunge, (CamelIMAPPFolder *) folder); -} - -static CamelMimeMessage * -imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) -{ - CamelMimeMessage * volatile msg = NULL; - CamelStream * volatile stream = NULL; - - printf("get message '%s'\n", uid); - - CAMEL_TRY { - /* simple implementation, just get whole message in 1 go */ - stream = camel_imapp_driver_fetch(((CamelIMAPPStore *)(folder->parent_store))->driver, (CamelIMAPPFolder *)folder, uid, ""); - camel_stream_reset(stream); - msg = camel_mime_message_new(); - if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)msg, stream) != -1) { - /* do we care? */ - } - } CAMEL_CATCH(e) { - if (msg) - camel_object_unref(msg); - msg = NULL; - camel_exception_xfer(ex, e); - } CAMEL_DONE; - - if (stream) - camel_object_unref(stream); - - return msg; -} - - -/* Algorithm for selecting a folder: - - - If uidvalidity == old uidvalidity - and exsists == old exists - and recent == old recent - and unseen == old unseen - Assume our summary is correct - for each summary item - mark the summary item as 'old/not updated' - rof - fetch flags from 1:* - for each fetch response - info = summary[index] - if info.uid != uid - info = summary_by_uid[uid] - fi - if info == NULL - create new info @ index - fi - if got.flags - update flags - fi - if got.header - update based on header - mark as retrieved - else if got.body - update based on imap body - mark as retrieved - fi - - Async fetch response: - info = summary[index] - if info == null - if uid == null - force resync/select? - info = empty @ index - else if uid && info.uid != uid - force a resync? - return - fi - - if got.flags { - info.flags = flags - } - if got.header { - info.init(header) - info.empty = false - } - -info.state - 2 bit field in flags - 0 = empty, nothing set - 1 = uid & flags set - 2 = update required - 3 = up to date -*/ - diff --git a/camel/providers/imapp/camel-imapp-folder.h b/camel/providers/imapp/camel-imapp-folder.h deleted file mode 100644 index 329c66b7fc..0000000000 --- a/camel/providers/imapp/camel-imapp-folder.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-folder.h : Class for a IMAP folder */ - -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2002 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef CAMEL_IMAPP_FOLDER_H -#define CAMEL_IMAPP_FOLDER_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-folder.h> - -#define CAMEL_IMAPP_FOLDER_TYPE (camel_imapp_folder_get_type ()) -#define CAMEL_IMAPP_FOLDER(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_FOLDER_TYPE, CamelIMAPPFolder)) -#define CAMEL_IMAPP_FOLDER_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_FOLDER_TYPE, CamelIMAPPFolderClass)) -#define CAMEL_IS_IMAP_FOLDER(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_FOLDER_TYPE)) - -typedef struct _CamelIMAPPFolder { - CamelFolder parent_object; - - char *raw_name; - CamelFolderChangeInfo *changes; - - guint32 exists; - guint32 recent; - guint32 uidvalidity; - guint32 unseen; - guint32 permanentflags; -} CamelIMAPPFolder; - -typedef struct _CamelIMAPPFolderClass { - CamelFolderClass parent_class; -} CamelIMAPPFolderClass; - -/* Standard Camel function */ -CamelType camel_imapp_folder_get_type (void); - -/* public methods */ -CamelFolder *camel_imapp_folder_new(CamelStore *parent, const char *path); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_IMAPP_FOLDER_H */ diff --git a/camel/providers/imapp/camel-imapp-provider.c b/camel/providers/imapp/camel-imapp-provider.c deleted file mode 100644 index 6b0cdd2d43..0000000000 --- a/camel/providers/imapp/camel-imapp-provider.c +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-pop3-provider.c: pop3 provider registration code */ - -/* - * Authors : - * Dan Winship <danw@ximian.com> - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2002 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "camel/camel-provider.h" -#include "camel/camel-session.h" -#include "camel/camel-url.h" -#include "camel/camel-sasl.h" - -#include "camel-imapp-store.h" - -CamelProviderConfEntry imapp_conf_entries[] = { - { CAMEL_PROVIDER_CONF_SECTION_START, NULL, NULL, - N_("Message storage") }, - { CAMEL_PROVIDER_CONF_SECTION_END }, - { CAMEL_PROVIDER_CONF_END } -}; - -static CamelProvider imapp_provider = { - "imapp", - - N_("IMAP+"), - - N_("Experimental IMAP 4(.1) client\n" - "This is untested and unsupported code, you want to use plain imap instead.\n\n" - " !!! DO NOT USE THIS FOR PRODUCTION EMAIL !!!\n"), - "mail", - - CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE | - CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL, - - CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH, - - imapp_conf_entries, - - /* ... */ -}; - -CamelServiceAuthType camel_imapp_password_authtype = { - N_("Password"), - - N_("This option will connect to the IMAP server using a " - "plaintext password."), - - "", - TRUE -}; - -void -camel_imapp_module_init(CamelSession *session) -{ - extern void camel_exception_setup(void); - - imapp_provider.object_types[CAMEL_PROVIDER_STORE] = camel_imapp_store_get_type(); - imapp_provider.url_hash = camel_url_hash; - imapp_provider.url_equal = camel_url_equal; - - imapp_provider.authtypes = g_list_prepend(imapp_provider.authtypes, camel_sasl_authtype_list(FALSE)); - imapp_provider.authtypes = g_list_prepend(imapp_provider.authtypes, &camel_imapp_password_authtype); - - /* blah ... could just use it in object setup? */ - /* TEMPORARY */ - camel_exception_setup(); - - camel_session_register_provider(session, &imapp_provider); -} - -void -camel_provider_module_init(CamelSession *session) -{ - camel_imapp_module_init(session); -} diff --git a/camel/providers/imapp/camel-imapp-store-summary.c b/camel/providers/imapp/camel-imapp-store-summary.c deleted file mode 100644 index a3ad57fb11..0000000000 --- a/camel/providers/imapp/camel-imapp-store-summary.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright (C) 2002 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <unistd.h> -#include <ctype.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -#include "camel-imapp-store-summary.h" - -#include "camel/camel-file-utils.h" - -#include "camel-string-utils.h" -#include "e-util/md5-utils.h" -#include "e-util/e-memory.h" - -#include "camel-private.h" -#include "camel-utf8.h" - -#define d(x) -#define io(x) /* io debug */ - -#define CAMEL_IMAPP_STORE_SUMMARY_VERSION_0 (0) - -#define CAMEL_IMAPP_STORE_SUMMARY_VERSION (0) - -#define _PRIVATE(o) (((CamelIMAPPStoreSummary *)(o))->priv) - -static int summary_header_load(CamelStoreSummary *, FILE *); -static int summary_header_save(CamelStoreSummary *, FILE *); - -/*static CamelStoreInfo * store_info_new(CamelStoreSummary *, const char *);*/ -static CamelStoreInfo * store_info_load(CamelStoreSummary *, FILE *); -static int store_info_save(CamelStoreSummary *, FILE *, CamelStoreInfo *); -static void store_info_free(CamelStoreSummary *, CamelStoreInfo *); - -static const char *store_info_string(CamelStoreSummary *, const CamelStoreInfo *, int); -static void store_info_set_string(CamelStoreSummary *, CamelStoreInfo *, int, const char *); - -static void camel_imapp_store_summary_class_init (CamelIMAPPStoreSummaryClass *klass); -static void camel_imapp_store_summary_init (CamelIMAPPStoreSummary *obj); -static void camel_imapp_store_summary_finalise (CamelObject *obj); - -static CamelStoreSummaryClass *camel_imapp_store_summary_parent; - -static void -camel_imapp_store_summary_class_init (CamelIMAPPStoreSummaryClass *klass) -{ - CamelStoreSummaryClass *ssklass = (CamelStoreSummaryClass *)klass; - - ssklass->summary_header_load = summary_header_load; - ssklass->summary_header_save = summary_header_save; - - /*ssklass->store_info_new = store_info_new;*/ - ssklass->store_info_load = store_info_load; - ssklass->store_info_save = store_info_save; - ssklass->store_info_free = store_info_free; - - ssklass->store_info_string = store_info_string; - ssklass->store_info_set_string = store_info_set_string; -} - -static void -camel_imapp_store_summary_init (CamelIMAPPStoreSummary *s) -{ - /*struct _CamelIMAPPStoreSummaryPrivate *p; - - p = _PRIVATE(s) = g_malloc0(sizeof(*p));*/ - - ((CamelStoreSummary *)s)->store_info_size = sizeof(CamelIMAPPStoreInfo); - s->version = CAMEL_IMAPP_STORE_SUMMARY_VERSION; -} - -static void -camel_imapp_store_summary_finalise (CamelObject *obj) -{ - /*struct _CamelIMAPPStoreSummaryPrivate *p;*/ - /*CamelIMAPPStoreSummary *s = (CamelIMAPPStoreSummary *)obj;*/ - - /*p = _PRIVATE(obj); - g_free(p);*/ -} - -CamelType -camel_imapp_store_summary_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - camel_imapp_store_summary_parent = (CamelStoreSummaryClass *)camel_store_summary_get_type(); - type = camel_type_register((CamelType)camel_imapp_store_summary_parent, "CamelIMAPPStoreSummary", - sizeof (CamelIMAPPStoreSummary), - sizeof (CamelIMAPPStoreSummaryClass), - (CamelObjectClassInitFunc) camel_imapp_store_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_imapp_store_summary_init, - (CamelObjectFinalizeFunc) camel_imapp_store_summary_finalise); - } - - return type; -} - -/** - * camel_imapp_store_summary_new: - * - * Create a new CamelIMAPPStoreSummary object. - * - * Return value: A new CamelIMAPPStoreSummary widget. - **/ -CamelIMAPPStoreSummary * -camel_imapp_store_summary_new (void) -{ - CamelIMAPPStoreSummary *new = CAMEL_IMAPP_STORE_SUMMARY ( camel_object_new (camel_imapp_store_summary_get_type ())); - - return new; -} - -/** - * camel_imapp_store_summary_full_name: - * @s: - * @path: - * - * Retrieve a summary item by full name. - * - * A referenced to the summary item is returned, which may be - * ref'd or free'd as appropriate. - * - * Return value: The summary item, or NULL if the @full_name name - * is not available. - * It must be freed using camel_store_summary_info_free(). - **/ -CamelIMAPPStoreInfo * -camel_imapp_store_summary_full_name(CamelIMAPPStoreSummary *s, const char *full_name) -{ - int count, i; - CamelIMAPPStoreInfo *info; - - count = camel_store_summary_count((CamelStoreSummary *)s); - for (i=0;i<count;i++) { - info = (CamelIMAPPStoreInfo *)camel_store_summary_index((CamelStoreSummary *)s, i); - if (info) { - if (strcmp(info->full_name, full_name) == 0) - return info; - camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info); - } - } - - return NULL; -} - -char * -camel_imapp_store_summary_full_to_path(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep) -{ - char *path, *p; - int c; - const char *f; - - if (dir_sep != '/') { - p = path = alloca(strlen(full_name)*3+1); - f = full_name; - while ( (c = *f++ & 0xff) ) { - if (c == dir_sep) - *p++ = '/'; - else if (c == '/' || c == '%') - p += sprintf(p, "%%%02X", c); - else - *p++ = c; - } - *p = 0; - } else - path = (char *)full_name; - - return camel_utf7_utf8(path); -} - -static guint32 hexnib(guint32 c) -{ - if (c >= '0' && c <= '9') - return c-'0'; - else if (c>='A' && c <= 'Z') - return c-'A'+10; - else - return 0; -} - -char * -camel_imapp_store_summary_path_to_full(CamelIMAPPStoreSummary *s, const char *path, char dir_sep) -{ - unsigned char *full, *f; - guint32 c, v = 0; - const char *p; - int state=0; - char *subpath, *last = NULL; - CamelStoreInfo *si; - CamelIMAPPStoreNamespace *ns; - - /* check to see if we have a subpath of path already defined */ - subpath = alloca(strlen(path)+1); - strcpy(subpath, path); - do { - si = camel_store_summary_path((CamelStoreSummary *)s, subpath); - if (si == NULL) { - last = strrchr(subpath, '/'); - if (last) - *last = 0; - } - } while (si == NULL && last); - - /* path is already present, use the raw version we have */ - if (si && strlen(subpath) == strlen(path)) { - f = g_strdup(camel_imapp_store_info_full_name(s, si)); - camel_store_summary_info_free((CamelStoreSummary *)s, si); - return f; - } - - ns = camel_imapp_store_summary_namespace_find_path(s, path); - - f = full = alloca(strlen(path)*2+1); - if (si) - p = path + strlen(subpath); - else if (ns) - p = path + strlen(ns->path); - else - p = path; - - while ( (c = camel_utf8_getc((const unsigned char **)&p)) ) { - switch(state) { - case 0: - if (c == '%') - state = 1; - else { - if (c == '/') - c = dir_sep; - camel_utf8_putc(&f, c); - } - break; - case 1: - state = 2; - v = hexnib(c)<<4; - break; - case 2: - state = 0; - v |= hexnib(c); - camel_utf8_putc(&f, v); - break; - } - } - camel_utf8_putc(&f, c); - - /* merge old path part if required */ - f = camel_utf8_utf7(full); - if (si) { - full = g_strdup_printf("%s%s", camel_imapp_store_info_full_name(s, si), f); - g_free(f); - camel_store_summary_info_free((CamelStoreSummary *)s, si); - f = full; - } else if (ns) { - full = g_strdup_printf("%s%s", ns->full_name, f); - g_free(f); - f = full; - } - - return f; -} - -CamelIMAPPStoreInfo * -camel_imapp_store_summary_add_from_full(CamelIMAPPStoreSummary *s, const char *full, char dir_sep) -{ - CamelIMAPPStoreInfo *info; - char *pathu8, *prefix; - int len; - char *full_name; - CamelIMAPPStoreNamespace *ns; - - d(printf("adding full name '%s' '%c'\n", full, dir_sep)); - - len = strlen(full); - full_name = alloca(len+1); - strcpy(full_name, full); - if (full_name[len-1] == dir_sep) - full_name[len-1] = 0; - - info = camel_imapp_store_summary_full_name(s, full_name); - if (info) { - camel_store_summary_info_free((CamelStoreSummary *)s, (CamelStoreInfo *)info); - d(printf(" already there\n")); - return info; - } - - ns = camel_imapp_store_summary_namespace_find_full(s, full_name); - if (ns) { - d(printf("(found namespace for '%s' ns '%s') ", full_name, ns->path)); - len = strlen(ns->full_name); - if (len >= strlen(full_name)) { - pathu8 = g_strdup(ns->path); - } else { - if (full_name[len] == ns->sep) - len++; - - prefix = camel_imapp_store_summary_full_to_path(s, full_name+len, ns->sep); - if (*ns->path) { - pathu8 = g_strdup_printf ("%s/%s", ns->path, prefix); - g_free (prefix); - } else { - pathu8 = prefix; - } - } - d(printf(" (pathu8 = '%s')", pathu8)); - } else { - d(printf("(Cannot find namespace for '%s')\n", full_name)); - pathu8 = camel_imapp_store_summary_full_to_path(s, full_name, dir_sep); - } - - info = (CamelIMAPPStoreInfo *)camel_store_summary_add_from_path((CamelStoreSummary *)s, pathu8); - if (info) { - d(printf(" '%s' -> '%s'\n", pathu8, full_name)); - camel_store_info_set_string((CamelStoreSummary *)s, (CamelStoreInfo *)info, CAMEL_IMAPP_STORE_INFO_FULL_NAME, full_name); - } else - d(printf(" failed\n")); - - return info; -} - -/* should this be const? */ -/* TODO: deprecate/merge this function with path_to_full */ -char * -camel_imapp_store_summary_full_from_path(CamelIMAPPStoreSummary *s, const char *path) -{ - CamelIMAPPStoreNamespace *ns; - char *name = NULL; - - ns = camel_imapp_store_summary_namespace_find_path(s, path); - if (ns) - name = camel_imapp_store_summary_path_to_full(s, path, ns->sep); - - d(printf("looking up path %s -> %s\n", path, name?name:"not found")); - - return name; -} - -/* TODO: this api needs some more work */ -CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_new(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep) -{ - CamelIMAPPStoreNamespace *ns; - char *p; - int len; - - ns = g_malloc0(sizeof(*ns)); - ns->full_name = g_strdup(full_name); - len = strlen(ns->full_name)-1; - if (len >= 0 && ns->full_name[len] == dir_sep) - ns->full_name[len] = 0; - ns->sep = dir_sep; - - p = ns->path = camel_imapp_store_summary_full_to_path(s, ns->full_name, dir_sep); - while (*p) { - if (*p == '/') - *p = '.'; - p++; - } - - return ns; -} - -void camel_imapp_store_summary_namespace_set(CamelIMAPPStoreSummary *s, CamelIMAPPStoreNamespace *ns) -{ - static void namespace_clear(CamelStoreSummary *s); - - d(printf("Setting namesapce to '%s' '%c' -> '%s'\n", ns->full_name, ns->sep, ns->path)); - namespace_clear((CamelStoreSummary *)s); - s->namespace = ns; - camel_store_summary_touch((CamelStoreSummary *)s); -} - -CamelIMAPPStoreNamespace * -camel_imapp_store_summary_namespace_find_path(CamelIMAPPStoreSummary *s, const char *path) -{ - int len; - CamelIMAPPStoreNamespace *ns; - - /* NB: this currently only compares against 1 namespace, in future compare against others */ - ns = s->namespace; - while (ns) { - len = strlen(ns->path); - if (len == 0 - || (strncmp(ns->path, path, len) == 0 - && (path[len] == '/' || path[len] == 0))) - break; - ns = NULL; - } - - /* have a default? */ - return ns; -} - -CamelIMAPPStoreNamespace * -camel_imapp_store_summary_namespace_find_full(CamelIMAPPStoreSummary *s, const char *full) -{ - int len; - CamelIMAPPStoreNamespace *ns; - - /* NB: this currently only compares against 1 namespace, in future compare against others */ - ns = s->namespace; - while (ns) { - len = strlen(ns->full_name); - d(printf("find_full: comparing namespace '%s' to name '%s'\n", ns->full_name, full)); - if (len == 0 - || (strncmp(ns->full_name, full, len) == 0 - && (full[len] == ns->sep || full[len] == 0))) - break; - ns = NULL; - } - - /* have a default? */ - return ns; -} - -static void -namespace_free(CamelStoreSummary *s, CamelIMAPPStoreNamespace *ns) -{ - g_free(ns->path); - g_free(ns->full_name); - g_free(ns); -} - -static void -namespace_clear(CamelStoreSummary *s) -{ - CamelIMAPPStoreSummary *is = (CamelIMAPPStoreSummary *)s; - - if (is->namespace) - namespace_free(s, is->namespace); - is->namespace = NULL; -} - -static CamelIMAPPStoreNamespace * -namespace_load(CamelStoreSummary *s, FILE *in) -{ - CamelIMAPPStoreNamespace *ns; - guint32 sep = '/'; - - ns = g_malloc0(sizeof(*ns)); - if (camel_file_util_decode_string(in, &ns->path) == -1 - || camel_file_util_decode_string(in, &ns->full_name) == -1 - || camel_file_util_decode_uint32(in, &sep) == -1) { - namespace_free(s, ns); - ns = NULL; - } else { - ns->sep = sep; - } - - return ns; -} - -static int -namespace_save(CamelStoreSummary *s, FILE *in, CamelIMAPPStoreNamespace *ns) -{ - if (camel_file_util_encode_string(in, ns->path) == -1 - || camel_file_util_encode_string(in, ns->full_name) == -1 - || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1) - return -1; - - return 0; -} - -static int -summary_header_load(CamelStoreSummary *s, FILE *in) -{ - CamelIMAPPStoreSummary *is = (CamelIMAPPStoreSummary *)s; - gint32 version, capabilities, count; - - namespace_clear(s); - - if (camel_imapp_store_summary_parent->summary_header_load((CamelStoreSummary *)s, in) == -1 - || camel_file_util_decode_fixed_int32(in, &version) == -1) - return -1; - - is->version = version; - - if (version < CAMEL_IMAPP_STORE_SUMMARY_VERSION_0) { - g_warning("Store summary header version too low"); - return -1; - } - - /* note file format can be expanded to contain more namespaces, but only 1 at the moment */ - if (camel_file_util_decode_fixed_int32(in, &capabilities) == -1 - || camel_file_util_decode_fixed_int32(in, &count) == -1 - || count > 1) - return -1; - - is->capabilities = capabilities; - if (count == 1) { - if ((is->namespace = namespace_load(s, in)) == NULL) - return -1; - } - - return 0; -} - -static int -summary_header_save(CamelStoreSummary *s, FILE *out) -{ - CamelIMAPPStoreSummary *is = (CamelIMAPPStoreSummary *)s; - guint32 count; - - count = is->namespace?1:0; - - /* always write as latest version */ - if (camel_imapp_store_summary_parent->summary_header_save((CamelStoreSummary *)s, out) == -1 - || camel_file_util_encode_fixed_int32(out, CAMEL_IMAPP_STORE_SUMMARY_VERSION) == -1 - || camel_file_util_encode_fixed_int32(out, is->capabilities) == -1 - || camel_file_util_encode_fixed_int32(out, count) == -1) - return -1; - - if (is->namespace && namespace_save(s, out, is->namespace) == -1) - return -1; - - return 0; -} - -static CamelStoreInfo * -store_info_load(CamelStoreSummary *s, FILE *in) -{ - CamelIMAPPStoreInfo *mi; - - mi = (CamelIMAPPStoreInfo *)camel_imapp_store_summary_parent->store_info_load(s, in); - if (mi) { - if (camel_file_util_decode_string(in, &mi->full_name) == -1) { - camel_store_summary_info_free(s, (CamelStoreInfo *)mi); - mi = NULL; - } - } - - return (CamelStoreInfo *)mi; -} - -static int -store_info_save(CamelStoreSummary *s, FILE *out, CamelStoreInfo *mi) -{ - CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi; - - if (camel_imapp_store_summary_parent->store_info_save(s, out, mi) == -1 - || camel_file_util_encode_string(out, isi->full_name) == -1) - return -1; - - return 0; -} - -static void -store_info_free(CamelStoreSummary *s, CamelStoreInfo *mi) -{ - CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi; - - g_free(isi->full_name); - camel_imapp_store_summary_parent->store_info_free(s, mi); -} - -static const char * -store_info_string(CamelStoreSummary *s, const CamelStoreInfo *mi, int type) -{ - CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi; - - /* FIXME: Locks? */ - - g_assert (mi != NULL); - - switch (type) { - case CAMEL_IMAPP_STORE_INFO_FULL_NAME: - return isi->full_name; - default: - return camel_imapp_store_summary_parent->store_info_string(s, mi, type); - } -} - -static void -store_info_set_string(CamelStoreSummary *s, CamelStoreInfo *mi, int type, const char *str) -{ - CamelIMAPPStoreInfo *isi = (CamelIMAPPStoreInfo *)mi; - - g_assert(mi != NULL); - - switch(type) { - case CAMEL_IMAPP_STORE_INFO_FULL_NAME: - d(printf("Set full name %s -> %s\n", isi->full_name, str)); - CAMEL_STORE_SUMMARY_LOCK(s, summary_lock); - g_free(isi->full_name); - isi->full_name = g_strdup(str); - CAMEL_STORE_SUMMARY_UNLOCK(s, summary_lock); - break; - default: - camel_imapp_store_summary_parent->store_info_set_string(s, mi, type, str); - break; - } -} diff --git a/camel/providers/imapp/camel-imapp-store-summary.h b/camel/providers/imapp/camel-imapp-store-summary.h deleted file mode 100644 index 154fe8798e..0000000000 --- a/camel/providers/imapp/camel-imapp-store-summary.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2002 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef _CAMEL_IMAPP_STORE_SUMMARY_H -#define _CAMEL_IMAPP_STORE_SUMMARY_H - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#include <camel/camel-object.h> -#include <camel/camel-store-summary.h> - -#define CAMEL_IMAPP_STORE_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imapp_store_summary_get_type (), CamelIMAPPStoreSummary) -#define CAMEL_IMAPP_STORE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_store_summary_get_type (), CamelIMAPPStoreSummaryClass) -#define CAMEL_IS_IMAP_STORE_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_store_summary_get_type ()) - -typedef struct _CamelIMAPPStoreSummary CamelIMAPPStoreSummary; -typedef struct _CamelIMAPPStoreSummaryClass CamelIMAPPStoreSummaryClass; - -typedef struct _CamelIMAPPStoreInfo CamelIMAPPStoreInfo; - -enum { - CAMEL_IMAPP_STORE_INFO_FULL_NAME = CAMEL_STORE_INFO_LAST, - CAMEL_IMAPP_STORE_INFO_LAST, -}; - -struct _CamelIMAPPStoreInfo { - CamelStoreInfo info; - char *full_name; -}; - -typedef struct _CamelIMAPPStoreNamespace CamelIMAPPStoreNamespace; - -struct _CamelIMAPPStoreNamespace { - char *path; /* display path */ - char *full_name; /* real name */ - char sep; /* directory separator */ -}; - -struct _CamelIMAPPStoreSummary { - CamelStoreSummary summary; - - struct _CamelIMAPPStoreSummaryPrivate *priv; - - /* header info */ - guint32 version; /* version of base part of file */ - guint32 capabilities; - CamelIMAPPStoreNamespace *namespace; /* eventually to be a list */ -}; - -struct _CamelIMAPPStoreSummaryClass { - CamelStoreSummaryClass summary_class; -}; - -CamelType camel_imapp_store_summary_get_type (void); -CamelIMAPPStoreSummary *camel_imapp_store_summary_new (void); - -/* TODO: this api needs some more work, needs to support lists */ -CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_new(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep); -void camel_imapp_store_summary_namespace_set(CamelIMAPPStoreSummary *s, CamelIMAPPStoreNamespace *ns); -CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_find_path(CamelIMAPPStoreSummary *s, const char *path); -CamelIMAPPStoreNamespace *camel_imapp_store_summary_namespace_find_full(CamelIMAPPStoreSummary *s, const char *full_name); - -/* converts to/from utf8 canonical nasmes */ -char *camel_imapp_store_summary_full_to_path(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep); -char *camel_imapp_store_summary_path_to_full(CamelIMAPPStoreSummary *s, const char *path, char dir_sep); - -CamelIMAPPStoreInfo *camel_imapp_store_summary_full_name(CamelIMAPPStoreSummary *s, const char *full_name); -CamelIMAPPStoreInfo *camel_imapp_store_summary_add_from_full(CamelIMAPPStoreSummary *s, const char *full_name, char dir_sep); - -/* a convenience lookup function. always use this if path known */ -char *camel_imapp_store_summary_full_from_path(CamelIMAPPStoreSummary *s, const char *path); - -/* helper macro's */ -#define camel_imapp_store_info_full_name(s, i) (camel_store_info_string((CamelStoreSummary *)s, (const CamelStoreInfo *)i, CAMEL_IMAPP_STORE_INFO_FULL_NAME)) - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ! _CAMEL_IMAPP_STORE_SUMMARY_H */ diff --git a/camel/providers/imapp/camel-imapp-store.c b/camel/providers/imapp/camel-imapp-store.c deleted file mode 100644 index 9123102a03..0000000000 --- a/camel/providers/imapp/camel-imapp-store.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-store.c : class for a imap store */ - -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2000-2002 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include "camel/camel-operation.h" - -#include "camel/camel-stream-buffer.h" -#include "camel/camel-session.h" -#include "camel/camel-exception.h" -#include "camel/camel-url.h" -#include "camel/camel-sasl.h" -#include "camel/camel-data-cache.h" -#include "camel/camel-tcp-stream.h" -#include "camel/camel-tcp-stream-raw.h" -#ifdef HAVE_SSL -#include "camel/camel-tcp-stream-ssl.h" -#endif - -#include "camel-imapp-store-summary.h" -#include "camel-imapp-store.h" -#include "camel-imapp-folder.h" -#include "camel-imapp-engine.h" -#include "camel-imapp-exception.h" -#include "camel-imapp-utils.h" -#include "camel-imapp-driver.h" - -/* Specified in RFC 2060 section 2.1 */ -#define IMAP_PORT 143 - -static CamelStoreClass *parent_class = NULL; - -static void finalize (CamelObject *object); - -static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex); -/* static char *imap_get_name(CamelService *service, gboolean brief);*/ -static gboolean imap_connect (CamelService *service, CamelException *ex); -static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex); -static GList *imap_query_auth_types (CamelService *service, CamelException *ex); - -static void imap_init_trash (CamelStore *store); -static CamelFolder *imap_get_trash (CamelStore *store, CamelException *ex); - -static CamelFolder *imap_get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); -static CamelFolder *imap_get_inbox (CamelStore *store, CamelException *ex); -static void imap_rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static CamelFolderInfo *imap_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex); -static void imap_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); -static void imap_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); -static CamelFolderInfo *imap_create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex); - -static int store_resp_list(CamelIMAPPEngine *ie, guint32 id, void *data); - -/* yet to see if this should go global or not */ -void camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *folder, CamelIMAPPSelectResponse *select); - -static void -camel_imapp_store_class_init (CamelIMAPPStoreClass *camel_imapp_store_class) -{ - CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS(camel_imapp_store_class); - CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS(camel_imapp_store_class); - - parent_class = CAMEL_STORE_CLASS(camel_type_get_global_classfuncs(camel_store_get_type())); - - /* virtual method overload */ - camel_service_class->construct = imap_construct; - /*camel_service_class->get_name = imap_get_name;*/ - camel_service_class->query_auth_types = imap_query_auth_types; - camel_service_class->connect = imap_connect; - camel_service_class->disconnect = imap_disconnect; - - camel_store_class->init_trash = imap_init_trash; - camel_store_class->get_trash = imap_get_trash; - - camel_store_class->get_folder = imap_get_folder; - camel_store_class->get_inbox = imap_get_inbox; - - camel_store_class->create_folder = imap_create_folder; - camel_store_class->rename_folder = imap_rename_folder; - camel_store_class->delete_folder = imap_delete_folder; - camel_store_class->get_folder_info = imap_get_folder_info; -} - -static void -camel_imapp_store_init (gpointer object, gpointer klass) -{ - CamelIMAPPStore *istore = object; -} - -CamelType -camel_imapp_store_get_type (void) -{ - static CamelType camel_imapp_store_type = CAMEL_INVALID_TYPE; - - if (!camel_imapp_store_type) { - camel_imapp_store_type = camel_type_register(CAMEL_STORE_TYPE, - "CamelIMAPPStore", - sizeof (CamelIMAPPStore), - sizeof (CamelIMAPPStoreClass), - (CamelObjectClassInitFunc) camel_imapp_store_class_init, - NULL, - (CamelObjectInitFunc) camel_imapp_store_init, - finalize); - } - - return camel_imapp_store_type; -} - -static void -finalize (CamelObject *object) -{ - CamelIMAPPStore *imap_store = CAMEL_IMAPP_STORE (object); - - /* force disconnect so we dont have it run later, after we've cleaned up some stuff */ - /* SIGH */ - - camel_service_disconnect((CamelService *)imap_store, TRUE, NULL); - - if (imap_store->driver) - camel_object_unref(imap_store->driver); - if (imap_store->cache) - camel_object_unref(imap_store->cache); -} - -static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex) -{ - char *root, *summary; - CamelIMAPPStore *store = (CamelIMAPPStore *)service; - - CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex); - if (camel_exception_is_set(ex)) - return; - - CAMEL_TRY { - store->summary = camel_imapp_store_summary_new(); - root = camel_session_get_storage_path(service->session, service, ex); - if (root) { - summary = g_build_filename(root, ".ev-store-summary", NULL); - camel_store_summary_set_filename((CamelStoreSummary *)store->summary, summary); - /* FIXME: need to remove params, passwords, etc */ - camel_store_summary_set_uri_base((CamelStoreSummary *)store->summary, service->url); - camel_store_summary_load((CamelStoreSummary *)store->summary); - } - } CAMEL_CATCH(e) { - camel_exception_xfer(ex, e); - } CAMEL_DONE; -} - -enum { - 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 void -connect_to_server (CamelService *service, int ssl_mode, int try_starttls) -/* throws IO exception */ -{ - CamelIMAPPStore *store = CAMEL_IMAPP_STORE (service); - CamelStream * volatile tcp_stream = NULL; - CamelIMAPPStream * volatile imap_stream = NULL; - struct hostent *h = NULL; - int ret, port; - CamelException *ex; - - ex = camel_exception_new(); - CAMEL_TRY { - /* parent class connect initialization */ - CAMEL_SERVICE_CLASS (parent_class)->connect (service, ex); - if (ex->id) - camel_exception_throw_ex(ex); - - h = camel_service_gethost(service, ex); - if (ex->id) - camel_exception_throw_ex(ex); - - port = service->url->port ? service->url->port : IMAP_PORT; - -#ifdef HAVE_SSL - if (camel_url_get_param (service->url, "use_ssl")) { - if (try_starttls) - tcp_stream = camel_tcp_stream_ssl_new_raw (service->session, service->url->host, STARTTLS_FLAGS); - else { - port = service->url->port ? service->url->port : 995; - tcp_stream = camel_tcp_stream_ssl_new (service->session, service->url->host, SSL_PORT_FLAGS); - } - } else { - tcp_stream = camel_tcp_stream_raw_new (); - } -#else - tcp_stream = camel_tcp_stream_raw_new (); -#endif /* HAVE_SSL */ - - ret = camel_tcp_stream_connect (CAMEL_TCP_STREAM (tcp_stream), h, port); - camel_free_host (h); - if (ret == -1) { - if (errno == EINTR) - camel_exception_throw(CAMEL_EXCEPTION_USER_CANCEL, _("Connection cancelled")); - else - camel_exception_throw(CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Could not connect to %s (port %d): %s"), - service->url->host, port, strerror(errno)); - } - - imap_stream = (CamelIMAPPStream *)camel_imapp_stream_new(tcp_stream); - store->driver = camel_imapp_driver_new(imap_stream); - - camel_object_unref(imap_stream); - camel_object_unref(tcp_stream); - } CAMEL_CATCH(e) { - if (tcp_stream) - camel_object_unref(tcp_stream); - if (imap_stream) - camel_object_unref((CamelObject *)imap_stream); - camel_exception_throw_ex(e); - } CAMEL_DONE; - - camel_exception_free(ex); -} - -#if 0 - -/* leave this stuff out for now */ - - -static struct { - char *value; - int mode; -} ssl_options[] = { - { "", 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) -{ -#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, use_ssl)) - break; - 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 { - /* User doesn't care about SSL */ - return connect_to_server (service, ssl_mode, FALSE, ex); - } -#else - return connect_to_server (service, USE_SSL_NEVER, FALSE, ex); -#endif -} -#endif - -extern CamelServiceAuthType camel_imapp_password_authtype; -extern CamelServiceAuthType camel_imapp_apop_authtype; - -static GList * -imap_query_auth_types (CamelService *service, CamelException *ex) -{ - /*CamelIMAPPStore *store = CAMEL_IMAPP_STORE (service);*/ - GList *types = NULL; - - types = CAMEL_SERVICE_CLASS (parent_class)->query_auth_types (service, ex); - if (types == NULL) - return NULL; - -#if 0 - if (connect_to_server_wrapper (service, NULL)) { - types = g_list_concat(types, g_list_copy(store->engine->auth)); - imap_disconnect (service, TRUE, NULL); - } else { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, - _("Could not connect to POP server on %s"), - service->url->host); - } -#endif - return types; -} - -static void -store_get_pass(CamelIMAPPStore *store) -{ - if (((CamelService *)store)->url->passwd == NULL) { - char *prompt; - CamelException ex; - - camel_exception_init(&ex); - - prompt = g_strdup_printf (_("%sPlease enter the IMAP password for %s@%s"), - store->login_error?store->login_error:"", - ((CamelService *)store)->url->user, - ((CamelService *)store)->url->host); - ((CamelService *)store)->url->passwd = camel_session_get_password(camel_service_get_session((CamelService *)store), - prompt, FALSE, TRUE, (CamelService*)store, "password", &ex); - g_free (prompt); - if (camel_exception_is_set(&ex)) - camel_exception_throw_ex(&ex); - } -} - -static struct _CamelSasl * -store_get_sasl(struct _CamelIMAPPDriver *driver, CamelIMAPPStore *store) -{ - store_get_pass(store); - - if (((CamelService *)store)->url->authmech) - return camel_sasl_new("imap", ((CamelService *)store)->url->authmech, (CamelService *)store); - - return NULL; -} - -static void -store_get_login(struct _CamelIMAPPDriver *driver, char **login, char **pass, CamelIMAPPStore *store) -{ - store_get_pass(store); - - *login = g_strdup(((CamelService *)store)->url->user); - *pass = g_strdup(((CamelService *)store)->url->passwd); -} - -static gboolean -imap_connect (CamelService *service, CamelException *ex) -{ - CamelIMAPPStore *store = (CamelIMAPPStore *)service; - volatile int ret = FALSE; - - CAMEL_TRY { - volatile int retry = TRUE; - - if (store->cache == NULL) { - char *root; - - root = camel_session_get_storage_path(service->session, service, ex); - if (root) { - store->cache = camel_data_cache_new(root, 0, ex); - g_free(root); - if (store->cache) { - /* Default cache expiry - 1 week or not visited in a day */ - camel_data_cache_set_expire_age(store->cache, 60*60*24*7); - camel_data_cache_set_expire_access(store->cache, 60*60*24); - } - } - if (camel_exception_is_set(ex)) - camel_exception_throw_ex(ex); - } - - connect_to_server(service, USE_SSL_NEVER, FALSE); - - camel_imapp_driver_set_sasl_factory(store->driver, (CamelIMAPPSASLFunc)store_get_sasl, store); - camel_imapp_driver_set_login_query(store->driver, (CamelIMAPPLoginFunc)store_get_login, store); - store->login_error = NULL; - - do { - CAMEL_TRY { - if (store->driver->engine->state != IMAP_ENGINE_AUTH) - camel_imapp_driver_login(store->driver); - ret = TRUE; - retry = FALSE; - } CAMEL_CATCH(e) { - g_free(store->login_error); - store->login_error = NULL; - switch (e->id) { - case CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE: - store->login_error = g_strdup_printf("%s\n\n", e->desc); - camel_session_forget_password(service->session, service, "password", ex); - camel_url_set_passwd(service->url, NULL); - break; - default: - camel_exception_throw_ex(e); - break; - } - } CAMEL_DONE; - } while (retry); - } CAMEL_CATCH(e) { - camel_exception_xfer(ex, e); - camel_service_disconnect(service, TRUE, NULL); - ret = FALSE; - } CAMEL_DONE; - - g_free(store->login_error); - store->login_error = NULL; - - return ret; -} - -static gboolean -imap_disconnect (CamelService *service, gboolean clean, CamelException *ex) -{ - CamelIMAPPStore *store = CAMEL_IMAPP_STORE (service); - - /* FIXME: logout */ - - if (!CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex)) - return FALSE; - - /* logout/disconnect */ - if (store->driver) { - camel_object_unref(store->driver); - store->driver = NULL; - } - - return TRUE; -} - -static void -imap_init_trash (CamelStore *store) -{ - /* no-op */ - ; -} - -static CamelFolder * -imap_get_trash (CamelStore *store, CamelException *ex) -{ - /* no-op */ - return NULL; -} - -static CamelFolder * -imap_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) -{ - CamelIMAPPStore *istore = (CamelIMAPPStore *)store; - CamelIMAPPFolder * volatile folder = NULL; - - /* ??? */ - - /* 1. create the folder */ - /* 2. run select? */ - /* 3. update the folder */ - - CAMEL_TRY { - folder = (CamelIMAPPFolder *)camel_imapp_folder_new(store, folder_name); - camel_imapp_driver_select(istore->driver, folder); - } CAMEL_CATCH (e) { - if (folder) { - camel_object_unref(folder); - folder = NULL; - } - camel_exception_xfer(ex, e); - } CAMEL_DONE; - - return (CamelFolder *)folder; -} - -static CamelFolder * -imap_get_inbox(CamelStore *store, CamelException *ex) -{ - camel_exception_setv(ex, 1, "get_inbox::unimplemented"); - - return NULL; -} - -/* 8 bit, string compare */ -static int folders_build_cmp(const void *app, const void *bpp) -{ - struct _list_info *a = *((struct _list_info **)app); - struct _list_info *b = *((struct _list_info **)bpp); - unsigned char *ap = (unsigned char *)(a->name); - unsigned char *bp = (unsigned char *)(b->name); - - printf("qsort, cmp '%s' <> '%s'\n", ap, bp); - - while (*ap && *ap == *bp) { - ap++; - bp++; - } - - if (*ap < *bp) - return -1; - else if (*ap > *bp) - return 1; - return 0; -} - -/* FIXME: this should go via storesummary? */ -static CamelFolderInfo * -folders_build_info(CamelURL *base, struct _list_info *li) -{ - char *path, *full_name, *name; - CamelFolderInfo *fi; - - full_name = imapp_list_get_path(li); - name = strrchr(full_name, '/'); - if (name) - name++; - else - name = full_name; - - path = alloca(strlen(full_name)+2); - sprintf(path, "/%s", full_name); - camel_url_set_path(base, path); - - fi = g_malloc0(sizeof(*fi)); - fi->url = camel_url_to_string(base, CAMEL_URL_HIDE_ALL); - fi->name = g_strdup(name); - fi->full_name = full_name; - fi->path = g_strdup(path); - fi->unread_message_count = -1; - fi->flags = li->flags; - - /* TODO: could look up count here ... */ - /* ?? */ - /*folder = camel_object_bag_get(store->folders, "INBOX");*/ - - return fi; -} - -/* - a - a/b - a/b/c - a/d - b - c/d - -*/ - -/* note, pname is the raw name, not the folderinfo name */ -/* note also this free's as we go, since we never go 'backwards' */ -static CamelFolderInfo * -folders_build_rec(CamelURL *base, GPtrArray *folders, int *ip, CamelFolderInfo *pfi, char *pname) -{ - int plen = 0; - CamelFolderInfo *last = NULL, *first = NULL; - - if (pfi) - plen = strlen(pname); - - for(;(*ip)<(int)folders->len;) { - CamelFolderInfo *fi; - struct _list_info *li; - - li = folders->pdata[*ip]; - printf("checking '%s' is child of '%s'\n", li->name, pname); - - /* is this a child of the parent? */ - if (pfi != NULL - && (strncmp(pname, li->name, strlen(pname)) != 0 - || li->name[plen] != li->separator)) { - printf(" nope\n"); - break; - } - printf(" yep\n"); - - /* is this not an immediate child of the parent? */ -#if 0 - char *p; - if (pfi != NULL - && li->separator != 0 - && (p = strchr(li->name + plen + 1, li->separator)) != NULL) { - if (last == NULL) { - struct _list_info tli; - - tli.flags = CAMEL_FOLDER_NOSELECT|CAMEL_FOLDER_CHILDREN; - tli.separator = li->separator; - tli.name = g_strndup(li->name, p-li->name+1); - fi = folders_build_info(base, &tli); - fi->parent = pfi; - if (pfi && pfi->child == NULL) - pfi->child = fi; - i = folders_build_rec(folders, i, fi, tli.name); - break; - } - } -#endif - - fi = folders_build_info(base, li); - fi->parent = pfi; - if (last != NULL) - last->sibling = fi; - last = fi; - if (first == NULL) - first = fi; - - (*ip)++; - fi->child = folders_build_rec(base, folders, ip, fi, li->name); - imap_free_list(li); - } - - return first; -} - -static void -folder_info_dump(CamelFolderInfo *fi, int depth) -{ - char *s; - - s = alloca(depth+1); - memset(s, ' ', depth); - s[depth] = 0; - while (fi) { - printf("%s%s (%s)\n", s, fi->name, fi->url); - if (fi->child) - folder_info_dump(fi->child, depth+2); - fi = fi->sibling; - } - -} - -static CamelFolderInfo * -imap_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex) -{ - CamelIMAPPStore *istore = (CamelIMAPPStore *)store; - CamelFolderInfo * fi= NULL; - char *name; - - /* FIXME: temporary, since this is not a disco store */ - if (istore->driver == NULL - && !camel_service_connect((CamelService *)store, ex)) - return NULL; - - name = (char *)top; - if (name == NULL || name[0] == 0) { - /* namespace? */ - name = ""; - } - - name = ""; - - CAMEL_TRY { - CamelURL *base; - int i; - GPtrArray *folders; - - /* FIXME: subscriptions? lsub? */ - folders = camel_imapp_driver_list(istore->driver, name, flags); - - /* this greatly simplifies the tree algorithm ... but it might - be faster just to use a hashtable to find parents? */ - qsort(folders->pdata, folders->len, sizeof(folders->pdata[0]), folders_build_cmp); - - i = 0; - base = camel_url_copy(((CamelService *)store)->url); - fi = folders_build_rec(base, folders, &i, NULL, NULL); - camel_url_free(base); - g_ptr_array_free(folders, TRUE); - } CAMEL_CATCH(e) { - camel_exception_xfer(ex, e); - } CAMEL_DONE; - - printf("built folder info:\n"); - folder_info_dump(fi, 2); - - return fi; - -#if 0 - if (top == NULL || !g_ascii_strcasecmp(top, "inbox")) { - CamelURL *uri = camel_url_copy(((CamelService *)store)->url); - - camel_url_set_path(uri, "/INBOX"); - fi = g_malloc0(sizeof(*fi)); - fi->url = camel_url_to_string(uri, CAMEL_URL_HIDE_ALL); - camel_url_free(uri); - fi->name = g_strdup("INBOX"); - fi->full_name = g_strdup("INBOX"); - fi->path = g_strdup("/INBOX"); - fi->unread_message_count = -1; - fi->flags = 0; - - folder = camel_object_bag_get(store->folders, "INBOX"); - if (folder) { - /*if (!cflags & FAST)*/ - camel_imapp_driver_update(istore->driver, (CamelIMAPPFolder *)folder); - fi->unread_message_count = camel_folder_get_unread_message_count(folder); - camel_object_unref(folder); - } - } else { - camel_exception_setv(ex, 1, "not implemented"); - } -#endif - return fi; - -#if 0 - istore->pending_list = g_ptr_array_new(); - - CAMEL_TRY { - ic = camel_imapp_engine_command_new(istore->driver->engine, "LIST", NULL, "LIST \"\" %f", top); - camel_imapp_engine_command_queue(istore->driver->engine, ic); - while (camel_imapp_engine_iterate(istore->driver->engine, ic) > 0) - ; - - if (ic->status->result != IMAP_OK) - camel_exception_throw(1, "list failed: %s", ic->status->text); - } CAMEL_CATCH (e) { - camel_exception_xfer(ex, e); - } CAMEL_DONE; - - camel_imapp_engine_command_free(istore->driver->engine, ic); - - printf("got folder list:\n"); - for (i=0;i<(int)istore->pending_list->len;i++) { - struct _list_info *linfo = istore->pending_list->pdata[i]; - - printf("%s (%c)\n", linfo->name, linfo->separator); - imap_free_list(linfo); - } - istore->pending_list = NULL; - - return NULL; -#endif -} - -static void -imap_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex) -{ - camel_exception_setv(ex, 1, "delete_folder::unimplemented"); -} - -static void -imap_rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex) -{ - camel_exception_setv(ex, 1, "rename_folder::unimplemented"); -} - -static CamelFolderInfo * -imap_create_folder(CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex) -{ - camel_exception_setv(ex, 1, "create_folder::unimplemented"); - return NULL; -} - -/* ********************************************************************** */ -#if 0 -static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data) -{ - struct _fetch_info *finfo; - CamelIMAPPStore *istore = data; - CamelMessageInfo *info; - struct _pending_fetch *pending; - - finfo = imap_parse_fetch(ie->stream); - if (istore->selected) { - if ((finfo->got & FETCH_UID) == 0) { - printf("didn't get uid in fetch response?\n"); - } else { - info = camel_folder_summary_index(((CamelFolder *)istore->selected)->summary, id-1); - /* exists, check/update */ - if (info) { - 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_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); - info = camel_folder_summary_uid(((CamelFolder *)istore->selected)->summary, finfo->uid); - } - } - - if (info) { - if (finfo->got & (FETCH_FLAGS)) { - printf("updating flags for uid '%s'\n", finfo->uid); - info->flags = finfo->flags; - camel_folder_change_info_change_uid(istore->selected->changes, finfo->uid); - } - if (finfo->got & FETCH_MINFO) { - printf("got envelope unexpectedly?\n"); - } - /* other things go here, like body fetches */ - } else { - pending = g_hash_table_lookup(istore->pending_fetch_table, finfo->uid); - - /* we need to create a new info, we only care about flags and minfo */ - - if (pending) - info = pending->info; - else { - info = camel_folder_summary_info_new(((CamelFolder *)istore->selected)->summary); - camel_message_info_set_uid(info, g_strdup(finfo->uid)); - } - - if (finfo->got & FETCH_FLAGS) - info->flags = finfo->flags; - - if (finfo->got & FETCH_MINFO) { - /* if we only use ENVELOPE? */ - camel_message_info_set_subject(info, g_strdup(camel_message_info_subject(finfo->minfo))); - camel_message_info_set_from(info, g_strdup(camel_message_info_from(finfo->minfo))); - camel_message_info_set_to(info, g_strdup(camel_message_info_to(finfo->minfo))); - camel_message_info_set_cc(info, g_strdup(camel_message_info_cc(finfo->minfo))); - info->date_sent = finfo->minfo->date_sent; - camel_folder_summary_add(((CamelFolder *)istore->selected)->summary, info); - camel_folder_change_info_add_uid(istore->selected->changes, finfo->uid); - if (pending) { - e_dlist_remove((EDListNode *)pending); - g_hash_table_remove(istore->pending_fetch_table, finfo->uid); - /*e_memchunk_free(istore->pending_fetch_chunks, pending);*/ - } - } else if (finfo->got & FETCH_HEADER) { - /* if we only use HEADER? */ - CamelMimeParser *mp; - - if (pending == NULL) - 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); - camel_object_unref(mp); - camel_message_info_set_uid(info, g_strdup(finfo->uid)); - - camel_folder_summary_add(((CamelFolder *)istore->selected)->summary, info); - camel_folder_change_info_add_uid(istore->selected->changes, finfo->uid); - if (pending) { - /* FIXME: use a dlist */ - e_dlist_remove((EDListNode *)pending); - g_hash_table_remove(istore->pending_fetch_table, camel_message_info_uid(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) { - if (pending == NULL) { - pending = e_memchunk_alloc(istore->pending_fetch_chunks); - pending->info = info; - g_hash_table_insert(istore->pending_fetch_table, (char *)camel_message_info_uid(info), pending); - e_dlist_addtail(&istore->pending_fetch_list, (EDListNode *)pending); - } - } else { - if (pending == NULL) - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); - printf("got unexpected fetch response?\n"); - imap_dump_fetch(finfo); - } - } - } - } else { - printf("unexpected fetch response, no folder selected?\n"); - } - /*imap_dump_fetch(finfo);*/ - imap_free_fetch(finfo); - - return camel_imapp_engine_skip(ie); -} -#endif - -/* ********************************************************************** */ - -/* should be moved to imapp-utils? - stuff in imapp-utils should be moved to imapp-parse? */ - -/* ********************************************************************** */ - -#if 0 -void -camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *folder, CamelIMAPPSelectResponse *select) -{ - CamelIMAPPCommand * volatile ic = NULL; - CamelIMAPPStore *istore = (CamelIMAPPStore *)store; - int i; - struct _uidset_state ss; - GPtrArray *fetch; - CamelMessageInfo *info; - struct _pending_fetch *fw, *fn; - - printf("imap folder selected\n"); - - if (select->uidvalidity == folder->uidvalidity - && select->exists == folder->exists - && select->recent == folder->recent - && select->unseen == folder->unseen) { - /* no work to do? */ - return; - } - - istore->pending_fetch_table = g_hash_table_new(g_str_hash, g_str_equal); - istore->pending_fetch_chunks = e_memchunk_new(256, sizeof(struct _pending_fetch)); - - /* perform an update - flags first (and see what we have) */ - CAMEL_TRY { - ic = camel_imapp_engine_command_new(istore->engine, "FETCH", NULL, "FETCH 1:%d (UID FLAGS)", select->exists); - camel_imapp_engine_command_queue(istore->engine, ic); - while (camel_imapp_engine_iterate(istore->engine, ic) > 0) - ; - - if (ic->status->result != IMAP_OK) - camel_exception_throw(1, "fetch failed: %s", ic->status->text); - - /* pending_fetch_list now contains any new messages */ - /* FIXME: how do we work out no-longer present messages? */ - printf("now fetching info for messages?\n"); - uidset_init(&ss, store->engine); - ic = camel_imapp_engine_command_new(istore->engine, "FETCH", NULL, "UID FETCH "); - fw = (struct _pending_fetch *)istore->pending_fetch_list.head; - fn = fw->next; - while (fn) { - info = fw->info; - /* if the uid set fills, then flush the command out */ - if (uidset_add(&ss, ic, camel_message_info_uid(info)) - || (fn->next == NULL && uidset_done(&ss, ic))) { - camel_imapp_engine_command_add(istore->engine, ic, " (FLAGS RFC822.HEADER)"); - camel_imapp_engine_command_queue(istore->engine, ic); - while (camel_imapp_engine_iterate(istore->engine, ic) > 0) - ; - if (ic->status->result != IMAP_OK) - camel_exception_throw(1, "fetch failed: %s", ic->status->text); - /* if not end ... */ - camel_imapp_engine_command_free(istore->engine, ic); - ic = camel_imapp_engine_command_new(istore->engine, "FETCH", NULL, "UID FETCH "); - } - fw = fn; - fn = fn->next; - } - - printf("The pending list should now be empty: %s\n", e_dlist_empty(&istore->pending_fetch_list)?"TRUE":"FALSE"); - for (i=0;i<10;i++) { - info = camel_folder_summary_index(((CamelFolder *)istore->selected)->summary, i); - if (info) { - printf("message info [%d] =\n", i); - camel_message_info_dump(info); - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); - } - } - } CAMEL_CATCH (e) { - /* FIXME: cleanup */ - camel_exception_throw_ex(e); - } CAMEL_DONE; - - g_hash_table_destroy(istore->pending_fetch_table); - istore->pending_fetch_table = NULL; - e_memchunk_destroy(istore->pending_fetch_chunks); - - camel_imapp_engine_command_free(istore->engine, ic); -} -#endif - -#if 0 -/*char *uids[] = {"1", "2", "4", "5", "6", "7", "9", "11", "12", 0};*/ -/*char *uids[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", 0};*/ -char *uids[] = {"1", "3", "5", "7", "9", "11", "12", "13", "14", "15", "20", "21", "24", "25", "26", 0}; - -void -uidset_test(CamelIMAPPEngine *ie) -{ - struct _uidset_state ss; - CamelIMAPPCommand *ic; - int i; - - /*ic = camel_imapp_engine_command_new(ie, 0, "FETCH", NULL, "FETCH ");*/ - uidset_init(&ss, 0, 0); - for (i=0;uids[i];i++) { - if (uidset_add(&ss, uids[i])) { - printf("\n[%d] flushing uids\n", i); - } - } - - if (uidset_done(&ss)) { - printf("\nflushing uids\n"); - } -} -#endif diff --git a/camel/providers/imapp/camel-imapp-store.h b/camel/providers/imapp/camel-imapp-store.h deleted file mode 100644 index 97b7afd1d1..0000000000 --- a/camel/providers/imapp/camel-imapp-store.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-imap-store.h : class for an imap store */ - -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 2002 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -#ifndef CAMEL_IMAPP_STORE_H -#define CAMEL_IMAPP_STORE_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -#include <camel/camel-types.h> -#include <camel/camel-store.h> -#include "camel-imapp-driver.h" -#include "e-util/e-memory.h" - -#define CAMEL_IMAPP_STORE_TYPE (camel_imapp_store_get_type ()) -#define CAMEL_IMAPP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPP_STORE_TYPE, CamelIMAPPStore)) -#define CAMEL_IMAPP_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_IMAPP_STORE_TYPE, CamelIMAPPStoreClass)) -#define CAMEL_IS_IMAP_STORE(o) (CAMEL_CHECK_TYPE((o), CAMEL_IMAPP_STORE_TYPE)) - -struct _pending_fetch { - struct _pending_fetch *next; - struct _pending_fetch *prev; - - CamelMessageInfo *info; -}; - -typedef struct { - CamelStore parent_object; - - struct _CamelIMAPPStoreSummary *summary; /* in-memory list of folders */ - struct _CamelIMAPPDriver *driver; /* IMAP processing engine */ - struct _CamelDataCache *cache; - - /* if we had a login error, what to show to user */ - char *login_error; - - GPtrArray *pending_list; -} CamelIMAPPStore; - -typedef struct { - CamelStoreClass parent_class; - -} CamelIMAPPStoreClass; - -/* Standard Camel function */ -CamelType camel_imapp_store_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CAMEL_IMAPP_STORE_H */ - - diff --git a/camel/providers/imapp/camel-imapp-stream.c b/camel/providers/imapp/camel-imapp-stream.c deleted file mode 100644 index 20876beae2..0000000000 --- a/camel/providers/imapp/camel-imapp-stream.c +++ /dev/null @@ -1,761 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*- - * - * Author: - * Michael Zucchi <notzed@ximian.com> - * - * Copyright 1999, 2000 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> - -#include <glib.h> - -#include <camel/camel-stream-mem.h> - -#include "camel-imapp-stream.h" -#include "camel-imapp-exception.h" - -#define t(x) -#define io(x) x - -static void setup_table(void); - -static CamelObjectClass *parent_class = NULL; - -/* Returns the class for a CamelStream */ -#define CS_CLASS(so) CAMEL_IMAPP_STREAM_CLASS(CAMEL_OBJECT_GET_CLASS(so)) - -#define CAMEL_IMAPP_STREAM_SIZE (4096) -#define CAMEL_IMAPP_STREAM_TOKEN (4096) /* maximum token size */ - -static int -stream_fill(CamelIMAPPStream *is) -{ - int left = 0; - - if (is->source) { - left = is->end - is->ptr; - memcpy(is->buf, is->ptr, left); - is->end = is->buf + left; - is->ptr = is->buf; - left = camel_stream_read(is->source, is->end, CAMEL_IMAPP_STREAM_SIZE - (is->end - is->buf)); - if (left > 0) { - is->end += left; - io(printf("camel_imapp_read: buffer is '%.*s'\n", is->end - is->ptr, is->ptr)); - return is->end - is->ptr; - } else { - io(printf("camel_imapp_read: -1\n")); - return -1; - } - } - - printf("camel_imapp_read: -1\n"); - - return -1; -} - -static ssize_t -stream_read(CamelStream *stream, char *buffer, size_t n) -{ - CamelIMAPPStream *is = (CamelIMAPPStream *)stream; - ssize_t max; - - if (is->literal == 0 || n == 0) - return 0; - - max = is->end - is->ptr; - if (max > 0) { - max = MIN(max, is->literal); - max = MIN(max, n); - memcpy(buffer, is->ptr, max); - is->ptr += max; - } else { - max = MIN(is->literal, n); - max = camel_stream_read(is->source, buffer, max); - if (max <= 0) - return max; - } - - is->literal -= max; - - return max; -} - -static ssize_t -stream_write(CamelStream *stream, const char *buffer, size_t n) -{ - CamelIMAPPStream *is = (CamelIMAPPStream *)stream; - - return camel_stream_write(is->source, buffer, n); -} - -static int -stream_close(CamelStream *stream) -{ - /* nop? */ - return 0; -} - -static int -stream_flush(CamelStream *stream) -{ - /* nop? */ - return 0; -} - -static gboolean -stream_eos(CamelStream *stream) -{ - CamelIMAPPStream *is = (CamelIMAPPStream *)stream; - - return is->literal == 0; -} - -static int -stream_reset(CamelStream *stream) -{ - /* nop? reset literal mode? */ - return 0; -} - -static void -camel_imapp_stream_class_init (CamelStreamClass *camel_imapp_stream_class) -{ - CamelStreamClass *camel_stream_class = (CamelStreamClass *)camel_imapp_stream_class; - - parent_class = camel_type_get_global_classfuncs( CAMEL_OBJECT_TYPE ); - - /* virtual method definition */ - camel_stream_class->read = stream_read; - camel_stream_class->write = stream_write; - camel_stream_class->close = stream_close; - camel_stream_class->flush = stream_flush; - camel_stream_class->eos = stream_eos; - camel_stream_class->reset = stream_reset; -} - -static void -camel_imapp_stream_init(CamelIMAPPStream *is, CamelIMAPPStreamClass *isclass) -{ - /* +1 is room for appending a 0 if we need to for a token */ - is->ptr = is->end = is->buf = g_malloc(CAMEL_IMAPP_STREAM_SIZE+1); - is->tokenptr = is->tokenbuf = g_malloc(CAMEL_IMAPP_STREAM_SIZE+1); - is->tokenend = is->tokenbuf + CAMEL_IMAPP_STREAM_SIZE; -} - -static void -camel_imapp_stream_finalise(CamelIMAPPStream *is) -{ - g_free(is->buf); - if (is->source) - camel_object_unref((CamelObject *)is->source); -} - -CamelType -camel_imapp_stream_get_type (void) -{ - static CamelType camel_imapp_stream_type = CAMEL_INVALID_TYPE; - - if (camel_imapp_stream_type == CAMEL_INVALID_TYPE) { - setup_table(); - camel_imapp_stream_type = camel_type_register( camel_stream_get_type(), - "CamelIMAPPStream", - sizeof( CamelIMAPPStream ), - sizeof( CamelIMAPPStreamClass ), - (CamelObjectClassInitFunc) camel_imapp_stream_class_init, - NULL, - (CamelObjectInitFunc) camel_imapp_stream_init, - (CamelObjectFinalizeFunc) camel_imapp_stream_finalise ); - } - - return camel_imapp_stream_type; -} - -/** - * camel_imapp_stream_new: - * - * Returns a NULL stream. A null stream is always at eof, and - * always returns success for all reads and writes. - * - * Return value: the stream - **/ -CamelStream * -camel_imapp_stream_new(CamelStream *source) -{ - CamelIMAPPStream *is; - - is = (CamelIMAPPStream *)camel_object_new(camel_imapp_stream_get_type ()); - camel_object_ref((CamelObject *)source); - is->source = source; - - return (CamelStream *)is; -} - - -/* - From rfc2060 - -ATOM_CHAR ::= <any CHAR except atom_specials> - -atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / - quoted_specials - -CHAR ::= <any 7-bit US-ASCII character except NUL, - 0x01 - 0x7f> - -CTL ::= <any ASCII control character and DEL, - 0x00 - 0x1f, 0x7f> - -SPACE ::= <ASCII SP, space, 0x20> - -list_wildcards ::= "%" / "*" - -quoted_specials ::= <"> / "\" -*/ - -static unsigned char imap_specials[256] = { -/* 00 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 10 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 20 */0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, -/* 30 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 40 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 50 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, -/* 60 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 70 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -#define imap_is_atom(c) ((imap_specials[(c)&0xff] & 0x01) != 0) -#define imap_is_simple(c) ((imap_specials[(c)&0xff] & 0x02) != 0) -#define imap_not_id(c) ((imap_specials[(c)&0xff] & 0x04) != 0) - -/* could be pregenerated, but this is cheap */ -static struct { - unsigned char *chars; - unsigned char mask; -} is_masks[] = { - { "\n*()[]+", 2 }, - { " \r\n()[]+", 4 }, -}; - -static void setup_table(void) -{ - int i; - unsigned char *p, c; - - for (i=0;i<(int)(sizeof(is_masks)/sizeof(is_masks[0]));i++) { - p = is_masks[i].chars; - while ((c = *p++)) - imap_specials[c] |= is_masks[i].mask; - } -} - -#if 0 - -static int -skip_ws(CamelIMAPPStream *is, unsigned char *pp, unsigned char *pe) -{ - register unsigned char c, *p; - unsigned char *e; - - p = is->ptr; - e = is->end; - - do { - while (p >= e ) { - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - return IMAP_TOK_ERROR; - p = is->ptr; - e = is->end; - } - c = *p++; - } while (c == ' ' || c == '\r'); - - is->ptr = p; - is->end = e; - - return c; -} -#endif - -/* FIXME: these should probably handle it themselves, - and get rid of the token interface? */ -int -camel_imapp_stream_atom(CamelIMAPPStream *is, unsigned char **data, unsigned int *lenp) -{ - unsigned char *p, c; - - /* this is only 'approximate' atom */ - switch(camel_imapp_stream_token(is, data, lenp)) { - case IMAP_TOK_TOKEN: - p = *data; - while ((c = *p)) - *p++ = toupper(c); - case IMAP_TOK_INT: - return 0; - case IMAP_TOK_ERROR: - return IMAP_TOK_ERROR; - default: - camel_exception_throw(1, "expecting atom"); - printf("expecting atom!\n"); - return IMAP_TOK_PROTOCOL; - } -} - -/* gets an atom, a quoted_string, or a literal */ -int -camel_imapp_stream_astring(CamelIMAPPStream *is, unsigned char **data) -{ - unsigned char *p, *start; - unsigned int len, inlen; - - switch(camel_imapp_stream_token(is, data, &len)) { - case IMAP_TOK_TOKEN: - case IMAP_TOK_INT: - case IMAP_TOK_STRING: - return 0; - case IMAP_TOK_LITERAL: - /* FIXME: just grow buffer */ - if (len >= CAMEL_IMAPP_STREAM_TOKEN) { - camel_exception_throw(1, "astring: literal too long"); - printf("astring too long\n"); - return IMAP_TOK_PROTOCOL; - } - p = is->tokenptr; - camel_imapp_stream_set_literal(is, len); - do { - len = camel_imapp_stream_getl(is, &start, &inlen); - if (len < 0) - return len; - memcpy(p, start, inlen); - p += inlen; - } while (len > 0); - *data = is->tokenptr; - return 0; - case IMAP_TOK_ERROR: - /* wont get unless no exception hanlder*/ - return IMAP_TOK_ERROR; - default: - camel_exception_throw(1, "expecting astring"); - printf("expecting astring!\n"); - return IMAP_TOK_PROTOCOL; - } -} - -/* check for NIL or (small) quoted_string or literal */ -int -camel_imapp_stream_nstring(CamelIMAPPStream *is, unsigned char **data) -{ - unsigned char *p, *start; - unsigned int len, inlen; - - switch(camel_imapp_stream_token(is, data, &len)) { - case IMAP_TOK_STRING: - return 0; - case IMAP_TOK_LITERAL: - /* FIXME: just grow buffer */ - if (len >= CAMEL_IMAPP_STREAM_TOKEN) { - camel_exception_throw(1, "nstring: literal too long"); - return IMAP_TOK_PROTOCOL; - } - p = is->tokenptr; - camel_imapp_stream_set_literal(is, len); - do { - len = camel_imapp_stream_getl(is, &start, &inlen); - if (len < 0) - return len; - memcpy(p, start, inlen); - p += inlen; - } while (len > 0); - *data = is->tokenptr; - return 0; - case IMAP_TOK_TOKEN: - p = *data; - if (toupper(p[0]) == 'N' && toupper(p[1]) == 'I' && toupper(p[2]) == 'L' && p[3] == 0) { - *data = NULL; - return 0; - } - default: - camel_exception_throw(1, "expecting nstring"); - return IMAP_TOK_PROTOCOL; - case IMAP_TOK_ERROR: - /* we'll never get this unless there are no exception handlers anyway */ - return IMAP_TOK_ERROR; - - } -} - -/* parse an nstring as a stream */ -int -camel_imapp_stream_nstring_stream(CamelIMAPPStream *is, CamelStream **stream) -/* throws IO,PARSE exception */ -{ - unsigned char *token; - unsigned int len; - int ret = 0; - CamelStream * volatile mem = NULL; - - *stream = NULL; - - CAMEL_TRY { - switch(camel_imapp_stream_token(is, &token, &len)) { - case IMAP_TOK_STRING: - mem = camel_stream_mem_new_with_buffer(token, len); - *stream = mem; - break; - case IMAP_TOK_LITERAL: - /* if len is big, we could automatically use a file backing */ - camel_imapp_stream_set_literal(is, len); - mem = camel_stream_mem_new(); - if (camel_stream_write_to_stream((CamelStream *)is, mem) == -1) - camel_exception_throw(1, "nstring: io error: %s", strerror(errno)); - camel_stream_reset(mem); - *stream = mem; - break; - case IMAP_TOK_TOKEN: - if (toupper(token[0]) == 'N' && toupper(token[1]) == 'I' && toupper(token[2]) == 'L' && token[3] == 0) { - *stream = NULL; - break; - } - default: - ret = -1; - camel_exception_throw(1, "nstring: token not string"); - } - } CAMEL_CATCH(ex) { - if (mem) - camel_object_unref((CamelObject *)mem); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - /* never reaches here anyway */ - return ret; -} - -guint32 -camel_imapp_stream_number(CamelIMAPPStream *is) -{ - unsigned char *token; - unsigned int len; - - if (camel_imapp_stream_token(is, &token, &len) != IMAP_TOK_INT) { - camel_exception_throw(1, "expecting number"); - return 0; - } - - return strtoul(token, 0, 10); -} - -int -camel_imapp_stream_text(CamelIMAPPStream *is, unsigned char **text) -{ - GByteArray *build = g_byte_array_new(); - unsigned char *token; - unsigned int len; - int tok; - - CAMEL_TRY { - while (is->unget > 0) { - switch (is->unget_tok) { - case IMAP_TOK_TOKEN: - case IMAP_TOK_STRING: - case IMAP_TOK_INT: - g_byte_array_append(build, is->unget_token, is->unget_len); - g_byte_array_append(build, " ", 1); - default: /* invalid, but we'll ignore */ - break; - } - is->unget--; - } - - do { - tok = camel_imapp_stream_gets(is, &token, &len); - if (tok < 0) - camel_exception_throw(1, "io error: %s", strerror(errno)); - if (len) - g_byte_array_append(build, token, len); - } while (tok > 0); - } CAMEL_CATCH(ex) { - *text = NULL; - g_byte_array_free(build, TRUE); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - g_byte_array_append(build, "", 1); - *text = build->data; - g_byte_array_free(build, FALSE); - - return 0; -} - -/* Get one token from the imap stream */ -camel_imapp_token_t -/* throws IO,PARSE exception */ -camel_imapp_stream_token(CamelIMAPPStream *is, unsigned char **data, unsigned int *len) -{ - register unsigned char c, *p, *o, *oe; - unsigned char *e; - unsigned int literal; - int digits; - - if (is->unget > 0) { - is->unget--; - *data = is->unget_token; - *len = is->unget_len; - /*printf("token UNGET '%c' %s\n", is->unget_tok, is->unget_token);*/ - return is->unget_tok; - } - - if (is->literal > 0) - g_warning("stream_token called with literal %d", is->literal); - - p = is->ptr; - e = is->end; - - /* skip whitespace/prefill buffer */ - do { - while (p >= e ) { - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - goto io_error; - p = is->ptr; - e = is->end; - } - c = *p++; - } while (c == ' ' || c == '\r'); - - /*strchr("\n*()[]+", c)*/ - if (imap_is_simple(c)) { - is->ptr = p; - t(printf("token '%c'\n", c)); - return c; - } else if (c == '{') { - literal = 0; - *data = p; - while (1) { - while (p < e) { - c = *p++; - if (isdigit(c) && literal < (UINT_MAX/10)) { - literal = literal * 10 + (c - '0'); - } else if (c == '}') { - while (1) { - while (p < e) { - c = *p++; - if (c == '\n') { - *len = literal; - is->ptr = p; - is->literal = literal; - t(printf("token LITERAL %d\n", literal)); - return IMAP_TOK_LITERAL; - } - } - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - goto io_error; - p = is->ptr; - e = is->end; - } - } else { - if (isdigit(c)) - printf("Protocol error: literal too big\n"); - else - printf("Protocol error: literal contains invalid char %02x '%c'\n", c, isprint(c)?c:c); - goto protocol_error; - } - } - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - goto io_error; - p = is->ptr; - e = is->end; - } - } else if (c == '"') { - o = is->tokenptr; - oe = is->tokenptr + CAMEL_IMAPP_STREAM_TOKEN - 1; - while (1) { - while (p < e) { - c = *p++; - if (c == '\\') { - while (p >= e) { - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - goto io_error; - p = is->ptr; - e = is->end; - } - c = *p++; - } else if (c == '\"') { - is->ptr = p; - *o = 0; - *data = is->tokenbuf; - *len = o - is->tokenbuf; - t(printf("token STRING '%s'\n", is->tokenbuf)); - return IMAP_TOK_STRING; - } - - if (c == '\n' || c == '\r' || o>=oe) { - if (o >= oe) - printf("Protocol error: string too long\n"); - else - printf("Protocol error: truncated string\n"); - goto protocol_error; - } else { - *o++ = c; - } - } - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - goto io_error; - p = is->ptr; - e = is->end; - } - } else { - o = is->tokenptr; - oe = is->tokenptr + CAMEL_IMAPP_STREAM_TOKEN - 1; - digits = isdigit(c); - *o++ = c; - while (1) { - while (p < e) { - c = *p++; - /*if (strchr(" \r\n*()[]+", c) != NULL) {*/ - if (imap_not_id(c)) { - if (c == ' ' || c == '\r') - is->ptr = p; - else - is->ptr = p-1; - *o = 0; - *data = is->tokenbuf; - *len = o - is->tokenbuf; - t(printf("token TOKEN '%s'\n", is->tokenbuf)); - return digits?IMAP_TOK_INT:IMAP_TOK_TOKEN; - } else if (o < oe) { - digits &= isdigit(c); - *o++ = c; - } else { - printf("Protocol error: token too long\n"); - goto protocol_error; - } - } - is->ptr = p; - if (stream_fill(is) == IMAP_TOK_ERROR) - goto io_error; - p = is->ptr; - e = is->end; - } - } - - /* Had an i/o erorr */ -io_error: - printf("Got io error\n"); - camel_exception_throw(1, "io error"); - return IMAP_TOK_ERROR; - - /* Protocol error, skip until next lf? */ -protocol_error: - printf("Got protocol error\n"); - - if (c == '\n') - is->ptr = p-1; - else - is->ptr = p; - - camel_exception_throw(1, "protocol error"); - return IMAP_TOK_PROTOCOL; -} - -void -camel_imapp_stream_ungettoken(CamelIMAPPStream *is, camel_imapp_token_t tok, unsigned char *token, unsigned int len) -{ - /*printf("ungettoken: '%c' '%s'\n", tok, token);*/ - is->unget_tok = tok; - is->unget_token = token; - is->unget_len = len; - is->unget++; -} - -/* returns -1 on error, 0 if last lot of data, >0 if more remaining */ -int camel_imapp_stream_gets(CamelIMAPPStream *is, unsigned char **start, unsigned int *len) -{ - int max; - unsigned char *end; - - *len = 0; - - max = is->end - is->ptr; - if (max == 0) { - max = stream_fill(is); - if (max <= 0) - return max; - } - - *start = is->ptr; - end = memchr(is->ptr, '\n', max); - if (end) - max = (end - is->ptr) + 1; - *start = is->ptr; - *len = max; - is->ptr += max; - - return end == NULL?1:0; -} - -void camel_imapp_stream_set_literal(CamelIMAPPStream *is, unsigned int literal) -{ - is->literal = literal; -} - -/* returns -1 on erorr, 0 if last data, >0 if more data left */ -int camel_imapp_stream_getl(CamelIMAPPStream *is, unsigned char **start, unsigned int *len) -{ - int max; - - *len = 0; - - if (is->literal > 0) { - max = is->end - is->ptr; - if (max == 0) { - max = stream_fill(is); - if (max <= 0) - return max; - } - - max = MIN(max, is->literal); - *start = is->ptr; - *len = max; - is->ptr += max; - is->literal -= max; - } - - if (is->literal > 0) - return 1; - - return 0; -} diff --git a/camel/providers/imapp/camel-imapp-stream.h b/camel/providers/imapp/camel-imapp-stream.h deleted file mode 100644 index 802c018672..0000000000 --- a/camel/providers/imapp/camel-imapp-stream.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_IMAPP_STREAM_H -#define _CAMEL_IMAPP_STREAM_H - -#include <camel/camel-stream.h> - -#define CAMEL_IMAPP_STREAM(obj) CAMEL_CHECK_CAST (obj, camel_imapp_stream_get_type (), CamelIMAPPStream) -#define CAMEL_IMAPP_STREAM_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_stream_get_type (), CamelIMAPPStreamClass) -#define CAMEL_IS_IMAP_STREAM(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_stream_get_type ()) - -typedef struct _CamelIMAPPStreamClass CamelIMAPPStreamClass; -typedef struct _CamelIMAPPStream CamelIMAPPStream; - -typedef enum { - IMAP_TOK_PROTOCOL = -2, - IMAP_TOK_ERROR = -1, - IMAP_TOK_TOKEN = 256, - IMAP_TOK_STRING, - IMAP_TOK_INT, - IMAP_TOK_LITERAL, -} camel_imapp_token_t; - -struct _CamelIMAPPStream { - CamelStream parent; - - CamelStream *source; - - /*int state;*/ - unsigned char *buf, *ptr, *end; - unsigned int literal; - - unsigned int unget; - camel_imapp_token_t unget_tok; - unsigned char *unget_token; - unsigned int unget_len; - - unsigned char *tokenbuf, *tokenptr, *tokenend; -}; - -struct _CamelIMAPPStreamClass { - CamelStreamClass parent_class; -}; - -CamelType camel_imapp_stream_get_type (void); - -CamelStream *camel_imapp_stream_new (CamelStream *source); - -camel_imapp_token_t camel_imapp_stream_token (CamelIMAPPStream *is, unsigned char **start, unsigned int *len); /* throws IO,PARSE exception */ -void camel_imapp_stream_ungettoken (CamelIMAPPStream *is, camel_imapp_token_t tok, unsigned char *token, unsigned int len); - -void camel_imapp_stream_set_literal (CamelIMAPPStream *is, unsigned int literal); -int camel_imapp_stream_gets (CamelIMAPPStream *is, unsigned char **start, unsigned int *len); -int camel_imapp_stream_getl (CamelIMAPPStream *is, unsigned char **start, unsigned int *len); - -/* all throw IO,PARSE exceptions */ - -/* gets an atom, upper-cases */ -int camel_imapp_stream_atom (CamelIMAPPStream *is, unsigned char **start, unsigned int *len); -/* gets an atom or string */ -int camel_imapp_stream_astring (CamelIMAPPStream *is, unsigned char **start); -/* gets a NIL or a string, start==NULL if NIL */ -int camel_imapp_stream_nstring (CamelIMAPPStream *is, unsigned char **start); -/* gets a NIL or string into a stream, stream==NULL if NIL */ -int camel_imapp_stream_nstring_stream(CamelIMAPPStream *is, CamelStream **stream); -/* gets 'text' */ -int camel_imapp_stream_text (CamelIMAPPStream *is, unsigned char **text); - -/* gets a 'number' */ -guint32 camel_imapp_stream_number(CamelIMAPPStream *is); - -#endif /* ! _CAMEL_IMAPP_STREAM_H */ diff --git a/camel/providers/imapp/camel-imapp-summary.c b/camel/providers/imapp/camel-imapp-summary.c deleted file mode 100644 index a0df21bcb0..0000000000 --- a/camel/providers/imapp/camel-imapp-summary.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright(C) 2000 Ximian Inc. - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * Dan Winship <danw@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/stat.h> -#include <sys/uio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include "camel-imapp-summary.h" -#include <camel/camel-file-utils.h> - -#define CAMEL_IMAPP_SUMMARY_VERSION (0x1000) - -static int summary_header_load(CamelFolderSummary *, FILE *); -static int summary_header_save(CamelFolderSummary *, FILE *); - -static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in); -static int message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info); - -static void camel_imapp_summary_class_init(CamelIMAPPSummaryClass *klass); -static void camel_imapp_summary_init (CamelIMAPPSummary *obj); - -static CamelFolderSummaryClass *camel_imapp_summary_parent; - -CamelType -camel_imapp_summary_get_type(void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register( - camel_folder_summary_get_type(), "CamelIMAPPSummary", - sizeof(CamelIMAPPSummary), - sizeof(CamelIMAPPSummaryClass), - (CamelObjectClassInitFunc) camel_imapp_summary_class_init, - NULL, - (CamelObjectInitFunc) camel_imapp_summary_init, - NULL); - } - - return type; -} - -static void -camel_imapp_summary_class_init(CamelIMAPPSummaryClass *klass) -{ - CamelFolderSummaryClass *cfs_class =(CamelFolderSummaryClass *) klass; - - camel_imapp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type())); - - cfs_class->summary_header_load = summary_header_load; - cfs_class->summary_header_save = summary_header_save; - cfs_class->message_info_load = message_info_load; - cfs_class->message_info_save = message_info_save; -} - -static void -camel_imapp_summary_init(CamelIMAPPSummary *obj) -{ - CamelFolderSummary *s =(CamelFolderSummary *)obj; - - /* subclasses need to set the right instance data sizes */ - s->message_info_size = sizeof(CamelIMAPPMessageInfo); - s->content_info_size = sizeof(CamelMessageContentInfo); - - /* and a unique file version */ - s->version += CAMEL_IMAPP_SUMMARY_VERSION; -} - -/** - * camel_imapp_summary_new: - * @filename: the file to store the summary in. - * - * This will create a new CamelIMAPPSummary object and read in the - * summary data from disk, if it exists. - * - * Return value: A new CamelIMAPPSummary object. - **/ -CamelFolderSummary * -camel_imapp_summary_new(void) -{ - CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY(camel_object_new(camel_imapp_summary_get_type())); - - return summary; -} - - -static int -summary_header_load(CamelFolderSummary *s, FILE *in) -{ - CamelIMAPPSummary *ims = CAMEL_IMAPP_SUMMARY(s); - - if (camel_imapp_summary_parent->summary_header_load(s, in) == -1) - return -1; - - return camel_file_util_decode_uint32(in, &ims->uidvalidity); -} - -static int -summary_header_save(CamelFolderSummary *s, FILE *out) -{ - CamelIMAPPSummary *ims = CAMEL_IMAPP_SUMMARY(s); - - if (camel_imapp_summary_parent->summary_header_save(s, out) == -1) - return -1; - - return camel_file_util_encode_uint32(out, ims->uidvalidity); -} - - -static CamelMessageInfo * -message_info_load(CamelFolderSummary *s, FILE *in) -{ - CamelMessageInfo *info; - CamelIMAPPMessageInfo *iinfo; - - info = camel_imapp_summary_parent->message_info_load(s, in); - if (info) { - iinfo =(CamelIMAPPMessageInfo *)info; - - if (camel_file_util_decode_uint32(in, &iinfo->server_flags) == -1) - goto error; - } - - return info; -error: - camel_folder_summary_info_free(s, info); - return NULL; -} - -static int -message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info) -{ - CamelIMAPPMessageInfo *iinfo =(CamelIMAPPMessageInfo *)info; - - if (camel_imapp_summary_parent->message_info_save(s, out, info) == -1) - return -1; - - return camel_file_util_encode_uint32(out, iinfo->server_flags); -} diff --git a/camel/providers/imapp/camel-imapp-summary.h b/camel/providers/imapp/camel-imapp-summary.h deleted file mode 100644 index e9783625f4..0000000000 --- a/camel/providers/imapp/camel-imapp-summary.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2000 Ximian Inc. - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * Dan Winship <danw@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _CAMEL_IMAPP_SUMMARY_H -#define _CAMEL_IMAPP_SUMMARY_H - -#include <camel/camel-folder-summary.h> -#include <camel/camel-exception.h> - -#define CAMEL_IMAPP_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_imapp_summary_get_type (), CamelIMAPPSummary) -#define CAMEL_IMAPP_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_imapp_summary_get_type (), CamelIMAPPSummaryClass) -#define CAMEL_IS_IMAPP_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_imapp_summary_get_type ()) - -#define CAMEL_IMAPP_SERVER_FLAGS (CAMEL_MESSAGE_ANSWERED | \ - CAMEL_MESSAGE_DELETED | \ - CAMEL_MESSAGE_DRAFT | \ - CAMEL_MESSAGE_FLAGGED | \ - CAMEL_MESSAGE_SEEN) - -#define CAMEL_IMAPP_MESSAGE_RECENT (1 << 8) - -typedef struct _CamelIMAPPSummaryClass CamelIMAPPSummaryClass; -typedef struct _CamelIMAPPSummary CamelIMAPPSummary; - -typedef struct _CamelIMAPPMessageInfo { - CamelMessageInfo info; - - guint32 server_flags; -} CamelIMAPPMessageInfo; - -struct _CamelIMAPPSummary { - CamelFolderSummary parent; - - guint32 uidvalidity; -}; - -struct _CamelIMAPPSummaryClass { - CamelFolderSummaryClass parent_class; - -}; - -CamelType camel_imapp_summary_get_type (void); -CamelFolderSummary *camel_imapp_summary_new (void); - -#endif /* ! _CAMEL_IMAPP_SUMMARY_H */ - diff --git a/camel/providers/imapp/camel-imapp-utils.c b/camel/providers/imapp/camel-imapp-utils.c deleted file mode 100644 index e20499689d..0000000000 --- a/camel/providers/imapp/camel-imapp-utils.c +++ /dev/null @@ -1,1339 +0,0 @@ - -#include <ctype.h> -#include <errno.h> -#include <string.h> - -#include <camel/camel-folder-summary.h> -#include <camel/camel-store.h> -#include <camel/camel-utf8.h> - -#include "camel-imapp-folder.h" -#include "camel-imapp-stream.h" -#include "camel-imapp-utils.h" -#include "camel-imapp-exception.h" -#include "camel-imapp-engine.h" -#include "e-util/e-memory.h" - -/* high-level parser state */ -#define p(x) -/* debug */ -#define d(x) - -/* ANSI-C code produced by gperf version 2.7 */ -/* Command-line: gperf -H imap_hash -N imap_tokenise -L ANSI-C -o -t -k1,$ imap-tokens.txt */ -struct _imap_keyword { char *name; enum _imap_id id; }; -/* - gperf input file - best hash generated using: gperf -o -s-2 -k1,'$' -t -H imap_hash -N imap_tokenise -L ANSI-C -*/ - -#define TOTAL_KEYWORDS 23 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 14 -#define MIN_HASH_VALUE 2 -#define MAX_HASH_VALUE 38 -/* maximum key range = 37, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#endif -static unsigned int -imap_hash (register const char *str, register unsigned int len) -{ - static unsigned char asso_values[] = - { - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 10, 15, 39, 20, 0, - 0, 39, 0, 10, 39, 0, 39, 39, 10, 0, - 0, 39, 0, 10, 5, 10, 39, 39, 39, 0, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39 - }; - return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; -} - -#ifdef __GNUC__ -__inline -#endif -enum _imap_id -imap_tokenise (register const char *str, register unsigned int len) -{ - static struct _imap_keyword wordlist[] = - { - {""}, {""}, - {"OK", IMAP_OK}, - {""}, {""}, - {"PARSE", IMAP_PARSE}, - {""}, - {"PREAUTH", IMAP_PREAUTH}, - {"ENVELOPE", IMAP_ENVELOPE}, - {"READ-ONLY", IMAP_READ_ONLY}, - {"READ-WRITE", IMAP_READ_WRITE}, - {"RFC822.SIZE", IMAP_RFC822_SIZE}, - {"NO", IMAP_NO}, - {"RFC822.HEADER", IMAP_RFC822_HEADER}, - {"TRYCREATE", IMAP_TRYCREATE}, - {"FLAGS", IMAP_FLAGS}, - {"RFC822.TEXT", IMAP_RFC822_TEXT}, - {"NEWNAME", IMAP_NEWNAME}, - {"BYE", IMAP_BYE}, - {"BODY", IMAP_BODY}, - {"ALERT", IMAP_ALERT}, - {"UIDVALIDITY", IMAP_UIDVALIDITY}, - {"INTERNALDATE", IMAP_INTERNALDATE}, - {""}, - {"PERMANENTFLAGS", IMAP_PERMANENTFLAGS}, - {""}, - {"UNSEEN", IMAP_UNSEEN}, - {""}, - {"BODYSTRUCTURE", IMAP_BODYSTRUCTURE}, - {""}, {""}, {""}, {""}, - {"UID", IMAP_UID}, - {""}, {""}, {""}, {""}, - {"BAD", IMAP_BAD} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = imap_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return wordlist[key].id; - } - } - return 0; -} - -/* flag table */ -static struct { - char *name; - guint32 flag; -} flag_table[] = { - { "\\ANSWERED", CAMEL_MESSAGE_ANSWERED }, - { "\\DELETED", CAMEL_MESSAGE_DELETED }, - { "\\DRAFT", CAMEL_MESSAGE_DRAFT }, - { "\\FLAGGED", CAMEL_MESSAGE_FLAGGED }, - { "\\SEEN", CAMEL_MESSAGE_SEEN }, - { "\\RECENT", CAMEL_IMAPP_MESSAGE_RECENT }, - { "\\*", CAMEL_MESSAGE_USER }, -}; - -/* utility functions - shoudl this be part of imapp-driver? */ -/* mabye this should be a stream op? */ -void -imap_parse_flags(CamelIMAPPStream *stream, guint32 *flagsp) -/* throws IO,PARSE exception */ -{ - int tok, len, i; - unsigned char *token, *p, c; - guint32 flags = 0; - - *flagsp = flags; - - tok = camel_imapp_stream_token(stream, &token, &len); - if (tok == '(') { - do { - tok = camel_imapp_stream_token(stream, &token, &len); - if (tok == IMAP_TOK_TOKEN) { - p = token; - while ((c=*p)) - *p++ = toupper(c); - for (i=0;i<(int)(sizeof(flag_table)/sizeof(flag_table[0]));i++) - if (!strcmp(token, flag_table[i].name)) - flags |= flag_table[i].flag; - } else if (tok != ')') { - camel_exception_throw(1, "expecting flag"); - } - } while (tok != ')'); - } else { - camel_exception_throw(1, "expecting flag list"); - } - - *flagsp = flags; -} - -void -imap_write_flags(CamelStream *stream, guint32 flags) -/* throws IO exception */ -{ - int i; - - /* all this ugly exception throwing goes away once camel streams throw their own? */ - if (camel_stream_write(stream, "(", 1) == -1) - camel_exception_throw(1, "io error: %s", strerror(errno)); - - for (i=0;flags!=0 && i<(int)(sizeof(flag_table)/sizeof(flag_table[0]));i++) { - if (flag_table[i].flag & flags) { - if (camel_stream_write(stream, flag_table[i].name, strlen(flag_table[i].name)) == -1) - camel_exception_throw(1, "io error: %s", strerror(errno)); - flags &= ~flag_table[i].flag; - if (flags != 0) - if (camel_stream_write(stream, " ", 1) == -1) - camel_exception_throw(1, "io error: %s", strerror(errno)); - } - } - - if (camel_stream_write(stream, ")", 1) == -1) - camel_exception_throw(1, "io error: %s", strerror(errno)); -} - -/* -body ::= "(" body_type_1part / body_type_mpart ")" - -body_extension ::= nstring / number / "(" 1#body_extension ")" - ;; Future expansion. Client implementations - ;; MUST accept body_extension fields. Server - ;; implementations MUST NOT generate - ;; body_extension fields except as defined by - ;; future standard or standards-track - ;; revisions of this specification. - -body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp - [SPACE body_fld_lang - [SPACE 1#body_extension]]] - ;; MUST NOT be returned on non-extensible - ;; "BODY" fetch - -body_ext_mpart ::= body_fld_param - [SPACE body_fld_dsp SPACE body_fld_lang - [SPACE 1#body_extension]] - ;; MUST NOT be returned on non-extensible - ;; "BODY" fetch - -body_fields ::= body_fld_param SPACE body_fld_id SPACE - body_fld_desc SPACE body_fld_enc SPACE - body_fld_octets - -body_fld_desc ::= nstring - -body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil - -body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ - "QUOTED-PRINTABLE") <">) / string - -body_fld_id ::= nstring - -body_fld_lang ::= nstring / "(" 1#string ")" - -body_fld_lines ::= number - -body_fld_md5 ::= nstring - -body_fld_octets ::= number - -body_fld_param ::= "(" 1#(string SPACE string) ")" / nil - -body_type_1part ::= (body_type_basic / body_type_msg / body_type_text) - [SPACE body_ext_1part] - -body_type_basic ::= media_basic SPACE body_fields - ;; MESSAGE subtype MUST NOT be "RFC822" - -body_type_mpart ::= 1*body SPACE media_subtype - [SPACE body_ext_mpart] - -body_type_msg ::= media_message SPACE body_fields SPACE envelope - SPACE body SPACE body_fld_lines - -body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines - -envelope ::= "(" env_date SPACE env_subject SPACE env_from - SPACE env_sender SPACE env_reply_to SPACE env_to - SPACE env_cc SPACE env_bcc SPACE env_in_reply_to - SPACE env_message_id ")" - -env_bcc ::= "(" 1*address ")" / nil - -env_cc ::= "(" 1*address ")" / nil - -env_date ::= nstring - -env_from ::= "(" 1*address ")" / nil - -env_in_reply_to ::= nstring - -env_message_id ::= nstring - -env_reply_to ::= "(" 1*address ")" / nil - -env_sender ::= "(" 1*address ")" / nil - -env_subject ::= nstring - -env_to ::= "(" 1*address ")" / nil - -media_basic ::= (<"> ("APPLICATION" / "AUDIO" / "IMAGE" / - "MESSAGE" / "VIDEO") <">) / string) - SPACE media_subtype - ;; Defined in [MIME-IMT] - -media_message ::= <"> "MESSAGE" <"> SPACE <"> "RFC822" <"> - ;; Defined in [MIME-IMT] - -media_subtype ::= string - ;; Defined in [MIME-IMT] - -media_text ::= <"> "TEXT" <"> SPACE media_subtype - ;; Defined in [MIME-IMT] - - - - ( "type" "subtype" body_fields [envelope body body_fld_lines] - [body_fld_lines] - - - - (("TEXT" "PLAIN" ("CHARSET" - "US-ASCII") NIL NIL "7BIT" 1152 23)("TEXT" "PLAIN" - ("CHARSET" "US-ASCII" "NAME" "cc.diff") - "<960723163407.20117h@cac.washington.edu>" - "Compiler diff" "BASE64" 4554 73) "MIXED")) - -*/ - -/* -struct _body_fields { - CamelContentType *ct; - char *msgid, *desc; - CamelTransferEncoding encoding; - guint32 size; - };*/ - -void -imap_free_body(struct _CamelMessageContentInfo *cinfo) -{ - struct _CamelMessageContentInfo *list, *next; - - list = cinfo->childs; - while (list) { - next = list->next; - imap_free_body(list); - list = next; - } - - if (cinfo->type) - camel_content_type_unref(cinfo->type); - g_free(cinfo->id); - g_free(cinfo->description); - g_free(cinfo->encoding); - g_free(cinfo); -} - -void -imap_parse_param_list(CamelIMAPPStream *is, struct _camel_header_param **plist) -{ - int tok, len; - unsigned char *token, *param; - - p(printf("body_fld_param\n")); - - /* body_fld_param ::= "(" 1#(string SPACE string) ")" / nil */ - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == '(') { - while (1) { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == ')') - break; - camel_imapp_stream_ungettoken(is, tok, token, len); - - camel_imapp_stream_astring(is, &token); - param = alloca(strlen(token)+1); - strcpy(param, token); - camel_imapp_stream_astring(is, &token); - camel_header_set_param(plist, param, token); - } - } /* else check nil? no need */ -} - -struct _CamelContentDisposition * -imap_parse_ext_optional(CamelIMAPPStream *is) -{ - int tok, len; - unsigned char *token; - struct _CamelContentDisposition * volatile dinfo = NULL; - - /* this parses both extension types, from the body_fld_dsp onwards */ - /* although the grammars are different, they can be parsed the same way */ - - /* body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp - [SPACE body_fld_lang - [SPACE 1#body_extension]]] - ;; MUST NOT be returned on non-extensible - ;; "BODY" fetch */ - - /* body_ext_mpart ::= body_fld_param - [SPACE body_fld_dsp SPACE body_fld_lang - [SPACE 1#body_extension]] - ;; MUST NOT be returned on non-extensible - ;; "BODY" fetch */ - - CAMEL_TRY { - /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */ - - tok = camel_imapp_stream_token(is, &token, &len); - switch (tok) { - case '(': - dinfo = g_malloc0(sizeof(*dinfo)); - dinfo->refcount = 1; - /* should be string */ - camel_imapp_stream_astring(is, &token); - - dinfo->disposition = g_strdup(token); - imap_parse_param_list(is, &dinfo->params); - case IMAP_TOK_TOKEN: - d(printf("body_fld_dsp: NIL\n")); - break; - default: - camel_exception_throw(1, "body_fld_disp: expecting nil or list"); - } - - p(printf("body_fld_lang\n")); - - /* body_fld_lang ::= nstring / "(" 1#string ")" */ - - /* we just drop the lang string/list, save it somewhere? */ - - tok = camel_imapp_stream_token(is, &token, &len); - switch (tok) { - case '(': - while (1) { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == ')') { - break; - } else if (tok != IMAP_TOK_STRING) { - camel_exception_throw(1, "expecting string"); - } - } - break; - case IMAP_TOK_TOKEN: - d(printf("body_fld_lang = nil\n")); - /* treat as 'nil' */ - break; - case IMAP_TOK_STRING: - /* we have a string */ - break; - case IMAP_TOK_LITERAL: - /* we have a literal string */ - camel_imapp_stream_set_literal(is, len); - while ((tok = camel_imapp_stream_getl(is, &token, &len)) > 0) { - d(printf("Skip literal data '%.*s'\n", (int)len, token)); - } - break; - - } - } CAMEL_CATCH(ex) { - if (dinfo) - camel_content_disposition_unref(dinfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return dinfo; -} - -struct _CamelMessageContentInfo * -imap_parse_body_fields(CamelIMAPPStream *is) -{ - unsigned char *token, *type; - struct _CamelMessageContentInfo *cinfo; - - /* body_fields ::= body_fld_param SPACE body_fld_id SPACE - body_fld_desc SPACE body_fld_enc SPACE - body_fld_octets */ - - p(printf("body_fields\n")); - - cinfo = g_malloc0(sizeof(*cinfo)); - - CAMEL_TRY { - /* this should be string not astring */ - camel_imapp_stream_astring(is, &token); - type = alloca(strlen(token)+1); - strcpy(type, token); - camel_imapp_stream_astring(is, &token); - cinfo->type = camel_content_type_new(type, token); - imap_parse_param_list(is, &cinfo->type->params); - - /* body_fld_id ::= nstring */ - camel_imapp_stream_nstring(is, &token); - cinfo->id = g_strdup(token); - - /* body_fld_desc ::= nstring */ - camel_imapp_stream_nstring(is, &token); - cinfo->description = g_strdup(token); - - /* body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ - "QUOTED-PRINTABLE") <">) / string */ - camel_imapp_stream_astring(is, &token); - cinfo->encoding = g_strdup(token); - - /* body_fld_octets ::= number */ - cinfo->size = camel_imapp_stream_number(is); - } CAMEL_CATCH(ex) { - imap_free_body(cinfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return cinfo; -} - -struct _camel_header_address * -imap_parse_address_list(CamelIMAPPStream *is) -/* throws PARSE,IO exception */ -{ - int tok, len; - unsigned char *token, *host, *mbox; - struct _camel_header_address *list = NULL; - - /* "(" 1*address ")" / nil */ - - CAMEL_TRY { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == '(') { - while (1) { - struct _camel_header_address *addr, *group = NULL; - - /* address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox - SPACE addr_host ")" */ - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == ')') - break; - if (tok != '(') - camel_exception_throw(1, "missing '(' for address"); - - addr = camel_header_address_new(); - addr->type = HEADER_ADDRESS_NAME; - tok = camel_imapp_stream_nstring(is, &token); - addr->name = g_strdup(token); - /* we ignore the route, nobody uses it in the real world */ - tok = camel_imapp_stream_nstring(is, &token); - - /* [RFC-822] group syntax is indicated by a special - form of address structure in which the host name - field is NIL. If the mailbox name field is also - NIL, this is an end of group marker (semi-colon in - RFC 822 syntax). If the mailbox name field is - non-NIL, this is a start of group marker, and the - mailbox name field holds the group name phrase. */ - - tok = camel_imapp_stream_nstring(is, &mbox); - mbox = g_strdup(mbox); - tok = camel_imapp_stream_nstring(is, &host); - if (host == NULL) { - if (mbox == NULL) { - group = NULL; - } else { - d(printf("adding group '%s'\n", mbox)); - g_free(addr->name); - addr->name = mbox; - addr->type = HEADER_ADDRESS_GROUP; - camel_header_address_list_append(&list, addr); - group = addr; - } - } else { - addr->v.addr = g_strdup_printf("%s%s%s", mbox?(char *)mbox:"", host?"@":"", host?(char *)host:""); - g_free(mbox); - d(printf("adding address '%s'\n", addr->v.addr)); - if (group != NULL) - camel_header_address_add_member(group, addr); - else - camel_header_address_list_append(&list, addr); - } - do { - tok = camel_imapp_stream_token(is, &token, &len); - } while (tok != ')'); - } - } else { - d(printf("empty, nil '%s'\n", token)); - } - } CAMEL_CATCH(ex) { - camel_header_address_list_clear(&list); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return list; -} - -struct _CamelMessageInfo * -imap_parse_envelope(CamelIMAPPStream *is) -{ - int tok, len; - unsigned char *token; - struct _camel_header_address *addr, *addr_from; - char *addrstr; - struct _CamelMessageInfo *minfo; - - /* envelope ::= "(" env_date SPACE env_subject SPACE env_from - SPACE env_sender SPACE env_reply_to SPACE env_to - SPACE env_cc SPACE env_bcc SPACE env_in_reply_to - SPACE env_message_id ")" */ - - p(printf("envelope\n")); - - minfo = camel_message_info_new(); - - CAMEL_TRY { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != '(') - camel_exception_throw(1, "envelope: expecting '('"); - - /* env_date ::= nstring */ - camel_imapp_stream_nstring(is, &token); - minfo->date_sent = camel_header_decode_date(token, NULL); - - /* env_subject ::= nstring */ - tok = camel_imapp_stream_nstring(is, &token); - /* DUH: this free's it!: camel_message_info_set_subject(minfo, token); */ - e_poolv_set(minfo->strings, CAMEL_MESSAGE_INFO_SUBJECT, token, FALSE); - - /* we merge from/sender into from, append should probably merge more smartly? */ - - /* env_from ::= "(" 1*address ")" / nil */ - addr_from = imap_parse_address_list(is); - - /* env_sender ::= "(" 1*address ")" / nil */ - addr = imap_parse_address_list(is); - if (addr_from) { - camel_header_address_list_clear(&addr); -#if 0 - if (addr) - camel_header_address_list_append_list(&addr_from, &addr); -#endif - } else { - if (addr) - addr_from = addr; - } - - if (addr_from) { - addrstr = camel_header_address_list_format(addr_from); - camel_message_info_set_from(minfo, addrstr); - camel_header_address_list_clear(&addr_from); - } - - /* we dont keep reply_to */ - - /* env_reply_to ::= "(" 1*address ")" / nil */ - addr = imap_parse_address_list(is); - camel_header_address_list_clear(&addr); - - /* env_to ::= "(" 1*address ")" / nil */ - addr = imap_parse_address_list(is); - if (addr) { - addrstr = camel_header_address_list_format(addr); - camel_message_info_set_to(minfo, addrstr); - camel_header_address_list_clear(&addr); - } - - /* env_cc ::= "(" 1*address ")" / nil */ - addr = imap_parse_address_list(is); - if (addr) { - addrstr = camel_header_address_list_format(addr); - camel_message_info_set_cc(minfo, addrstr); - camel_header_address_list_clear(&addr); - } - - /* we dont keep bcc either */ - - /* env_bcc ::= "(" 1*address ")" / nil */ - addr = imap_parse_address_list(is); - camel_header_address_list_clear(&addr); - - /* FIXME: need to put in-reply-to into references hash list */ - - /* env_in_reply_to ::= nstring */ - tok = camel_imapp_stream_nstring(is, &token); - - /* FIXME: need to put message-id into message-id hash */ - - /* env_message_id ::= nstring */ - tok = camel_imapp_stream_nstring(is, &token); - - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != ')') - camel_exception_throw(1, "expecting ')'"); - } CAMEL_CATCH(ex) { - camel_message_info_free(minfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return minfo; -} - -struct _CamelMessageContentInfo * -imap_parse_body(CamelIMAPPStream *is) -{ - int tok, len; - unsigned char *token; - struct _CamelMessageContentInfo * volatile cinfo = NULL; - struct _CamelMessageContentInfo *subinfo, *last; - struct _CamelContentDisposition * volatile dinfo = NULL; - struct _CamelMessageInfo * volatile minfo = NULL; - - /* body ::= "(" body_type_1part / body_type_mpart ")" */ - - p(printf("body\n")); - - CAMEL_TRY { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != '(') - camel_exception_throw(1, "body: expecting '('"); - - /* 1*body (optional for multiparts) */ - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - if (tok == '(') { - /* body_type_mpart ::= 1*body SPACE media_subtype - [SPACE body_ext_mpart] */ - - cinfo = g_malloc0(sizeof(*cinfo)); - last = (struct _CamelMessageContentInfo *)&cinfo->childs; - do { - subinfo = imap_parse_body(is); - last->next = subinfo; - last = subinfo; - subinfo->parent = cinfo; - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - } while (tok == '('); - - d(printf("media_subtype\n")); - - camel_imapp_stream_astring(is, &token); - cinfo->type = camel_content_type_new("multipart", token); - - /* body_ext_mpart ::= body_fld_param - [SPACE body_fld_dsp SPACE body_fld_lang - [SPACE 1#body_extension]] - ;; MUST NOT be returned on non-extensible - ;; "BODY" fetch */ - - d(printf("body_ext_mpart\n")); - - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - if (tok == '(') { - imap_parse_param_list(is, &cinfo->type->params); - - /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */ - - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - if (tok == '(' || tok == IMAP_TOK_TOKEN) { - dinfo = imap_parse_ext_optional(is); - /* other extension fields?, soaked up below */ - } else { - camel_imapp_stream_ungettoken(is, tok, token, len); - } - } - } else { - /* body_type_1part ::= (body_type_basic / body_type_msg / body_type_text) - [SPACE body_ext_1part] - - body_type_basic ::= media_basic SPACE body_fields - body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines - body_type_msg ::= media_message SPACE body_fields SPACE envelope - SPACE body SPACE body_fld_lines */ - - d(printf("Single part body\n")); - - cinfo = imap_parse_body_fields(is); - - d(printf("envelope?\n")); - - /* do we have an envelope following */ - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - if (tok == '(') { - /* what do we do with the envelope?? */ - minfo = imap_parse_envelope(is); - /* what do we do with the message content info?? */ - minfo->content = imap_parse_body(is); - camel_message_info_free(minfo); - minfo = NULL; - d(printf("Scanned envelope - what do i do with it?\n")); - } - - d(printf("fld_lines?\n")); - - /* do we have fld_lines following? */ - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == IMAP_TOK_INT) { - d(printf("field lines: %s\n", token)); - tok = camel_imapp_stream_token(is, &token, &len); - } - camel_imapp_stream_ungettoken(is, tok, token, len); - - /* body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp - [SPACE body_fld_lang - [SPACE 1#body_extension]]] - ;; MUST NOT be returned on non-extensible - ;; "BODY" fetch */ - - d(printf("extension data?\n")); - - if (tok != ')') { - camel_imapp_stream_nstring(is, &token); - - d(printf("md5: %s\n", token?(char *)token:"NIL")); - - /* body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil */ - - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - if (tok == '(' || tok == IMAP_TOK_TOKEN) { - dinfo = imap_parse_ext_optional(is); - /* then other extension fields, soaked up below */ - } - } - } - - /* soak up any other extension fields that may be present */ - /* there should only be simple tokens, no lists */ - do { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != ')') - d(printf("Dropping extension data '%s'\n", token)); - } while (tok != ')'); - } CAMEL_CATCH(ex) { - if (cinfo) - imap_free_body(cinfo); - if (dinfo) - camel_content_disposition_unref(dinfo); - if (minfo) - camel_message_info_free(minfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - /* FIXME: do something with the disposition, currently we have no way to pass it out? */ - if (dinfo) - camel_content_disposition_unref(dinfo); - - return cinfo; -} - -char * -imap_parse_section(CamelIMAPPStream *is) -{ - int tok, len; - unsigned char *token; - char * volatile section = NULL; - - /* currently we only return the part within the [section] specifier - any header fields are parsed, but dropped */ - - /* - section ::= "[" [section_text / - (nz_number *["." nz_number] ["." (section_text / "MIME")])] "]" - - section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"] - SPACE header_list / "TEXT" - */ - - CAMEL_TRY { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != '[') - camel_exception_throw(1, "section: expecting '['"); - - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == IMAP_TOK_INT || tok == IMAP_TOK_TOKEN) - section = g_strdup(token); - else if (tok == ']') { - section = g_strdup(""); - camel_imapp_stream_ungettoken(is, tok, token, len); - } else - camel_exception_throw(1, "section: expecting token"); - - /* header_list ::= "(" 1#header_fld_name ")" - header_fld_name ::= astring */ - - /* we dont need the header specifiers */ - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == '(') { - do { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == IMAP_TOK_STRING || tok == IMAP_TOK_TOKEN || tok == IMAP_TOK_INT) { - /* ?do something? */ - } else if (tok != ')') - camel_exception_throw(1, "section: header fields: expecting string"); - } while (tok != ')'); - tok = camel_imapp_stream_token(is, &token, &len); - } - - if (tok != ']') - camel_exception_throw(1, "section: expecting ']'"); - } CAMEL_CATCH(ex) { - g_free(section); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return section; -} - -void -imap_free_fetch(struct _fetch_info *finfo) -{ - if (finfo == NULL) - return; - - if (finfo->body) - camel_object_unref((CamelObject *)finfo->body); - if (finfo->text) - camel_object_unref((CamelObject *)finfo->text); - if (finfo->header) - camel_object_unref((CamelObject *)finfo->header); - if (finfo->minfo) - camel_message_info_free(finfo->minfo); - if (finfo->cinfo) - imap_free_body(finfo->cinfo); - g_free(finfo->date); - g_free(finfo->section); - g_free(finfo->uid); - g_free(finfo); -} - -extern void camel_content_info_dump(CamelMessageContentInfo *ci, int depth); -extern void camel_message_info_dump(CamelMessageInfo *mi); - -#include <camel/camel-stream-fs.h> - -/* debug, dump one out */ -void -imap_dump_fetch(struct _fetch_info *finfo) -{ - CamelStream *sout; - int fd; - - printf("Fetch info:\n"); - if (finfo == NULL) { - printf("Empty\n"); - return; - } - - fd = dup(1); - sout = camel_stream_fs_new_with_fd(fd); - if (finfo->body) { - camel_stream_printf(sout, "Body content:\n"); - camel_stream_write_to_stream(finfo->body, sout); - } - if (finfo->text) { - camel_stream_printf(sout, "Text content:\n"); - camel_stream_write_to_stream(finfo->text, sout); - } - if (finfo->header) { - camel_stream_printf(sout, "Header content:\n"); - camel_stream_write_to_stream(finfo->header, sout); - } - if (finfo->minfo) { - camel_stream_printf(sout, "Message Info:\n"); - camel_message_info_dump(finfo->minfo); - } - if (finfo->cinfo) { - camel_stream_printf(sout, "Content Info:\n"); - camel_content_info_dump(finfo->cinfo, 0); - } - if (finfo->got & FETCH_SIZE) - camel_stream_printf(sout, "Size: %d\n", (int)finfo->size); - if (finfo->got & FETCH_BODY) - camel_stream_printf(sout, "Offset: %d\n", (int)finfo->offset); - if (finfo->got & FETCH_FLAGS) - camel_stream_printf(sout, "Flags: %08x\n", (int)finfo->flags); - if (finfo->date) - camel_stream_printf(sout, "Date: '%s'\n", finfo->date); - if (finfo->section) - camel_stream_printf(sout, "Section: '%s'\n", finfo->section); - if (finfo->date) - camel_stream_printf(sout, "UID: '%s'\n", finfo->uid); - camel_object_unref((CamelObject *)sout); -} - -struct _fetch_info * -imap_parse_fetch(CamelIMAPPStream *is) -{ - int tok, len; - unsigned char *token, *p, c; - struct _fetch_info *finfo; - - finfo = g_malloc0(sizeof(*finfo)); - - CAMEL_TRY { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != '(') - camel_exception_throw(1, "fetch: expecting '('"); - - while ( (tok = camel_imapp_stream_token(is, &token, &len)) == IMAP_TOK_TOKEN ) { - - p = token; - while ((c=*p)) - *p++ = toupper(c); - - switch(imap_tokenise(token, len)) { - case IMAP_ENVELOPE: - finfo->minfo = imap_parse_envelope(is); - finfo->got |= FETCH_MINFO; - break; - case IMAP_FLAGS: - imap_parse_flags(is, &finfo->flags); - finfo->got |= FETCH_FLAGS; - break; - case IMAP_INTERNALDATE: - camel_imapp_stream_nstring(is, &token); - /* TODO: convert to camel format? */ - finfo->date = g_strdup(token); - finfo->got |= FETCH_DATE; - break; - case IMAP_RFC822_HEADER: - camel_imapp_stream_nstring_stream(is, &finfo->header); - finfo->got |= FETCH_HEADER; - break; - case IMAP_RFC822_TEXT: - camel_imapp_stream_nstring_stream(is, &finfo->text); - finfo->got |= FETCH_TEXT; - break; - case IMAP_RFC822_SIZE: - finfo->size = camel_imapp_stream_number(is); - finfo->got |= FETCH_SIZE; - break; - case IMAP_BODYSTRUCTURE: - finfo->cinfo = imap_parse_body(is); - finfo->got |= FETCH_CINFO; - break; - case IMAP_BODY: - tok = camel_imapp_stream_token(is, &token, &len); - camel_imapp_stream_ungettoken(is, tok, token, len); - if (tok == '(') { - finfo->cinfo = imap_parse_body(is); - finfo->got |= FETCH_CINFO; - } else if (tok == '[') { - finfo->section = imap_parse_section(is); - finfo->got |= FETCH_SECTION; - tok = camel_imapp_stream_token(is, &token, &len); - if (token[0] == '<') { - finfo->offset = strtoul(token+1, NULL, 10); - } else { - camel_imapp_stream_ungettoken(is, tok, token, len); - } - camel_imapp_stream_nstring_stream(is, &finfo->body); - finfo->got |= FETCH_BODY; - } else { - camel_exception_throw(1, "unknown body response"); - } - break; - case IMAP_UID: - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != IMAP_TOK_INT) - camel_exception_throw(1, "uid not integer"); - finfo->uid = g_strdup(token); - finfo->got |= FETCH_UID; - break; - default: - camel_exception_throw(1, "unknown body response"); - } - } - - if (tok != ')') - camel_exception_throw(1, "missing closing ')' on fetch response"); - } CAMEL_CATCH(ex) { - imap_free_fetch(finfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return finfo; -} - -/* rfc 2060 section 7.1 Status Responses */ -/* shoudl this start after [ or before the [? token_unget anyone? */ -struct _status_info * -imap_parse_status(CamelIMAPPStream *is) -{ - int tok, len; - unsigned char *token; - struct _status_info *sinfo; - - sinfo = g_malloc0(sizeof(*sinfo)); - - CAMEL_TRY { - camel_imapp_stream_atom(is, &token, &len); - - /* - resp_cond_auth ::= ("OK" / "PREAUTH") SPACE resp_text - ;; Authentication condition - - resp_cond_bye ::= "BYE" SPACE resp_text - - resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text - ;; Status condition - */ - - sinfo->result = imap_tokenise(token, len); - switch (sinfo->result) { - case IMAP_OK: - case IMAP_NO: - case IMAP_BAD: - case IMAP_PREAUTH: - case IMAP_BYE: - break; - default: - camel_exception_throw(1, "expecting OK/NO/BAD"); - } - - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == '[') { - camel_imapp_stream_atom(is, &token, &len); - sinfo->condition = imap_tokenise(token, len); - - /* parse any details */ - switch (sinfo->condition) { - case IMAP_READ_ONLY: - case IMAP_READ_WRITE: - case IMAP_ALERT: - case IMAP_PARSE: - case IMAP_TRYCREATE: - break; - case IMAP_NEWNAME: - /* the rfc doesn't specify the bnf for this */ - camel_imapp_stream_astring(is, &token); - sinfo->u.newname.oldname = g_strdup(token); - camel_imapp_stream_astring(is, &token); - sinfo->u.newname.newname = g_strdup(token); - break; - case IMAP_PERMANENTFLAGS: - imap_parse_flags(is, &sinfo->u.permanentflags); - break; - case IMAP_UIDVALIDITY: - sinfo->u.uidvalidity = camel_imapp_stream_number(is); - break; - case IMAP_UNSEEN: - sinfo->u.unseen = camel_imapp_stream_number(is); - break; - default: - sinfo->condition = IMAP_UNKNOWN; - printf("Got unknown response code: %s: ignored\n", token); - } - - /* ignore anything we dont know about */ - do { - tok = camel_imapp_stream_token(is, &token, &len); - if (tok == '\n') - camel_exception_throw(1, "server response truncated"); - } while (tok != ']'); - } else { - camel_imapp_stream_ungettoken(is, tok, token, len); - } - - /* and take the human readable response */ - camel_imapp_stream_text(is, (unsigned char **)&sinfo->text); - } CAMEL_CATCH(ex) { - imap_free_status(sinfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return sinfo; -} - -void -imap_free_status(struct _status_info *sinfo) -{ - if (sinfo == NULL) - return; - - switch (sinfo->condition) { - case IMAP_NEWNAME: - g_free(sinfo->u.newname.oldname); - g_free(sinfo->u.newname.newname); - default: - break; - } - - g_free(sinfo->text); - g_free(sinfo); -} - -/* FIXME: use tokeniser? */ -/* FIXME: real flags */ -static struct { - char *name; - guint32 flag; -} list_flag_table[] = { - { "\\NOINFERIORS", CAMEL_FOLDER_NOINFERIORS }, - { "\\NOSELECT", CAMEL_FOLDER_NOSELECT }, - { "\\MARKED", 1<<8 }, - { "\\UNMARKED", 1<<9 }, -}; - -struct _list_info * -imap_parse_list(CamelIMAPPStream *is) -/* throws io, parse */ -{ - int tok, len, i; - unsigned char *token, *p, c; - struct _list_info * volatile linfo; - - linfo = g_malloc0(sizeof(*linfo)); - - CAMEL_TRY { - /* mailbox_list ::= "(" #("\Marked" / "\Noinferiors" / - "\Noselect" / "\Unmarked" / flag_extension) ")" - SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox */ - - tok = camel_imapp_stream_token(is, &token, &len); - if (tok != '(') - camel_exception_throw(1, "list: expecting '('"); - - while ( (tok = camel_imapp_stream_token(is, &token, &len)) != ')' ) { - if (tok == IMAP_TOK_STRING || tok == IMAP_TOK_TOKEN) { - p = token; - while ((c=*p)) - *p++ = toupper(c); - for (i=0;i<(int)(sizeof(list_flag_table)/sizeof(list_flag_table[0]));i++) - if (!strcmp(token, list_flag_table[i].name)) - linfo->flags |= list_flag_table[i].flag; - } else { - camel_exception_throw(1, "list: expecting flag or ')'"); - } - } - - camel_imapp_stream_nstring(is, &token); - linfo->separator = token?*token:0; - camel_imapp_stream_astring(is, &token); - linfo->name = g_strdup(token); - } CAMEL_CATCH(ex) { - imap_free_list(linfo); - camel_exception_throw_ex(ex); - } CAMEL_DONE; - - return linfo; -} - -char * -imapp_list_get_path(struct _list_info *li) -{ - char *path, *p; - int c; - const char *f; - - if (li->separator != 0 && li->separator != '/') { - p = path = alloca(strlen(li->name)*3+1); - f = li->name; - while ( (c = *f++ & 0xff) ) { - if (c == li->separator) - *p++ = '/'; - else if (c == '/' || c == '%') - p += sprintf(p, "%%%02X", c); - else - *p++ = c; - } - *p = 0; - } else - path = li->name; - - return camel_utf7_utf8(path); -} - -void -imap_free_list(struct _list_info *linfo) -{ - if (linfo) { - g_free(linfo->name); - g_free(linfo); - } -} - - -/* ********************************************************************** */ -/* utility functions */ - -/* should the rest of imapp-utils go into imapp-parse? */ - -/* this creates a uid (or sequence number) set directly into the command, - optionally breaking it into smaller chunks */ - -void -imapp_uidset_init(struct _uidset_state *ss, CamelIMAPPEngine *ie) -{ - ss->ie = ie; - ss->len = 0; - ss->start = 0; - ss->last = 0; -} - -int -imapp_uidset_done(struct _uidset_state *ss, CamelIMAPPCommand *ic) -{ - int ret = 0; - - if (ss->last != 0 && ss->last != ss->start) { - camel_imapp_engine_command_add(ss->ie, ic, ":%d", ss->last); - printf(":%d", ss->last); - } - - ret = ss->last != 0; - - ss->start = 0; - ss->last = 0; - ss->len = 0; - - return ret; -} - -int -imapp_uidset_add(struct _uidset_state *ss, CamelIMAPPCommand *ic, const char *uid) -{ - guint32 uidn; - - uidn = strtoul(uid, NULL, 10); - if (uidn == 0) - return -1; - - if (ss->last == 0) { - camel_imapp_engine_command_add(ss->ie, ic, "%d", uidn); - printf("%d", uidn); - ss->len ++; - ss->start = uidn; - } else { - if (ss->last != uidn-1) { - if (ss->last == ss->start) { - camel_imapp_engine_command_add(ss->ie, ic, ",%d", uidn); - printf(",%d", uidn); - ss->len ++; - } else { - camel_imapp_engine_command_add(ss->ie, ic, ":%d,%d", ss->last, uidn); - printf(":%d,%d", ss->last, uidn); - ss->len+=2; - } - ss->start = uidn; - } - } - - ss->last = uidn; - - if (ss->len > 10) { - imapp_uidset_done(ss, ic); - return 1; - } - - return 0; -} diff --git a/camel/providers/imapp/camel-imapp-utils.h b/camel/providers/imapp/camel-imapp-utils.h deleted file mode 100644 index e0974bdc96..0000000000 --- a/camel/providers/imapp/camel-imapp-utils.h +++ /dev/null @@ -1,145 +0,0 @@ - -#ifndef _CAMEL_IMAPP_UTILS_H -#define _CAMEL_IMAPP_UTILS_H - -#include <camel/camel-mime-utils.h> - -/* FIXME: the enum should be split up into logical groups, so that testing - can be done more accurately? */ - -/* list of strings we know about that can be *quickly* tokenised */ -enum _imap_id { - IMAP_UNKNOWN = 0, - IMAP_ALERT, - IMAP_BYE, - IMAP_BAD, - IMAP_NO, - IMAP_OK, - IMAP_PREAUTH, - IMAP_NEWNAME, - IMAP_PARSE, - IMAP_PERMANENTFLAGS, - IMAP_READ_ONLY, - IMAP_READ_WRITE, - IMAP_TRYCREATE, - IMAP_UIDVALIDITY, - IMAP_UNSEEN, - IMAP_ENVELOPE, - IMAP_FLAGS, - IMAP_INTERNALDATE, - IMAP_RFC822_HEADER, - IMAP_RFC822_TEXT, - IMAP_RFC822_SIZE, - IMAP_BODYSTRUCTURE, - IMAP_BODY, - IMAP_UID, -}; - -/* str MUST be in upper case, tokenised using gperf function */ -enum _imap_id imap_tokenise(register const char *str, register unsigned int len); - -/* this flag should be part of imapfoldersummary */ -enum { - CAMEL_IMAPP_MESSAGE_RECENT = (1<<8), -}; - -/* ********************************************************************** */ -void imap_parse_flags(CamelIMAPPStream *stream, guint32 *flagsp) /* IO,PARSE */; -void imap_write_flags(CamelStream *stream, guint32 flags) /* IO */; - -/* ********************************************************************** */ -void imap_parse_param_list(CamelIMAPPStream *is, struct _camel_header_param **plist) /* IO,PARSE */; -struct _CamelContentDisposition *imap_parse_ext_optional(CamelIMAPPStream *is) /* IO,PARSE */; -struct _CamelMessageContentInfo *imap_parse_body_fields(CamelIMAPPStream *is) /* IO,PARSE */; -struct _camel_header_address *imap_parse_address_list(CamelIMAPPStream *is) /* IO,PARSE */; -struct _CamelMessageInfo *imap_parse_envelope(CamelIMAPPStream *is) /* IO, PARSE */; -struct _CamelMessageContentInfo *imap_parse_body(CamelIMAPPStream *is) /* IO,PARSE */; -char *imap_parse_section(CamelIMAPPStream *is) /* IO,PARSE */; -void imap_free_body(struct _CamelMessageContentInfo *cinfo); - -/* ********************************************************************** */ -/* all the possible stuff we might get from a fetch request */ -/* this assumes the caller/server doesn't send any one of these types twice */ -struct _fetch_info { - guint32 got; /* what we got, see below */ - CamelStream *body; /* BODY[.*](<.*>)? */ - CamelStream *text; /* RFC822.TEXT */ - CamelStream *header; /* RFC822.HEADER */ - CamelMessageInfo *minfo; /* ENVELOPE */ - CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */ - guint32 size; /* RFC822.SIZE */ - guint32 offset; /* start offset of a BODY[]<offset.length> request */ - guint32 flags; /* FLAGS */ - char *date; /* INTERNALDATE */ - char *section; /* section for a BODY[section] request */ - char *uid; /* UID */ -}; - -#define FETCH_BODY (1<<0) -#define FETCH_TEXT (1<<1) -#define FETCH_HEADER (1<<2) -#define FETCH_MINFO (1<<3) -#define FETCH_CINFO (1<<4) -#define FETCH_SIZE (1<<5) -#define FETCH_OFFSET (1<<6) -#define FETCH_FLAGS (1<<7) -#define FETCH_DATE (1<<8) -#define FETCH_SECTION (1<<9) -#define FETCH_UID (1<<10) - -struct _fetch_info *imap_parse_fetch(CamelIMAPPStream *is); -void imap_free_fetch(struct _fetch_info *finfo); -void imap_dump_fetch(struct _fetch_info *finfo); - -/* ********************************************************************** */ - -struct _status_info { - enum _imap_id result; /* ok/no/bad/preauth only */ - enum _imap_id condition; /* read-only/read-write/alert/parse/trycreate/newname/permanentflags/uidvalidity/unseen */ - - union { - struct { - char *oldname; - char *newname; - } newname; - guint32 permanentflags; - guint32 uidvalidity; - guint32 unseen; - } u; - - char *text; -}; - -struct _status_info *imap_parse_status(CamelIMAPPStream *is); -void imap_free_status(struct _status_info *sinfo); - -/* ********************************************************************** */ - -/* should this just return a FolderInfo? - should this just return the name & flags & separator by reference? */ -struct _list_info { - guint32 flags:24; - char separator; - char *name; -}; - -struct _list_info *imap_parse_list(CamelIMAPPStream *is); -char *imapp_list_get_path(struct _list_info *li); -void imap_free_list(struct _list_info *linfo); - -/* ********************************************************************** */ - -struct _uidset_state { - struct _CamelIMAPPEngine *ie; - int len; - guint32 start; - guint32 last; -}; - -struct _CamelIMAPPEngine; -struct _CamelIMAPPCommand; -void imapp_uidset_init(struct _uidset_state *ss, struct _CamelIMAPPEngine *ie); -int imapp_uidset_done(struct _uidset_state *ss, struct _CamelIMAPPCommand *ic); -int imapp_uidset_add(struct _uidset_state *ss, struct _CamelIMAPPCommand *ic, const char *uid); - -#endif diff --git a/camel/providers/imapp/libcamelimapp.urls b/camel/providers/imapp/libcamelimapp.urls deleted file mode 100644 index aad1347834..0000000000 --- a/camel/providers/imapp/libcamelimapp.urls +++ /dev/null @@ -1 +0,0 @@ -imapp |