2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * Copyright © 2007 Pierre Habouzit
19 * Copyright © 2000-2002 Vsevolod Volkov <vvv@mutt.org.ua>
22 #include <lib-sys/evtloop.h>
27 #define POP3S_PORT 995
34 typedef struct pop_data_t {
42 static void pop_data_delete(pop_data_t **tp);
43 DO_ARRAY_TYPE(pop_data_t, pop_data);
44 DO_ARRAY_FUNCS(pop_data_t, pop_data, pop_data_delete);
46 /****************************************************************************/
48 /****************************************************************************/
50 static pop_data_array conns;
52 static inline pop_data_t *pop_data_new(void)
54 pop_data_t *res = p_new(pop_data_t, 1);
56 pop_data_array_append(&conns, res);
59 static inline pop_data_t *pop_data_dup(pop_data_t *t)
64 static void pop_data_wipe(pop_data_t *pd)
67 IGNORE(el_job_release((job_t *)pd->w, EL_KILLED));
69 static void pop_data_delete(pop_data_t **tp)
73 if (--(*tp)->refcnt > 0) {
76 for (int i = 0; i < conns.len; i++) {
77 if (conns.arr[i] == *tp) {
78 pop_data_array_take(&conns, i);
87 static __init void pop_initialize(void)
89 pop_data_array_init(&conns);
91 static __fini void pop_shutdown(void)
93 pop_data_array_wipe(&conns);
96 /****************************************************************************/
98 /****************************************************************************/
100 static int pop_setup(job_t *w, void *cfg)
102 w->ptr = pop_data_dup(cfg);
103 /* FIXME */ return el_job_release(w, EL_ERROR);
107 static void pop_finalize(job_t *w, el_status reason)
109 pop_data_delete((pop_data_t **)(void *)&w->ptr);
112 static machine_t const pop_machine = {
115 .finalize = &pop_finalize,
118 /****************************************************************************/
120 /****************************************************************************/
122 static int pop_parse_path(const char *path, ACCOUNT *act)
129 act->port = POP3_PORT;
130 act->type = M_ACCT_TYPE_POP;
131 m_strcpy(s, sizeof(s), path);
132 url_parse_ciss(&url, s);
134 if (url.scheme == U_POP || url.scheme == U_POPS) {
135 if (url.scheme == U_POPS) {
137 act->port = POP3S_PORT;
140 if (m_strisempty(url.path) && !mutt_account_fromurl(act, &url))
147 static pop_data_t *pop_find_conn(ACCOUNT *act)
149 pop_data_t *pd = NULL;
152 for (int i = 0; i < conns.len; i++) {
153 if (mutt_account_match(act, &conns.arr[i]->act)) {
154 pd = pop_data_dup(conns.arr[i]);
163 pd->w = el_job_start(&pop_machine, pd);
165 while (pd->w && pd->state != POP_READY) {
169 pop_data_delete(&pd);
175 static int pop_open_mailbox(CONTEXT *ctx)
180 pop_data_t *pd = NULL;
182 if (pop_parse_path(ctx->path, &act)) {
183 mutt_error(_("%s is an invalid POP path"), ctx->path);
189 mutt_account_tourl(&act, &url);
191 pd = pop_find_conn(&act);
194 url_ciss_tostring(&url, buf, sizeof (buf), 0);
195 m_strreplace(&ctx->path, buf);
200 mx_t const pop_mx_ng = {
202 .mx_open_mailbox = pop_open_mailbox,