X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-mx%2Fpop-new.c;h=3d772b43a3d18d4e134610c674f8be8594ccc700;hp=3936cbbfc6d44efa11af2c21a5bc22cae6a3bb2a;hb=fc9b0f39b53ad39e08c45d4c036af036f512755e;hpb=6b4475312b058043257fba4526817f60d9e26baf diff --git a/lib-mx/pop-new.c b/lib-mx/pop-new.c index 3936cbb..3d772b4 100644 --- a/lib-mx/pop-new.c +++ b/lib-mx/pop-new.c @@ -21,14 +21,18 @@ #include #include "pop.h" +#include "account.h" + +#define POP3_PORT 110 +#define POP3S_PORT 995 typedef struct pop_data_t { int refcnt; job_t *w; + + ACCOUNT act; } pop_data_t; -DO_INIT(pop_data_t, pop_data); -DO_WIPE(pop_data_t, pop_data); -DO_REFCNT(pop_data_t, pop_data); +static void pop_data_delete(pop_data_t **tp); DO_ARRAY_TYPE(pop_data_t, pop_data); DO_ARRAY_FUNCS(pop_data_t, pop_data, pop_data_delete); @@ -38,6 +42,41 @@ DO_ARRAY_FUNCS(pop_data_t, pop_data, pop_data_delete); static pop_data_array conns; +static inline pop_data_t *pop_data_new(void) +{ + pop_data_t *res = p_new(pop_data_t, 1); + res->refcnt = 1; + pop_data_array_append(&conns, res); + return res; +} +static inline pop_data_t *pop_data_dup(pop_data_t *t) +{ + t->refcnt++; + return t; +} +static void pop_data_wipe(pop_data_t *pd) +{ + if (pd->w) + IGNORE(el_job_release(pd->w, EL_KILLED)); +} +static void pop_data_delete(pop_data_t **tp) +{ + if (!*tp) + return; + if (--(*tp)->refcnt > 0) { + *tp = NULL; + } else { + for (int i = 0; i < conns.len; i++) { + if (conns.arr[i] == *tp) { + pop_data_array_take(&conns, i); + break; + } + } + pop_data_wipe(*tp); + p_delete(tp); + } +} + static __init void pop_initialize(void) { pop_data_array_init(&conns); @@ -53,11 +92,14 @@ static __fini void pop_shutdown(void) static int pop_setup(job_t *w, void *cfg) { + w->ptr = pop_data_dup(cfg); + /* FIXME */ return el_job_release(w, EL_ERROR); return 0; } static void pop_finalize(job_t *w, el_status reason) { + pop_data_delete((pop_data_t **)(void *)&w->ptr); } static machine_t const pop_machine = { @@ -70,18 +112,80 @@ static machine_t const pop_machine = { /* pop3 mx driver */ /****************************************************************************/ +static int pop_parse_path(const char *path, ACCOUNT *act) +{ + ciss_url_t url; + char s[BUFSIZ]; + + /* Defaults */ + act->flags = 0; + act->port = POP3_PORT; + act->type = M_ACCT_TYPE_POP; + m_strcpy(s, sizeof(s), path); + url_parse_ciss(&url, s); + + if (url.scheme == U_POP || url.scheme == U_POPS) { + if (url.scheme == U_POPS) { + act->has_ssl = 1; + act->port = POP3S_PORT; + } + + if (m_strisempty(url.path) && !mutt_account_fromurl(act, &url)) + return 0; + } + + return -1; +} + +static pop_data_t *pop_find_conn(ACCOUNT *act) +{ + pop_data_t *pd = NULL; + + for (int i = 0; i < conns.len; i++) { + if (mutt_account_match(act, &conns.arr[i]->act)) { + pd = pop_data_dup(conns.arr[i]); + break; + } + } + if (!pd) { + pd = pop_data_new(); + pd->act = *act; + } + + return pd; +} + +static int pop_open_mailbox(CONTEXT *ctx) +{ + char buf[BUFSIZ]; + ACCOUNT act; + ciss_url_t url; + pop_data_t *pd = NULL; + + if (pop_parse_path(ctx->path, &act)) { + mutt_error(_("%s is an invalid POP path"), ctx->path); + mutt_sleep(2); + return -1; + } + + p_clear(&url, 1); + mutt_account_tourl(&act, &url); + + el_lock(); + pd = pop_find_conn(&act); + if (false) { + ctx->data = pd; + url_ciss_tostring(&url, buf, sizeof (buf), 0); + m_strreplace(&ctx->path, buf); + } else { + pop_data_delete(&pd); + } + el_unlock(); + + return -1; +} + mx_t const pop_mx_ng = { - M_POP, - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + .type = M_POP, + .mx_open_mailbox = pop_open_mailbox, };