#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 account;
+ ACCOUNT act;
} pop_data_t;
-DO_INIT(pop_data_t, pop_data);
-DO_WIPE(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);
static pop_data_array conns;
-static inline pop_data_t *pop_data_new(void) {
- pop_data_t *res = pop_data_init(p_new(pop_data_t, 1));
+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) {
+static inline pop_data_t *pop_data_dup(pop_data_t *t)
+{
t->refcnt++;
return t;
}
-static void pop_data_delete(pop_data_t **tp) {
+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) {
static int pop_setup(job_t *w, void *cfg)
{
- w->ptr = cfg;
+ w->ptr = pop_data_dup(cfg);
/* FIXME */ return el_job_release(w, EL_ERROR);
return 0;
}
/* 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 = {
- .type = M_POP,
+ .type = M_POP,
+ .mx_open_mailbox = pop_open_mailbox,
};