1 /*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #ifdef HAVE_CONFIG_H
33 # include <config.h>
34 #endif
35
36 #include "mailimap_extension.h"
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41
42 #include "clist.h"
43 #include "annotatemore.h"
44 #include "acl.h"
45 #include "uidplus.h"
46 #include "quota.h"
47 #include "namespace.h"
48 #include "xlist.h"
49 #include "xgmlabels.h"
50 #include "xgmmsgid.h"
51 #include "xgmthrid.h"
52 #include "mailimap_id.h"
53 #include "enable.h"
54 #include "condstore.h"
55 #include "qresync.h"
56 #include "mailimap_sort.h"
57
58 /*
59 the list of registered extensions (struct mailimap_extension_api *)
60
61 the list of extension is kept as a simple clist.
62 */
63
64 static clist * mailimap_extension_list = NULL;
65
66 static struct mailimap_extension_api * internal_extension_list[] = {
67 &mailimap_extension_annotatemore,
68 &mailimap_extension_acl,
69 &mailimap_extension_uidplus,
70 &mailimap_extension_quota,
71 &mailimap_extension_namespace,
72 &mailimap_extension_xlist,
73 &mailimap_extension_xgmlabels,
74 &mailimap_extension_xgmmsgid,
75 &mailimap_extension_xgmthrid,
76 &mailimap_extension_id,
77 &mailimap_extension_enable,
78 &mailimap_extension_condstore,
79 &mailimap_extension_qresync,
80 &mailimap_extension_sort
81 };
82
83 LIBETPAN_EXPORT
84 int
mailimap_extension_register(struct mailimap_extension_api * extension)85 mailimap_extension_register(struct mailimap_extension_api * extension)
86 {
87 if (mailimap_extension_list == NULL) {
88 mailimap_extension_list = clist_new();
89 if (mailimap_extension_list == NULL)
90 return MAILIMAP_ERROR_MEMORY;
91 }
92
93 return clist_append(mailimap_extension_list, extension);
94 }
95
96 LIBETPAN_EXPORT
97 void
mailimap_extension_unregister_all(void)98 mailimap_extension_unregister_all(void)
99 {
100 clist_free(mailimap_extension_list);
101 mailimap_extension_list = NULL;
102 }
103
104 LIBETPAN_EXPORT
105 int
mailimap_extension_data_parse(int calling_parser,mailstream * fd,MMAPString * buffer,struct mailimap_parser_context * parser_ctx,size_t * indx,struct mailimap_extension_data ** result,size_t progr_rate,progress_function * progr_fun)106 mailimap_extension_data_parse(int calling_parser,
107 mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx,
108 size_t * indx, struct mailimap_extension_data ** result,
109 size_t progr_rate,
110 progress_function * progr_fun)
111 {
112 clistiter * cur;
113 int r;
114 unsigned int i;
115
116 for(i = 0 ; i < sizeof(internal_extension_list) / sizeof(* internal_extension_list) ; i ++) {
117 struct mailimap_extension_api * ext;
118
119 ext = internal_extension_list[i];
120 r = ext->ext_parser(calling_parser, fd, buffer, parser_ctx, indx, result,
121 progr_rate, progr_fun);
122 if (r != MAILIMAP_ERROR_PARSE)
123 return r;
124 }
125
126 if (mailimap_extension_list == NULL)
127 return MAILIMAP_ERROR_PARSE;
128
129 for (cur = clist_begin(mailimap_extension_list);
130 cur != NULL; cur = clist_next(cur)) {
131 struct mailimap_extension_api * ext;
132
133 ext = clist_content(cur);
134 r = ext->ext_parser(calling_parser, fd, buffer, parser_ctx, indx, result,
135 progr_rate, progr_fun);
136 if (r != MAILIMAP_ERROR_PARSE)
137 return r;
138 }
139
140 return MAILIMAP_ERROR_PARSE;
141 }
142
143 LIBETPAN_EXPORT
144 struct mailimap_extension_data *
mailimap_extension_data_new(struct mailimap_extension_api * extension,int type,void * data)145 mailimap_extension_data_new(struct mailimap_extension_api * extension,
146 int type, void * data)
147 {
148 struct mailimap_extension_data * ext_data;
149
150 ext_data = malloc(sizeof(* ext_data));
151 if (ext_data == NULL)
152 return NULL;
153
154 ext_data->ext_extension = extension;
155 ext_data->ext_type = type;
156 ext_data->ext_data = data;
157
158 return ext_data;
159 }
160
161 LIBETPAN_EXPORT
162 void
mailimap_extension_data_free(struct mailimap_extension_data * data)163 mailimap_extension_data_free(struct
164 mailimap_extension_data * data)
165 {
166 if (data == NULL)
167 return;
168
169 if (data->ext_extension != NULL && data->ext_data != NULL)
170 /* ext_free() includes free(data) */
171 data->ext_extension->ext_free(data);
172 else
173 free(data);
174 }
175
mailimap_extension_data_store(mailimap * session,struct mailimap_extension_data ** ext_data)176 void mailimap_extension_data_store(mailimap * session,
177 struct mailimap_extension_data ** ext_data)
178 {
179 int r;
180
181 if (session->imap_response_info) {
182 r = clist_append(session->imap_response_info->rsp_extension_list,
183 * ext_data);
184 if (r == 0)
185 * ext_data = NULL;
186 else {
187 /* TODO must handle error case */
188 }
189 }
190 }
191
192 LIBETPAN_EXPORT
mailimap_has_extension(mailimap * session,const char * extension_name)193 int mailimap_has_extension(mailimap * session, const char * extension_name)
194 {
195 if (session->imap_connection_info != NULL) {
196 if (session->imap_connection_info->imap_capability != NULL) {
197 clist * list;
198 clistiter * cur;
199
200 list = session->imap_connection_info->imap_capability->cap_list;
201 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
202 struct mailimap_capability * cap;
203
204 cap = clist_content(cur);
205 if (cap->cap_type != MAILIMAP_CAPABILITY_NAME)
206 continue;
207
208 if (strcasecmp(cap->cap_data.cap_name, extension_name) == 0)
209 return 1;
210 }
211 }
212 }
213
214 return 0;
215 }
216
217 LIBETPAN_EXPORT
mailimap_has_authentication(mailimap * session,const char * authentication_name)218 int mailimap_has_authentication(mailimap * session, const char * authentication_name)
219 {
220 if (session->imap_connection_info != NULL) {
221 if (session->imap_connection_info->imap_capability != NULL) {
222 clist * list;
223 clistiter * cur;
224
225 list = session->imap_connection_info->imap_capability->cap_list;
226 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
227 struct mailimap_capability * cap;
228
229 cap = clist_content(cur);
230 if (cap->cap_type != MAILIMAP_CAPABILITY_AUTH_TYPE)
231 continue;
232
233 if (strcasecmp(cap->cap_data.cap_name, authentication_name) == 0)
234 return 1;
235
236 }
237 }
238 }
239
240 return 0;
241 }
242