Refcounted type isn't enough, we must have a list of'em
[apps/madmutt.git] / lib-mx / pop-new.c
1 /*
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.
6  *
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.
11  *
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,
15  *  MA 02110-1301, USA.
16  */
17 /*
18  *  Copyright © 2007 Pierre Habouzit
19  *  Copyright © 2000-2002 Vsevolod Volkov <vvv@mutt.org.ua>
20  */
21
22 #include <lib-sys/evtloop.h>
23 #include "pop.h"
24 #include "account.h"
25
26 typedef struct pop_data_t {
27     int refcnt;
28     job_t *w;
29
30     ACCOUNT account;
31 } pop_data_t;
32 DO_INIT(pop_data_t, pop_data);
33 DO_WIPE(pop_data_t, pop_data);
34 static void pop_data_delete(pop_data_t **tp);
35 DO_ARRAY_TYPE(pop_data_t, pop_data);
36 DO_ARRAY_FUNCS(pop_data_t, pop_data, pop_data_delete);
37
38 /****************************************************************************/
39 /* module                                                                   */
40 /****************************************************************************/
41
42 static pop_data_array conns;
43
44 static inline pop_data_t *pop_data_new(void) {
45     pop_data_t *res = pop_data_init(p_new(pop_data_t, 1));
46     res->refcnt = 1;
47     pop_data_array_append(&conns, res);
48     return res;
49 }
50 static inline pop_data_t *pop_data_dup(pop_data_t *t) {
51     t->refcnt++;
52     return t;
53 }
54 static void pop_data_delete(pop_data_t **tp) {
55     if (!*tp)
56         return;
57     if (--(*tp)->refcnt > 0) {
58         *tp = NULL;
59     } else {
60         for (int i = 0; i < conns.len; i++) {
61             if (conns.arr[i] == *tp) {
62                 pop_data_array_take(&conns, i);
63                 break;
64             }
65         }
66         pop_data_wipe(*tp);
67         p_delete(tp);
68     }
69 }
70
71 static __init void pop_initialize(void)
72 {
73     pop_data_array_init(&conns);
74 }
75 static __fini void pop_shutdown(void)
76 {
77     pop_data_array_wipe(&conns);
78 }
79
80 /****************************************************************************/
81 /* pop3 machine                                                             */
82 /****************************************************************************/
83
84 static int pop_setup(job_t *w, void *cfg)
85 {
86     w->ptr = cfg;
87     /* FIXME */ return el_job_release(w, EL_ERROR);
88     return 0;
89 }
90
91 static void pop_finalize(job_t *w, el_status reason)
92 {
93     pop_data_delete((pop_data_t **)(void *)&w->ptr);
94 }
95
96 static machine_t const pop_machine = {
97     .name     = "POP3",
98     .setup    = &pop_setup,
99     .finalize = &pop_finalize,
100 };
101
102 /****************************************************************************/
103 /* pop3 mx driver                                                           */
104 /****************************************************************************/
105
106 mx_t const pop_mx_ng = {
107     .type = M_POP,
108 };