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 /*
33 * $Id: nntpstorage.c,v 1.19 2008/02/17 13:13:27 hoa Exp $
34 */
35
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 #endif
39
40 #include "nntpstorage.h"
41
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "maildriver.h"
46 #include "nntpdriver.h"
47 #include "nntpdriver_cached.h"
48 #include "mailstorage_tools.h"
49 #include "mail.h"
50
51 /* nntp storage */
52
53 #define NNTP_DEFAULT_PORT 119
54 #define NNTPS_DEFAULT_PORT 563
55
56 static int nntp_mailstorage_connect(struct mailstorage * storage);
57 static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
58 char * pathname, mailsession ** result);
59 static void nntp_mailstorage_uninitialize(struct mailstorage * storage);
60
61 static mailstorage_driver nntp_mailstorage_driver = {
62 /* sto_name */ "nntp",
63 /* sto_connect */ nntp_mailstorage_connect,
64 /* sto_get_folder_session */ nntp_mailstorage_get_folder_session,
65 /* sto_uninitialize */ nntp_mailstorage_uninitialize
66 };
67
68 LIBETPAN_EXPORT
nntp_mailstorage_init(struct mailstorage * storage,const char * nntp_servername,uint16_t nntp_port,const char * nntp_command,int nntp_connection_type,int nntp_auth_type,const char * nntp_login,const char * nntp_password,int nntp_cached,const char * nntp_cache_directory,const char * nntp_flags_directory)69 int nntp_mailstorage_init(struct mailstorage * storage,
70 const char * nntp_servername, uint16_t nntp_port,
71 const char * nntp_command,
72 int nntp_connection_type, int nntp_auth_type,
73 const char * nntp_login, const char * nntp_password,
74 int nntp_cached,
75 const char * nntp_cache_directory, const char * nntp_flags_directory)
76 {
77 return nntp_mailstorage_init_with_local_address(storage,
78 nntp_servername, nntp_port,
79 NULL, 0,
80 nntp_command,
81 nntp_connection_type, nntp_auth_type,
82 nntp_login, nntp_password,
83 nntp_cached, nntp_cache_directory,
84 nntp_flags_directory);
85 }
86
87 LIBETPAN_EXPORT
nntp_mailstorage_init_with_local_address(struct mailstorage * storage,const char * nntp_servername,uint16_t nntp_port,const char * nntp_local_address,uint16_t nntp_local_port,const char * nntp_command,int nntp_connection_type,int nntp_auth_type,const char * nntp_login,const char * nntp_password,int nntp_cached,const char * nntp_cache_directory,const char * nntp_flags_directory)88 int nntp_mailstorage_init_with_local_address(struct mailstorage * storage,
89 const char * nntp_servername, uint16_t nntp_port,
90 const char * nntp_local_address, uint16_t nntp_local_port,
91 const char * nntp_command,
92 int nntp_connection_type, int nntp_auth_type,
93 const char * nntp_login, const char * nntp_password,
94 int nntp_cached, const char * nntp_cache_directory,
95 const char * nntp_flags_directory)
96 {
97 struct nntp_mailstorage * nntp_storage;
98 int res;
99
100 nntp_storage = malloc(sizeof(* nntp_storage));
101 if (nntp_storage == NULL) {
102 res = MAIL_ERROR_MEMORY;
103 goto err;
104 }
105
106 if (nntp_servername != NULL) {
107 nntp_storage->nntp_servername = strdup(nntp_servername);
108 if (nntp_storage->nntp_servername == NULL) {
109 res = MAIL_ERROR_MEMORY;
110 goto free;
111 }
112 }
113 else {
114 nntp_storage->nntp_servername = NULL;
115 }
116
117 if (nntp_local_address != NULL) {
118 nntp_storage->nntp_local_address = strdup(nntp_local_address);
119 if (nntp_storage->nntp_local_address == NULL) {
120 res = MAIL_ERROR_MEMORY;
121 goto free_servername;
122 }
123 }
124 else {
125 nntp_storage->nntp_local_address = NULL;
126 }
127
128 nntp_storage->nntp_local_port = nntp_local_port;
129
130 nntp_storage->nntp_connection_type = nntp_connection_type;
131
132 if (nntp_port == 0) {
133 switch (nntp_connection_type) {
134 case CONNECTION_TYPE_PLAIN:
135 case CONNECTION_TYPE_COMMAND:
136 nntp_port = NNTP_DEFAULT_PORT;
137 break;
138
139 case CONNECTION_TYPE_TLS:
140 case CONNECTION_TYPE_COMMAND_TLS:
141 nntp_port = NNTPS_DEFAULT_PORT;
142 break;
143
144 default:
145 nntp_port = NNTP_DEFAULT_PORT;
146 break;
147 }
148 }
149
150 nntp_storage->nntp_port = nntp_port;
151
152 if (nntp_command != NULL) {
153 nntp_storage->nntp_command = strdup(nntp_command);
154 if (nntp_storage->nntp_command == NULL) {
155 res = MAIL_ERROR_MEMORY;
156 goto free_local_address;
157 }
158 }
159 else
160 nntp_storage->nntp_command = NULL;
161
162 nntp_storage->nntp_auth_type = nntp_auth_type;
163
164 if (nntp_login != NULL) {
165 nntp_storage->nntp_login = strdup(nntp_login);
166 if (nntp_storage->nntp_login == NULL) {
167 res = MAIL_ERROR_MEMORY;
168 goto free_command;
169 }
170 }
171 else
172 nntp_storage->nntp_login = NULL;
173
174 if (nntp_password != NULL) {
175 nntp_storage->nntp_password = strdup(nntp_password);
176 if (nntp_storage->nntp_password == NULL) {
177 res = MAIL_ERROR_MEMORY;
178 goto free_login;
179 }
180 }
181 else
182 nntp_storage->nntp_password = NULL;
183
184 nntp_storage->nntp_cached = nntp_cached;
185
186 if (nntp_cached && (nntp_cache_directory != NULL) &&
187 (nntp_flags_directory != NULL)) {
188 nntp_storage->nntp_cache_directory = strdup(nntp_cache_directory);
189 if (nntp_storage->nntp_cache_directory == NULL) {
190 res = MAIL_ERROR_MEMORY;
191 goto free_password;
192 }
193 nntp_storage->nntp_flags_directory = strdup(nntp_flags_directory);
194 if (nntp_storage->nntp_flags_directory == NULL) {
195 res = MAIL_ERROR_MEMORY;
196 goto free_cache_directory;
197 }
198 }
199 else {
200 nntp_storage->nntp_cached = FALSE;
201 nntp_storage->nntp_cache_directory = NULL;
202 nntp_storage->nntp_flags_directory = NULL;
203 }
204
205 storage->sto_data = nntp_storage;
206 storage->sto_driver = &nntp_mailstorage_driver;
207
208 return MAIL_NO_ERROR;
209
210 free_cache_directory:
211 free(nntp_storage->nntp_cache_directory);
212 free_password:
213 free(nntp_storage->nntp_password);
214 free_login:
215 free(nntp_storage->nntp_login);
216 free_command:
217 free(nntp_storage->nntp_command);
218 free_local_address:
219 free(nntp_storage->nntp_local_address);
220 free_servername:
221 free(nntp_storage->nntp_servername);
222 free:
223 free(nntp_storage);
224 err:
225 return res;
226 }
227
nntp_mailstorage_uninitialize(struct mailstorage * storage)228 static void nntp_mailstorage_uninitialize(struct mailstorage * storage)
229 {
230 struct nntp_mailstorage * nntp_storage;
231
232 nntp_storage = storage->sto_data;
233
234 free(nntp_storage->nntp_flags_directory);
235 free(nntp_storage->nntp_cache_directory);
236 free(nntp_storage->nntp_password);
237 free(nntp_storage->nntp_login);
238 free(nntp_storage->nntp_command);
239 free(nntp_storage->nntp_local_address);
240 free(nntp_storage->nntp_servername);
241 free(nntp_storage);
242
243 storage->sto_data = NULL;
244 }
245
nntp_mailstorage_connect(struct mailstorage * storage)246 static int nntp_mailstorage_connect(struct mailstorage * storage)
247 {
248 struct nntp_mailstorage * nntp_storage;
249 mailsession_driver * driver;
250 int r;
251 int res;
252 mailsession * session;
253
254 nntp_storage = storage->sto_data;
255
256 if (nntp_storage->nntp_cached)
257 driver = nntp_cached_session_driver;
258 else
259 driver = nntp_session_driver;
260
261 r = mailstorage_generic_connect_with_local_address(driver,
262 nntp_storage->nntp_servername, nntp_storage->nntp_port,
263 nntp_storage->nntp_local_address, nntp_storage->nntp_local_port,
264 nntp_storage->nntp_command,
265 nntp_storage->nntp_connection_type,
266 NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
267 nntp_storage->nntp_cache_directory,
268 NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
269 nntp_storage->nntp_flags_directory,
270 &session);
271 switch (r) {
272 case MAIL_NO_ERROR_NON_AUTHENTICATED:
273 case MAIL_NO_ERROR_AUTHENTICATED:
274 case MAIL_NO_ERROR:
275 break;
276 default:
277 res = r;
278 goto err;
279 }
280
281 r = mailstorage_generic_auth(session, r,
282 nntp_storage->nntp_connection_type,
283 nntp_storage->nntp_login,
284 nntp_storage->nntp_password);
285 if (r != MAIL_NO_ERROR) {
286 res = r;
287 goto free;
288 }
289
290 storage->sto_session = session;
291
292 return MAIL_NO_ERROR;
293
294 free:
295 mailsession_free(session);
296 err:
297 return res;
298 }
299
nntp_mailstorage_get_folder_session(struct mailstorage * storage,char * pathname,mailsession ** result)300 static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
301 char * pathname, mailsession ** result)
302 {
303 mailsession_select_folder(storage->sto_session, pathname);
304
305 * result = storage->sto_session;
306
307 return MAIL_NO_ERROR;
308 }
309