summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/tests
Unidiff
Diffstat (limited to 'kmicromail/libetpan/tests') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/tests/README58
-rw-r--r--kmicromail/libetpan/tests/compose-msg.c317
-rw-r--r--kmicromail/libetpan/tests/fetch-attachment.c274
-rw-r--r--kmicromail/libetpan/tests/frm-common.c158
-rw-r--r--kmicromail/libetpan/tests/frm-common.h14
-rw-r--r--kmicromail/libetpan/tests/frm-simple.c227
-rw-r--r--kmicromail/libetpan/tests/frm-tree.c234
-rw-r--r--kmicromail/libetpan/tests/frm.c158
-rw-r--r--kmicromail/libetpan/tests/option-parser.c234
-rw-r--r--kmicromail/libetpan/tests/option-parser.h28
-rw-r--r--kmicromail/libetpan/tests/readmsg-common.c720
-rw-r--r--kmicromail/libetpan/tests/readmsg-common.h34
-rw-r--r--kmicromail/libetpan/tests/readmsg-simple.c133
-rw-r--r--kmicromail/libetpan/tests/readmsg.c355
-rw-r--r--kmicromail/libetpan/tests/smtpsend.c278
15 files changed, 3222 insertions, 0 deletions
diff --git a/kmicromail/libetpan/tests/README b/kmicromail/libetpan/tests/README
new file mode 100644
index 0000000..66d8b2f
--- a/dev/null
+++ b/kmicromail/libetpan/tests/README
@@ -0,0 +1,58 @@
1compose-msg
2-----------
3
4creates a RFC 2822 message with MIME parts
5
6syntax: compose-msg "text" filename
7
8
9
10all the following programs will take as argument :
11
12 --driver=(pop3|imap|nntp|mbox|mh) -d pop3 (pop3|imap|nntp|mbox|mh)
13
14 default driver is mbox
15
16 --server={server-name} -s {server-name}
17 --port={port-number} -p {port-number}
18 --tls -t
19 --starttls -x
20 --user={login} -u {login}
21 --password={password} -v {password}
22 --path={mailbox} -l {mailbox}
23 --apop -a
24 --cache={directory} -c {directory}
25
26the default driver is mbox with the path /var/mail/$USER
27
28frm-simple, frm, frm-tree
29-------------------------
30
31frm-simple will list all the mails of a mailbox without any MIME decoding.
32
33frm will list all the mails of a mailbox and will decode the fields.
34
35frm-tree will do the same thing as frm and will also show the threads
36 of the folder.
37
38
39fetch-attachment
40----------------
41
42 fetch-attachment gets all the named attachment of the given message
43of the chosen mailbox and writes them on the current directory.
44
45 The program should be given message numbers (as given by frm) as
46additionnal arguments.
47
48
49readmsg-simple, readmsg
50-----------------------
51
52 readmsg-simple will display the content of the given messages.
53All the content (headers and body) will be displayed.
54
55 readmsg will display only the text parts of the given messages.
56
57 The program should be given message numbers (as given by frm) as
58additionnal arguments.
diff --git a/kmicromail/libetpan/tests/compose-msg.c b/kmicromail/libetpan/tests/compose-msg.c
new file mode 100644
index 0000000..f68660b
--- a/dev/null
+++ b/kmicromail/libetpan/tests/compose-msg.c
@@ -0,0 +1,317 @@
1#include <libetpan/libetpan.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define DEST_CHARSET "iso-8859-1"
6
7/* build a mime parameter */
8
9static struct mailmime_parameter *
10mailmime_param_new_with_data(char * name, char * value)
11{
12 char * param_name;
13 char * param_value;
14 struct mailmime_parameter * param;
15
16 param_name = strdup(name);
17 if (param_name == NULL)
18 goto err;
19
20 param_value = strdup(value);
21 if (param_value == NULL)
22 goto free_name;
23
24 param = mailmime_parameter_new(param_name, param_value);
25 if (param == NULL)
26 goto free_value;
27
28 return param;
29
30 free_value:
31 free(param_value);
32 free_name:
33 free(param_name);
34 err:
35 return NULL;
36}
37
38
39/* build sample fields */
40
41static struct mailimf_fields * build_fields(void)
42{
43 struct mailimf_mailbox_list * from;
44 struct mailimf_address_list * to;
45 char * subject;
46 int r;
47 struct mailimf_fields * new_fields;
48
49 /* subject field */
50
51 subject = strdup("this is a sample");
52 if (subject == NULL) {
53 goto err;
54 }
55
56 /* from field */
57
58 from = mailimf_mailbox_list_new_empty();
59 if (from == NULL) {
60 goto free_subject;
61 }
62
63 r = mailimf_mailbox_list_add_parse(from,
64 "DINH Viet Hoa <hoa@sourceforge.net>");
65 if (r != MAILIMF_NO_ERROR) {
66 goto free_from;
67 }
68
69 /* to field */
70
71 to = mailimf_address_list_new_empty();
72 if (to == NULL) {
73 goto free_from;
74 }
75
76 r = mailimf_address_list_add_parse(to,
77 "Paul <claws@thewildbeast.co.uk>");
78 if (r != MAILIMF_NO_ERROR) {
79 goto free_to;
80 }
81
82 new_fields = mailimf_fields_new_with_data(from /* from */,
83 NULL /* sender */, NULL /* reply-to */,
84 to, NULL /* cc */, NULL /* bcc */, NULL /* in-reply-to */,
85 NULL /* references */,
86 subject);
87 if (new_fields == NULL)
88 goto free_to;
89
90 return new_fields;
91
92 free_to:
93 mailimf_address_list_free(to);
94 free_from:
95 mailimf_mailbox_list_free(from);
96 free_subject:
97 free(subject);
98 err:
99 return NULL;
100}
101
102
103
104/* text is a string, build a mime part containing this string */
105
106static struct mailmime * build_body_text(char * text)
107{
108 struct mailmime_fields * mime_fields;
109 struct mailmime * mime_sub;
110 struct mailmime_content * content;
111 struct mailmime_parameter * param;
112 int r;
113
114 /* text/plain part */
115
116 mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
117 if (mime_fields == NULL) {
118 goto err;
119 }
120
121 content = mailmime_content_new_with_str("text/plain");
122 if (content == NULL) {
123 goto free_fields;
124 }
125
126 param = mailmime_param_new_with_data("charset", DEST_CHARSET);
127 if (param == NULL) {
128 goto free_content;
129 }
130
131 r = clist_append(content->ct_parameters, param);
132 if (r < 0) {
133 mailmime_parameter_free(param);
134 goto free_content;
135 }
136
137 mime_sub = mailmime_new_empty(content, mime_fields);
138 if (mime_sub == NULL) {
139 goto free_content;
140 }
141
142 r = mailmime_set_body_text(mime_sub, text, strlen(text));
143 if (r != MAILIMF_NO_ERROR) {
144 goto free_mime;
145 }
146
147 return mime_sub;
148
149 free_mime:
150 mailmime_free(mime_sub);
151 goto err;
152 free_content:
153 mailmime_content_free(content);
154 free_fields:
155 mailmime_fields_free(mime_fields);
156 err:
157 return NULL;
158}
159
160
161/* build a mime part containing the given file */
162
163static struct mailmime * build_body_file(char * filename)
164{
165 struct mailmime_fields * mime_fields;
166 struct mailmime * mime_sub;
167 struct mailmime_content * content;
168 struct mailmime_parameter * param;
169 char * dup_filename;
170 int r;
171
172 /* text/plain part */
173
174 dup_filename = strdup(filename);
175 if (dup_filename == NULL)
176 goto err;
177
178 mime_fields =
179 mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
180 dup_filename, MAILMIME_MECHANISM_BASE64);
181 if (mime_fields == NULL)
182 goto free_dup_filename;
183
184 content = mailmime_content_new_with_str("text/plain");
185 if (content == NULL) {
186 goto free_fields;
187 }
188
189 param = mailmime_param_new_with_data("charset", DEST_CHARSET);
190 if (param == NULL) {
191 goto free_content;
192 }
193
194 r = clist_append(content->ct_parameters, param);
195 if (r < 0) {
196 mailmime_parameter_free(param);
197 goto free_content;
198 }
199
200 mime_sub = mailmime_new_empty(content, mime_fields);
201 if (mime_sub == NULL) {
202 goto free_content;
203 }
204
205 dup_filename = strdup(filename);
206 if (dup_filename == NULL)
207 goto free_mime;
208
209 r = mailmime_set_body_file(mime_sub, dup_filename);
210 if (r != MAILIMF_NO_ERROR) {
211 goto free_mime;
212 }
213
214 return mime_sub;
215
216 free_mime:
217 mailmime_free(mime_sub);
218 goto err;
219 free_content:
220 mailmime_content_free(content);
221 free_fields:
222 mailmime_fields_free(mime_fields);
223 goto err;
224 free_dup_filename:
225 free(dup_filename);
226 err:
227 return NULL;
228}
229
230
231/* build an empty message */
232
233static struct mailmime * build_message(struct mailimf_fields * fields)
234{
235 struct mailmime * mime;
236
237 /* message */
238
239 mime = mailmime_new_message_data(NULL);
240 if (mime == NULL) {
241 goto err;
242 }
243
244 mailmime_set_imf_fields(mime, fields);
245
246 return mime;
247
248 err:
249 return NULL;
250}
251
252
253int main(int argc, char ** argv)
254{
255 struct mailimf_fields * fields;
256 char * text;
257 char * filename;
258 struct mailmime * message;
259 struct mailmime * text_part;
260 struct mailmime * file_part;
261 int r;
262 int col;
263
264 if (argc < 3) {
265 printf("syntax: compose-msg \"text\" filename\n");
266 return 1;
267 }
268
269 fields = build_fields();
270 if (fields == NULL)
271 goto err;
272
273 message = build_message(fields);
274 if (message == NULL)
275 goto free_fields;
276
277 text = argv[1];
278 text_part = build_body_text(text);
279 if (text_part == NULL)
280 goto free_message;
281
282 filename = argv[2];
283 file_part = build_body_file(filename);
284 if (file_part == NULL)
285 goto free_text;
286
287 r = mailmime_smart_add_part(message, text_part);
288 if (r != MAILIMF_NO_ERROR)
289 goto free_file;
290
291 r = mailmime_smart_add_part(message, file_part);
292 if (r != MAILIMF_NO_ERROR)
293 goto free_file_alone;
294
295 col = 0;
296 mailmime_write(stdout, &col, message);
297
298 mailmime_free(message);
299
300 return 0;
301
302 free_file_alone:
303 mailmime_free(file_part);
304 goto free_text;
305 free_file:
306 mailmime_free(file_part);
307 free_text:
308 mailmime_free(text_part);
309 free_message:
310 mailmime_free(message);
311 goto err;
312 free_fields:
313 mailimf_fields_free(fields);
314 err:
315 printf("error memory\n");
316 return 1;
317}
diff --git a/kmicromail/libetpan/tests/fetch-attachment.c b/kmicromail/libetpan/tests/fetch-attachment.c
new file mode 100644
index 0000000..a79ef8b
--- a/dev/null
+++ b/kmicromail/libetpan/tests/fetch-attachment.c
@@ -0,0 +1,274 @@
1#include <unistd.h>
2#include <string.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6
7#include <libetpan/libetpan.h>
8
9#include "option-parser.h"
10#include "readmsg-common.h"
11
12/* write content to the given filename */
13
14static int etpan_write_data(char * filename, char * data, size_t len)
15{
16 size_t write_len;
17 FILE * f;
18 int res;
19 mode_t old_umask;
20
21 old_umask = umask(0077);
22 f = fopen(filename, "w");
23 umask(old_umask);
24 if (f == NULL) {
25 res = ERROR_FILE;
26 goto err;
27 }
28
29 write_len = fwrite(data, 1, len, f);
30 if (write_len < len) {
31 res = ERROR_FILE;
32 goto close;
33 }
34
35 fclose(f);
36
37 return NO_ERROR;
38
39 close:
40 fclose(f);
41 err:
42 return res;
43}
44
45
46/* save attachment */
47
48static int save_mime_content(mailmessage * msg_info,
49 struct mailmime * mime_part)
50{
51 char * body;
52 size_t body_len;
53 int r;
54 char * filename;
55 struct mailmime_single_fields fields;
56 int res;
57
58 memset(&fields, 0, sizeof(struct mailmime_single_fields));
59 if (mime_part->mm_mime_fields != NULL)
60 mailmime_single_fields_init(&fields, mime_part->mm_mime_fields,
61 mime_part->mm_content_type);
62
63 filename = fields.fld_disposition_filename;
64
65 if (filename == NULL)
66 filename = fields.fld_content_name;
67
68 if (filename == NULL)
69 return ERROR_INVAL;
70
71 r = etpan_fetch_message(msg_info, mime_part, &fields, &body, &body_len);
72 if (r != NO_ERROR) {
73 res = r;
74 goto err;
75 }
76
77 printf("writing %s, %i bytes\n", filename, body_len);
78
79 r = etpan_write_data(filename, body, body_len);
80 if (r != NO_ERROR) {
81 res = r;
82 goto free;
83 }
84
85 mailmime_decoded_part_free(body);
86
87 return NO_ERROR;
88
89 free:
90 mailmime_decoded_part_free(body);
91 err:
92 return res;
93}
94
95
96
97/* fetch attachments */
98
99static int etpan_fetch_mime(FILE * f, mailmessage * msg_info,
100 struct mailmime * mime)
101{
102 int r;
103 clistiter * cur;
104 struct mailmime_single_fields fields;
105 int res;
106
107 memset(&fields, 0, sizeof(struct mailmime_single_fields));
108 if (mime->mm_mime_fields != NULL)
109 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
110 mime->mm_content_type);
111
112 switch(mime->mm_type) {
113 case MAILMIME_SINGLE:
114 save_mime_content(msg_info, mime);
115
116 break;
117
118 case MAILMIME_MULTIPLE:
119
120 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
121 cur != NULL ; cur = clist_next(cur)) {
122
123 r = etpan_fetch_mime(f, msg_info, clist_content(cur));
124 if (r != NO_ERROR) {
125 res = r;
126 goto err;
127 }
128 }
129
130 break;
131
132 case MAILMIME_MESSAGE:
133
134 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
135 r = etpan_fetch_mime(f, msg_info, mime->mm_data.mm_message.mm_msg_mime);
136 if (r != NO_ERROR) {
137 res = r;
138 goto err;
139 }
140 }
141
142 break;
143 }
144
145 return NO_ERROR;
146
147 err:
148 return res;
149}
150
151
152int main(int argc, char ** argv)
153{
154 int r;
155 int driver;
156 char * server;
157 int port;
158 int connection_type;
159 char * user;
160 char * password;
161 int auth_type;
162 char * path;
163 char * cache_directory;
164 char * flags_directory;
165 struct mailstorage * storage;
166 int cached;
167 struct mailfolder * folder;
168
169 /* get options */
170
171 r = parse_options(argc, argv,
172 &driver, &server, &port, &connection_type,
173 &user, &password, &auth_type,
174 &path, &cache_directory, &flags_directory);
175
176 cached = (cache_directory != NULL);
177
178 /* build the storage structure */
179
180 storage = mailstorage_new(NULL);
181 if (storage == NULL) {
182 printf("error initializing storage\n");
183 goto free_opt;
184 }
185
186 r = init_storage(storage, driver, server, port, connection_type,
187 user, password, auth_type, path, cache_directory, flags_directory);
188 if (r != MAIL_NO_ERROR) {
189 printf("error initializing storage\n");
190 goto free_opt;
191 }
192
193 /* get the folder structure */
194
195 folder = mailfolder_new(storage, path, NULL);
196 if (folder == NULL) {
197 printf("error initializing folder\n");
198 goto free_storage;
199 }
200
201 r = mailfolder_connect(folder);
202 if (r != MAIL_NO_ERROR) {
203 printf("error initializing folder\n");
204 goto free_folder;
205 }
206
207 while (optind < argc) {
208 mailmessage * msg;
209 uint32_t msg_num;
210 struct mailmime * mime;
211
212 msg_num = strtoul(argv[optind], NULL, 10);
213
214 r = mailsession_get_message(folder->fld_session, msg_num, &msg);
215 if (r != MAIL_NO_ERROR) {
216 printf("** message %i not found ** - %s\n", msg_num,
217 maildriver_strerror(r));
218 optind ++;
219 continue;
220 }
221
222 r = mailmessage_get_bodystructure(msg, &mime);
223 if (r != MAIL_NO_ERROR) {
224 printf("** message %i not found - %s **\n", msg_num,
225 maildriver_strerror(r));
226 mailmessage_free(msg);
227 optind ++;
228 continue;
229 }
230
231 r = etpan_fetch_mime(stdout, msg, mime);
232
233 mailmessage_free(msg);
234
235 optind ++;
236 }
237
238 mailfolder_free(folder);
239 mailstorage_free(storage);
240
241 if (server != NULL)
242 free(server);
243 if (user != NULL)
244 free(user);
245 if (password != NULL)
246 free(password);
247 if (path != NULL)
248 free(path);
249 if (cache_directory != NULL)
250 free(cache_directory);
251 if (flags_directory != NULL)
252 free(flags_directory);
253
254 return 0;
255
256 free_folder:
257 mailfolder_free(folder);
258 free_storage:
259 mailstorage_free(storage);
260 free_opt:
261 if (server != NULL)
262 free(server);
263 if (user != NULL)
264 free(user);
265 if (password != NULL)
266 free(password);
267 if (path != NULL)
268 free(path);
269 if (cache_directory != NULL)
270 free(cache_directory);
271 if (flags_directory != NULL)
272 free(flags_directory);
273 return -1;
274}
diff --git a/kmicromail/libetpan/tests/frm-common.c b/kmicromail/libetpan/tests/frm-common.c
new file mode 100644
index 0000000..eeeadf0
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-common.c
@@ -0,0 +1,158 @@
1#include "frm-common.h"
2
3#include <string.h>
4#include <stdlib.h>
5
6#define DEST_CHARSET "iso-8859-1"
7
8/* get part of the from field to display */
9
10void get_from_value(struct mailimf_single_fields * fields,
11 char ** from, int * is_addr)
12{
13 struct mailimf_mailbox * mb;
14
15 if (fields->fld_from == NULL) {
16 * from = NULL;
17 * is_addr = 0;
18 return;
19 }
20
21 if (clist_isempty(fields->fld_from->frm_mb_list->mb_list)) {
22 * from = NULL;
23 * is_addr = 0;
24 return;
25 }
26
27 mb = clist_begin(fields->fld_from->frm_mb_list->mb_list)->data;
28
29 if (mb->mb_display_name != NULL) {
30 * from = mb->mb_display_name;
31 * is_addr = 0;
32 }
33 else {
34 * from = mb->mb_addr_spec;
35 * is_addr = 1;
36 }
37}
38
39/* remove all CR and LF of a string and replace them with SP */
40
41void strip_crlf(char * str)
42{
43 char * p;
44
45 for(p = str ; * p != '\0' ; p ++) {
46 if ((* p == '\n') || (* p == '\r'))
47 * p = ' ';
48 }
49}
50
51#define MAX_OUTPUT 81
52
53/* display information for one message */
54
55void print_mail_info(char * prefix, mailmessage * msg)
56{
57 char * from;
58 char * subject;
59 char * decoded_from;
60 char * decoded_subject;
61 size_t cur_token;
62 int r;
63 int is_addr;
64 char * dsp_from;
65 char * dsp_subject;
66 char output[MAX_OUTPUT];
67 struct mailimf_single_fields single_fields;
68
69 is_addr = 0;
70 from = NULL;
71 subject = NULL;
72
73 decoded_subject = NULL;
74 decoded_from = NULL;
75
76 /* from field */
77
78 if (msg->msg_fields != NULL)
79 mailimf_single_fields_init(&single_fields, msg->msg_fields);
80 else
81 memset(&single_fields, 0, sizeof(single_fields));
82
83 get_from_value(&single_fields, &from, &is_addr);
84
85 if (from == NULL)
86 decoded_from = NULL;
87 else {
88 if (!is_addr) {
89 cur_token = 0;
90 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
91 from, strlen(from),
92 &cur_token, DEST_CHARSET,
93 &decoded_from);
94 if (r != MAILIMF_NO_ERROR) {
95 decoded_from = strdup(from);
96 if (decoded_from == NULL)
97 goto err;
98 }
99 }
100 else {
101 decoded_from = strdup(from);
102 if (decoded_from == NULL) {
103 goto err;
104 }
105 }
106 }
107
108 if (decoded_from == NULL)
109 dsp_from = "";
110 else {
111 dsp_from = decoded_from;
112 strip_crlf(dsp_from);
113 }
114
115 /* subject */
116
117 if (single_fields.fld_subject != NULL)
118 subject = single_fields.fld_subject->sbj_value;
119
120 if (subject == NULL)
121 decoded_subject = NULL;
122 else {
123 cur_token = 0;
124 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
125 subject, strlen(subject),
126 &cur_token, DEST_CHARSET,
127 &decoded_subject);
128 if (r != MAILIMF_NO_ERROR) {
129 decoded_subject = strdup(subject);
130 if (decoded_subject == NULL)
131 goto free_from;
132 }
133 }
134
135 if (decoded_subject == NULL)
136 dsp_subject = "";
137 else {
138 dsp_subject = decoded_subject;
139 strip_crlf(dsp_subject);
140 }
141
142 snprintf(output, MAX_OUTPUT, "%3i: %-21.21s %s%-53.53s",
143 msg->msg_index, dsp_from, prefix, dsp_subject);
144
145 printf("%s\n", output);
146
147 if (decoded_subject != NULL)
148 free(decoded_subject);
149 if (decoded_from != NULL)
150 free(decoded_from);
151
152 return;
153
154 free_from:
155 if (decoded_from)
156 free(decoded_from);
157 err:
158}
diff --git a/kmicromail/libetpan/tests/frm-common.h b/kmicromail/libetpan/tests/frm-common.h
new file mode 100644
index 0000000..c1a27c2
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-common.h
@@ -0,0 +1,14 @@
1#ifndef FRM_COMMON_H
2
3#define FRM_COMMON_H
4
5#include <libetpan/libetpan.h>
6
7void get_from_value(struct mailimf_single_fields * fields,
8 char ** from, int * is_addr);
9
10void strip_crlf(char * str);
11
12void print_mail_info(char * prefix, mailmessage * msg);
13
14#endif
diff --git a/kmicromail/libetpan/tests/frm-simple.c b/kmicromail/libetpan/tests/frm-simple.c
new file mode 100644
index 0000000..7c3640f
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-simple.c
@@ -0,0 +1,227 @@
1#include "option-parser.h"
2#include "frm-common.h"
3
4#include <libetpan/libetpan.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9#define DEST_CHARSET "iso-8859-1"
10
11#define MAX_OUTPUT 81
12
13/* display information for one message */
14
15static void simple_print_mail_info(mailmessage * msg)
16{
17 char * from;
18 char * subject;
19 int is_addr;
20 char * dsp_from;
21 char * dsp_subject;
22 char output[MAX_OUTPUT];
23 struct mailimf_single_fields single_fields;
24
25 is_addr = 0;
26 from = NULL;
27 subject = NULL;
28
29 if (msg->msg_fields != NULL)
30 mailimf_single_fields_init(&single_fields, msg->msg_fields);
31 else
32 memset(&single_fields, 0, sizeof(single_fields));
33
34 /* from field */
35
36 get_from_value(&single_fields, &from, &is_addr);
37
38 if (from == NULL)
39 dsp_from = strdup("");
40 else
41 dsp_from = strdup(from);
42 if (dsp_from == NULL)
43 goto err;
44
45 strip_crlf(dsp_from);
46
47 /* subject */
48
49 if (single_fields.fld_subject != NULL)
50 subject = single_fields.fld_subject->sbj_value;
51
52 if (subject == NULL)
53 dsp_subject = strdup("");
54 else
55 dsp_subject = strdup(subject);
56
57 if (dsp_subject == NULL)
58 goto free_from;
59
60 strip_crlf(dsp_subject);
61
62 snprintf(output, MAX_OUTPUT, "%3i: %-21.21s %-53.53s\n",
63 msg->msg_index % 1000, dsp_from, dsp_subject);
64
65 printf("%s\n", output);
66
67 free(dsp_subject);
68 free(dsp_from);
69
70 return;
71
72 free_from:
73 free(dsp_from);
74 err:
75}
76
77/* get the message list and display it */
78
79static void print_message_list(mailsession * session)
80{
81 int r;
82 uint32_t i;
83 struct mailmessage_list * env_list;
84 unsigned int count;
85
86 /* get the list of messages numbers of the folder */
87
88 r = mailsession_get_messages_list(session, &env_list);
89 if (r != MAIL_NO_ERROR) {
90 printf("error message list\n");
91 goto err;
92 }
93
94 /* get fields content of these messages */
95
96 r = mailsession_get_envelopes_list(session, env_list);
97 if (r != MAIL_NO_ERROR) {
98 printf("error envelopes list\n");
99 goto free_msg_list;
100 }
101
102 /* display all the messages */
103
104 count = 0;
105 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
106 mailmessage * msg;
107
108 msg = carray_get(env_list->msg_tab, i);
109
110 if (msg->msg_fields == NULL) {
111 printf("could not fetch envelope of message %i\n", i);
112 }
113 else {
114 simple_print_mail_info(msg);
115 count ++;
116 }
117 }
118 printf(" %i messages\n", count);
119
120 /* free structure */
121
122 mailmessage_list_free(env_list);
123
124 return;
125
126 free_msg_list:
127 mailmessage_list_free(env_list);
128 err:
129}
130
131int main(int argc, char ** argv)
132{
133 int r;
134 int driver;
135 char * server;
136 int port;
137 int connection_type;
138 char * user;
139 char * password;
140 int auth_type;
141 char * path;
142 char * cache_directory;
143 char * flags_directory;
144 struct mailstorage * storage;
145 int cached;
146 struct mailfolder * folder;
147
148 /* get options */
149
150 r = parse_options(argc, argv,
151 &driver, &server, &port, &connection_type,
152 &user, &password, &auth_type,
153 &path, &cache_directory, &flags_directory);
154
155 cached = (cache_directory != NULL);
156
157 /* build the storage structure */
158
159 storage = mailstorage_new(NULL);
160 if (storage == NULL) {
161 printf("error initializing storage\n");
162 goto free_opt;
163 }
164
165 r = init_storage(storage, driver, server, port, connection_type,
166 user, password, auth_type, path, cache_directory, flags_directory);
167 if (r != MAIL_NO_ERROR) {
168 printf("error initializing storage\n");
169 goto free_opt;
170 }
171
172 /* get the folder structure */
173
174 folder = mailfolder_new(storage, path, NULL);
175 if (folder == NULL) {
176 printf("error initializing folder\n");
177 goto free_storage;
178 }
179
180 r = mailfolder_connect(folder);
181 if (r != MAIL_NO_ERROR) {
182 printf("error initializing folder\n");
183 goto free_folder;
184 }
185
186 /* get and display the list of messages */
187
188 print_message_list(folder->fld_session);
189
190 mailfolder_free(folder);
191 mailstorage_free(storage);
192
193 if (server != NULL)
194 free(server);
195 if (user != NULL)
196 free(user);
197 if (password != NULL)
198 free(password);
199 if (path != NULL)
200 free(path);
201 if (cache_directory != NULL)
202 free(cache_directory);
203 if (flags_directory != NULL)
204 free(flags_directory);
205
206 return 0;
207
208 free_folder:
209 mailfolder_free(folder);
210 free_storage:
211 mailstorage_free(storage);
212 free_opt:
213 if (server != NULL)
214 free(server);
215 if (user != NULL)
216 free(user);
217 if (password != NULL)
218 free(password);
219 if (path != NULL)
220 free(path);
221 if (cache_directory != NULL)
222 free(cache_directory);
223 if (flags_directory != NULL)
224 free(flags_directory);
225 return -1;
226}
227
diff --git a/kmicromail/libetpan/tests/frm-tree.c b/kmicromail/libetpan/tests/frm-tree.c
new file mode 100644
index 0000000..3a8464a
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm-tree.c
@@ -0,0 +1,234 @@
1#include "option-parser.h"
2#include "frm-common.h"
3
4#include <libetpan/libetpan.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9#define DEST_CHARSET "iso-8859-1"
10
11/* display tree */
12
13static void
14display_sub_tree(MMAPString * prefix,
15 struct mailmessage_tree * msg_tree,
16 int level, int has_next, unsigned int * pcount)
17{
18 carray * list;
19 uint32_t cur;
20
21 if (msg_tree->node_msg != NULL) {
22 print_mail_info(prefix->str, msg_tree->node_msg);
23 (* pcount) ++;
24 }
25
26 list = msg_tree->node_children;
27
28 if (carray_count(list) != 0) {
29 char old_prefix[2];
30
31 if (level > 1) {
32 memcpy(old_prefix, prefix->str + prefix->len - 2, 2);
33 if (has_next)
34 memcpy(prefix->str + prefix->len - 2, "| ", 2);
35 else
36 memcpy(prefix->str + prefix->len - 2, " ", 2);
37 }
38 for(cur = 0 ; cur < carray_count(list) ; cur ++) {
39 int sub_has_next;
40
41 if (cur != carray_count(list) - 1) {
42 if (level > 0) {
43 if (mmap_string_append(prefix, "+-") == NULL)
44 return;
45 }
46 sub_has_next = 1;
47 }
48 else {
49 if (level > 0) {
50 if (mmap_string_append(prefix, "\\-") == NULL)
51 return;
52 }
53 sub_has_next = 0;
54 }
55
56 display_sub_tree(prefix, carray_get(list, cur),
57 level + 1, sub_has_next, pcount);
58
59 if (mmap_string_truncate(prefix, prefix->len - 2) == NULL) {
60 return;
61 }
62 }
63 if (level > 1) {
64 memcpy(prefix->str + prefix->len - 2, old_prefix, 2);
65 }
66 }
67}
68
69static void display_tree(struct mailmessage_tree * env_tree,
70 unsigned int * pcount)
71{
72 MMAPString * prefix;
73
74 prefix = mmap_string_new("");
75 if (prefix == NULL)
76 return;
77
78 display_sub_tree(prefix, env_tree, 0, 0, pcount);
79
80 mmap_string_free(prefix);
81}
82
83/* get the message list and display it */
84
85static void print_message_list(mailsession * session)
86{
87 int r;
88 struct mailmessage_list * env_list;
89 struct mailmessage_tree * env_tree;
90 unsigned int count;
91
92 /* get the list of messages numbers of the folder */
93
94 r = mailsession_get_messages_list(session, &env_list);
95 if (r != MAIL_NO_ERROR) {
96 printf("error message list\n");
97 goto err;
98 }
99
100 /* get fields content of these messages */
101
102 r = mailsession_get_envelopes_list(session, env_list);
103 if (r != MAIL_NO_ERROR) {
104 printf("error envelopes list\n");
105 goto free_msg_list;
106 }
107
108 /* build threads */
109
110 r = mail_build_thread(MAIL_THREAD_REFERENCES_NO_SUBJECT,
111 DEST_CHARSET,
112 env_list, &env_tree,
113 mailthread_tree_timecomp);
114 if (r != MAIL_NO_ERROR) {
115 printf("can't build tree\n");
116 goto free_msg_list;
117 }
118
119 /* display message tree */
120
121 count = 0;
122 display_tree(env_tree, &count);
123
124 printf(" %i messages\n", count);
125
126 /* free structure */
127
128 mailmessage_tree_free_recursive(env_tree);
129 mailmessage_list_free(env_list);
130
131 return;
132
133 free_msg_list:
134 mailmessage_list_free(env_list);
135 err:
136}
137
138int main(int argc, char ** argv)
139{
140 int r;
141 int driver;
142 char * server;
143 int port;
144 int connection_type;
145 char * user;
146 char * password;
147 int auth_type;
148 char * path;
149 char * cache_directory;
150 char * flags_directory;
151 struct mailstorage * storage;
152 int cached;
153 struct mailfolder * folder;
154
155 /* get options */
156
157 r = parse_options(argc, argv,
158 &driver, &server, &port, &connection_type,
159 &user, &password, &auth_type,
160 &path, &cache_directory, &flags_directory);
161
162 cached = (cache_directory != NULL);
163
164 /* build the storage structure */
165
166 storage = mailstorage_new(NULL);
167 if (storage == NULL) {
168 printf("error initializing storage\n");
169 goto free_opt;
170 }
171
172 r = init_storage(storage, driver, server, port, connection_type,
173 user, password, auth_type, path, cache_directory, flags_directory);
174 if (r != MAIL_NO_ERROR) {
175 printf("error initializing storage\n");
176 goto free_opt;
177 }
178
179 /* get the folder structure */
180
181 folder = mailfolder_new(storage, path, NULL);
182 if (folder == NULL) {
183 printf("error initializing folder\n");
184 goto free_storage;
185 }
186
187 r = mailfolder_connect(folder);
188 if (r != MAIL_NO_ERROR) {
189 printf("error initializing folder\n");
190 goto free_folder;
191 }
192
193 /* get and display the list of messages */
194
195 print_message_list(folder->fld_session);
196
197 mailfolder_free(folder);
198 mailstorage_free(storage);
199
200 if (server != NULL)
201 free(server);
202 if (user != NULL)
203 free(user);
204 if (password != NULL)
205 free(password);
206 if (path != NULL)
207 free(path);
208 if (cache_directory != NULL)
209 free(cache_directory);
210 if (flags_directory != NULL)
211 free(flags_directory);
212
213 return 0;
214
215 free_folder:
216 mailfolder_free(folder);
217 free_storage:
218 mailstorage_free(storage);
219 free_opt:
220 if (server != NULL)
221 free(server);
222 if (user != NULL)
223 free(user);
224 if (password != NULL)
225 free(password);
226 if (path != NULL)
227 free(path);
228 if (cache_directory != NULL)
229 free(cache_directory);
230 if (flags_directory != NULL)
231 free(flags_directory);
232 return -1;
233}
234
diff --git a/kmicromail/libetpan/tests/frm.c b/kmicromail/libetpan/tests/frm.c
new file mode 100644
index 0000000..8ce9d9b
--- a/dev/null
+++ b/kmicromail/libetpan/tests/frm.c
@@ -0,0 +1,158 @@
1#include "option-parser.h"
2#include "frm-common.h"
3
4#include <libetpan/libetpan.h>
5
6#include <stdlib.h>
7#include <string.h>
8
9#define DEST_CHARSET "iso-8859-1"
10
11/* get the message list and display it */
12
13static void print_message_list(mailsession * session)
14{
15 int r;
16 uint32_t i;
17 struct mailmessage_list * env_list;
18 unsigned int count;
19
20 /* get the list of messages numbers of the folder */
21
22 r = mailsession_get_messages_list(session, &env_list);
23 if (r != MAIL_NO_ERROR) {
24 printf("error message list\n");
25 goto err;
26 }
27
28 /* get fields content of these messages */
29
30 r = mailsession_get_envelopes_list(session, env_list);
31 if (r != MAIL_NO_ERROR) {
32 printf("error envelopes list\n");
33 goto free_msg_list;
34 }
35
36 /* display all the messages */
37
38 count = 0;
39 for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
40 mailmessage * msg;
41
42 msg = carray_get(env_list->msg_tab, i);
43
44 if (msg->msg_fields == NULL) {
45 printf("could not fetch envelope of message %i\n", i);
46 }
47 else {
48 print_mail_info("", msg);
49 count ++;
50 }
51 }
52 printf(" %i messages\n", count);
53
54 /* free structure */
55
56 mailmessage_list_free(env_list);
57
58 return;
59
60 free_msg_list:
61 mailmessage_list_free(env_list);
62 err:
63}
64
65int main(int argc, char ** argv)
66{
67 int r;
68 int driver;
69 char * server;
70 int port;
71 int connection_type;
72 char * user;
73 char * password;
74 int auth_type;
75 char * path;
76 char * cache_directory;
77 char * flags_directory;
78 struct mailstorage * storage;
79 struct mailfolder * folder;
80
81 /* get options */
82
83 r = parse_options(argc, argv,
84 &driver, &server, &port, &connection_type,
85 &user, &password, &auth_type,
86 &path, &cache_directory, &flags_directory);
87
88 /* build the storage structure */
89
90 storage = mailstorage_new(NULL);
91 if (storage == NULL) {
92 printf("error initializing storage\n");
93 goto free_opt;
94 }
95
96 r = init_storage(storage, driver, server, port, connection_type,
97 user, password, auth_type, path, cache_directory, flags_directory);
98 if (r != MAIL_NO_ERROR) {
99 printf("error initializing storage\n");
100 goto free_opt;
101 }
102
103 /* get the folder structure */
104
105 folder = mailfolder_new(storage, path, NULL);
106 if (folder == NULL) {
107 printf("error initializing folder\n");
108 goto free_storage;
109 }
110
111 r = mailfolder_connect(folder);
112 if (r != MAIL_NO_ERROR) {
113 printf("error connecting folder\n");
114 goto free_folder;
115 }
116
117 /* get and display the list of messages */
118
119 print_message_list(folder->fld_session);
120
121 mailfolder_free(folder);
122 mailstorage_free(storage);
123
124 if (server != NULL)
125 free(server);
126 if (user != NULL)
127 free(user);
128 if (password != NULL)
129 free(password);
130 if (path != NULL)
131 free(path);
132 if (cache_directory != NULL)
133 free(cache_directory);
134 if (flags_directory != NULL)
135 free(flags_directory);
136
137 return 0;
138
139 free_folder:
140 mailfolder_free(folder);
141 free_storage:
142 mailstorage_free(storage);
143 free_opt:
144 if (server != NULL)
145 free(server);
146 if (user != NULL)
147 free(user);
148 if (password != NULL)
149 free(password);
150 if (path != NULL)
151 free(path);
152 if (cache_directory != NULL)
153 free(cache_directory);
154 if (flags_directory != NULL)
155 free(flags_directory);
156 return -1;
157}
158
diff --git a/kmicromail/libetpan/tests/option-parser.c b/kmicromail/libetpan/tests/option-parser.c
new file mode 100644
index 0000000..57a1597
--- a/dev/null
+++ b/kmicromail/libetpan/tests/option-parser.c
@@ -0,0 +1,234 @@
1#define _GNU_SOURCE
2#include <getopt.h>
3
4#include <stdlib.h>
5#include <string.h>
6#include <limits.h>
7
8#include <libetpan/libetpan.h>
9
10#include "option-parser.h"
11
12/*
13 options
14
15 --driver (pop3|imap|nntp|mbox|mh|maildir) -d
16
17 default driver is mbox
18
19 --server {server-name} -s
20 --port {port-number} -p
21 --tls -t
22 --starttls -x
23 --user {login} -u
24 --password {password} -v
25 --path {mailbox} -l
26 --apop -a
27 --cache {directory} -c
28 --flags {directory} -f
29*/
30
31struct storage_name {
32 int id;
33 char * name;
34};
35
36static struct storage_name storage_tab[] = {
37 {POP3_STORAGE, "pop3"},
38 {IMAP_STORAGE, "imap"},
39 {NNTP_STORAGE, "nntp"},
40 {MBOX_STORAGE, "mbox"},
41 {MH_STORAGE, "mh"},
42 {MAILDIR_STORAGE, "maildir"},
43};
44
45static int get_driver(char * name)
46{
47 int driver_type;
48 unsigned int i;
49
50 driver_type = -1;
51 for(i = 0 ; i < sizeof(storage_tab) / sizeof(struct storage_name) ; i++) {
52 if (strcasecmp(name, storage_tab[i].name) == 0) {
53 driver_type = i;
54 break;
55 }
56 }
57
58 return driver_type;
59}
60
61int parse_options(int argc, char ** argv,
62 int * driver,
63 char ** server, int * port, int * connection_type,
64 char ** user, char ** password, int * auth_type,
65 char ** path, char ** cache_directory,
66 char ** flags_directory)
67{
68 int index;
69 static struct option long_options[] = {
70 {"driver", 1, 0, 'd'},
71 {"server", 1, 0, 's'},
72 {"port", 1, 0, 'p'},
73 {"tls", 0, 0, 't'},
74 {"starttls", 0, 0, 'x'},
75 {"user", 1, 0, 'u'},
76 {"password", 1, 0, 'v'},
77 {"path", 1, 0, 'l'},
78 {"apop", 0, 0, 'a'},
79 {"cache", 1, 0, 'c'},
80 {"flags", 1, 0, 'f'},
81 };
82 int r;
83 char location[PATH_MAX];
84 char * env_user;
85
86 index = 0;
87
88 * driver = MBOX_STORAGE;
89 * server = NULL;
90 * port = 0;
91 * connection_type = CONNECTION_TYPE_PLAIN;
92 * user = NULL;
93 * password = NULL;
94 * auth_type = POP3_AUTH_TYPE_PLAIN;
95 env_user = getenv("USER");
96 if (env_user != NULL) {
97 snprintf(location, PATH_MAX, "/var/mail/%s", env_user);
98 * path = strdup(location);
99 }
100 else
101 * path = NULL;
102 * cache_directory = NULL;
103 * flags_directory = NULL;
104
105 while (1) {
106 r = getopt_long(argc, argv, "d:s:p:txu:v:l:ac:f:", long_options, &index);
107
108 if (r == -1)
109 break;
110
111 switch (r) {
112 case 'd':
113 * driver = get_driver(optarg);
114 break;
115 case 's':
116 if (* server != NULL)
117 free(* server);
118 * server = strdup(optarg);
119 break;
120 case 'p':
121 * port = strtoul(optarg, NULL, 10);
122 break;
123 case 't':
124 * connection_type = CONNECTION_TYPE_TLS;
125 break;
126 case 'x':
127 * connection_type = CONNECTION_TYPE_STARTTLS;
128 break;
129 case 'u':
130 if (* user != NULL)
131 free(* user);
132 * user = strdup(optarg);
133 break;
134 case 'v':
135 if (* password != NULL)
136 free(* password);
137 * password = strdup(optarg);
138 break;
139 case 'l':
140 if (* path != NULL)
141 free(* path);
142 * path = strdup(optarg);
143 break;
144 case 'a':
145 * auth_type = POP3_AUTH_TYPE_APOP;
146 break;
147 case 'c':
148 if (* cache_directory != NULL)
149 free(* cache_directory);
150 * cache_directory = strdup(optarg);
151 break;
152 case 'f':
153 if (* flags_directory != NULL)
154 free(* flags_directory);
155 * flags_directory = strdup(optarg);
156 break;
157 }
158 }
159
160 return 0;
161}
162
163int init_storage(struct mailstorage * storage,
164 int driver, char * server, int port,
165 int connection_type, char * user, char * password, int auth_type,
166 char * path, char * cache_directory, char * flags_directory)
167{
168 int r;
169 int cached;
170
171 cached = (cache_directory != NULL);
172
173 switch (driver) {
174 case POP3_STORAGE:
175 r = pop3_mailstorage_init(storage, server, port, NULL, connection_type,
176 auth_type, user, password, cached, cache_directory,
177 flags_directory);
178 if (r != MAIL_NO_ERROR) {
179 printf("error initializing POP3 storage\n");
180 goto err;
181 }
182 break;
183
184 case IMAP_STORAGE:
185 r = imap_mailstorage_init(storage, server, port, NULL, connection_type,
186 IMAP_AUTH_TYPE_PLAIN, user, password, cached, cache_directory);
187 if (r != MAIL_NO_ERROR) {
188 printf("error initializing IMAP storage\n");
189 goto err;
190 }
191 break;
192
193 case NNTP_STORAGE:
194 r = nntp_mailstorage_init(storage, server, port, NULL, connection_type,
195 NNTP_AUTH_TYPE_PLAIN, user, password, cached, cache_directory,
196 flags_directory);
197 if (r != MAIL_NO_ERROR) {
198 printf("error initializing NNTP storage\n");
199 goto err;
200 }
201 break;
202
203 case MBOX_STORAGE:
204 r = mbox_mailstorage_init(storage, path, cached, cache_directory,
205 flags_directory);
206 if (r != MAIL_NO_ERROR) {
207 printf("error initializing mbox storage\n");
208 goto err;
209 }
210 break;
211
212 case MH_STORAGE:
213 r = mh_mailstorage_init(storage, path, cached, cache_directory,
214 flags_directory);
215 if (r != MAIL_NO_ERROR) {
216 printf("error initializing MH storage\n");
217 goto err;
218 }
219 break;
220 case MAILDIR_STORAGE:
221 r = maildir_mailstorage_init(storage, path, cached, cache_directory,
222 flags_directory);
223 if (r != MAIL_NO_ERROR) {
224 printf("error initializing maildir storage\n");
225 goto err;
226 }
227 break;
228 }
229
230 return MAIL_NO_ERROR;
231
232 err:
233 return r;
234}
diff --git a/kmicromail/libetpan/tests/option-parser.h b/kmicromail/libetpan/tests/option-parser.h
new file mode 100644
index 0000000..d765332
--- a/dev/null
+++ b/kmicromail/libetpan/tests/option-parser.h
@@ -0,0 +1,28 @@
1#ifndef OPTION_PARSER
2
3#define OPTION_PARSER
4
5#include <libetpan/libetpan.h>
6
7enum {
8 POP3_STORAGE = 0,
9 IMAP_STORAGE,
10 NNTP_STORAGE,
11 MBOX_STORAGE,
12 MH_STORAGE,
13 MAILDIR_STORAGE,
14};
15
16int parse_options(int argc, char ** argv,
17 int * driver,
18 char ** server, int * port, int * connection_type,
19 char ** user, char ** password, int * auth_type,
20 char ** path, char ** cache_directory,
21 char ** flags_directory);
22
23int init_storage(struct mailstorage * storage,
24 int driver, char * server, int port,
25 int connection_type, char * user, char * password, int auth_type,
26 char * path, char * cache_directory, char * flags_directory);
27
28#endif
diff --git a/kmicromail/libetpan/tests/readmsg-common.c b/kmicromail/libetpan/tests/readmsg-common.c
new file mode 100644
index 0000000..060497d
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-common.c
@@ -0,0 +1,720 @@
1#include "readmsg-common.h"
2
3#include <sys/stat.h>
4#include <sys/mman.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <string.h>
8#include <stdlib.h>
9
10/* returns TRUE is given MIME part is a text part */
11
12int etpan_mime_is_text(struct mailmime * build_info)
13{
14 if (build_info->mm_type == MAILMIME_SINGLE) {
15 if (build_info->mm_content_type != NULL) {
16 if (build_info->mm_content_type->ct_type->tp_type ==
17 MAILMIME_TYPE_DISCRETE_TYPE) {
18 if (build_info->mm_content_type->ct_type->tp_data.tp_discrete_type->dt_type ==
19 MAILMIME_DISCRETE_TYPE_TEXT)
20 return 1;
21 }
22 }
23 else
24 return 1;
25 }
26
27 return 0;
28}
29
30
31/* display content type */
32
33int show_part_info(FILE * f,
34 struct mailmime_single_fields * mime_fields,
35 struct mailmime_content * content)
36{
37 char * description;
38 char * filename;
39 int col;
40 int r;
41
42 description = mime_fields->fld_description;
43 filename = mime_fields->fld_disposition_filename;
44
45 col = 0;
46
47 r = fprintf(f, " [ Part ");
48 if (r < 0)
49 goto err;
50
51 if (content != NULL) {
52 r = mailmime_content_type_write(f, &col, content);
53 if (r != MAILIMF_NO_ERROR)
54 goto err;
55 }
56
57 if (filename != NULL) {
58 r = fprintf(f, " (%s)", filename);
59 if (r < 0)
60 goto err;
61 }
62
63 if (description != NULL) {
64 r = fprintf(f, " : %s", description);
65 if (r < 0)
66 goto err;
67 }
68
69 r = fprintf(f, " ]\n\n");
70 if (r < 0)
71 goto err;
72
73 return NO_ERROR;
74
75 err:
76 return ERROR_FILE;
77}
78
79/*
80 fetch the data of the mailmime_data structure whether it is a file
81 or a string.
82
83 data must be freed with mmap_string_unref()
84*/
85
86#if 0
87static int fetch_data(struct mailmime_data * data,
88 char ** result, size_t * result_len)
89{
90 int fd;
91 int r;
92 char * text;
93 struct stat buf;
94 int res;
95 MMAPString * mmapstr;
96
97 switch (data->dt_type) {
98 case MAILMIME_DATA_TEXT:
99 mmapstr = mmap_string_new_len(data->dt_data.dt_text.dt_data,
100 data->dt_data.dt_text.dt_length);
101 if (mmapstr == NULL) {
102 res = ERROR_MEMORY;
103 goto err;
104 }
105
106 * result = mmapstr->str;
107 * result_len = mmapstr->len;
108
109 return NO_ERROR;
110
111 case MAILMIME_DATA_FILE:
112 fd = open(data->dt_data.dt_filename, O_RDONLY);
113 if (fd < 0) {
114 res = ERROR_FILE;
115 goto err;
116 }
117
118 r = fstat(fd, &buf);
119 if (r < 0) {
120 res = ERROR_FILE;
121 goto close;
122 }
123
124 if (buf.st_size != 0) {
125 text = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
126 if (text == MAP_FAILED) {
127 res = ERROR_FILE;
128 goto close;
129 }
130
131 mmapstr = mmap_string_new_len(text, buf.st_size);
132 if (mmapstr == NULL) {
133 res = r;
134 goto unmap;
135 }
136
137 munmap(text, buf.st_size);
138 }
139 else {
140 mmapstr = mmap_string_new("");
141 if (mmapstr == NULL) {
142 res = r;
143 goto close;
144 }
145 }
146
147 close(fd);
148
149 * result = mmapstr->str;
150 * result_len = mmapstr->len;
151
152 return NO_ERROR;
153
154 default:
155 return ERROR_INVAL;
156 }
157
158 unmap:
159 munmap(text, buf.st_size);
160 close:
161 close(fd);
162 err:
163 return res;
164}
165#endif
166
167/* fetch message and decode if it is base64 or quoted-printable */
168
169int etpan_fetch_message(mailmessage * msg_info,
170 struct mailmime * mime_part,
171 struct mailmime_single_fields * fields,
172 char ** result, size_t * result_len)
173{
174 char * data;
175 size_t len;
176 int r;
177 int encoding;
178 char * decoded;
179 size_t decoded_len;
180 size_t cur_token;
181 int res;
182 int encoded;
183
184 encoded = 0;
185
186 r = mailmessage_fetch_section(msg_info,
187 mime_part, &data, &len);
188 if (r != MAIL_NO_ERROR) {
189 res = ERROR_FETCH;
190 goto err;
191 }
192
193 encoded = 1;
194
195 /* decode message */
196
197 if (encoded) {
198 if (fields->fld_encoding != NULL)
199 encoding = fields->fld_encoding->enc_type;
200 else
201 encoding = MAILMIME_MECHANISM_8BIT;
202 }
203 else {
204 encoding = MAILMIME_MECHANISM_8BIT;
205 }
206
207 cur_token = 0;
208 r = mailmime_part_parse(data, len, &cur_token,
209 encoding, &decoded, &decoded_len);
210 if (r != MAILIMF_NO_ERROR) {
211 res = ERROR_FETCH;
212 goto free;
213 }
214
215 mailmessage_fetch_result_free(msg_info, data);
216
217 * result = decoded;
218 * result_len = decoded_len;
219
220 return NO_ERROR;
221
222 free:
223 mailmessage_fetch_result_free(msg_info, data);
224 err:
225 return res;
226}
227
228
229/* fetch fields */
230
231struct mailimf_fields * fetch_fields(mailmessage * msg_info,
232 struct mailmime * mime)
233{
234 char * data;
235 size_t len;
236 int r;
237 size_t cur_token;
238 struct mailimf_fields * fields;
239
240 r = mailmessage_fetch_section_header(msg_info, mime, &data, &len);
241 if (r != MAIL_NO_ERROR)
242 return NULL;
243
244 cur_token = 0;
245 r = mailimf_fields_parse(data, len, &cur_token, &fields);
246 if (r != MAILIMF_NO_ERROR) {
247 mailmessage_fetch_result_free(msg_info, data);
248 return NULL;
249 }
250
251 mailmessage_fetch_result_free(msg_info, data);
252
253 return fields;
254}
255
256
257
258#define MAX_MAIL_COL 72
259
260/* write decoded mailbox */
261
262static int
263etpan_mailbox_write(FILE * f, int * col,
264 struct mailimf_mailbox * mb)
265{
266 int r;
267
268 if (* col > 1) {
269
270 if (* col + strlen(mb->mb_addr_spec) >= MAX_MAIL_COL) {
271 r = mailimf_string_write(f, col, "\r\n ", 3);
272 if (r != MAILIMF_NO_ERROR)
273 return ERROR_FILE;
274 * col = 1;
275 }
276 }
277
278 if (mb->mb_display_name) {
279 char * decoded_from;
280 size_t cur_token;
281
282 cur_token = 0;
283 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
284 mb->mb_display_name, strlen(mb->mb_display_name),
285 &cur_token, DEST_CHARSET,
286 &decoded_from);
287 if (r != MAILIMF_NO_ERROR) {
288 decoded_from = strdup(mb->mb_display_name);
289 if (decoded_from == NULL)
290 return ERROR_MEMORY;
291 }
292
293 r = mailimf_quoted_string_write(f, col, decoded_from,
294 strlen(decoded_from));
295 if (r != MAILIMF_NO_ERROR) {
296 free(decoded_from);
297 return ERROR_FILE;
298 }
299
300 if (* col > 1) {
301
302 if (* col + strlen(decoded_from) + 3 >= MAX_MAIL_COL) {
303 r = mailimf_string_write(f, col, "\r\n ", 3);
304 if (r != MAILIMF_NO_ERROR) {
305 free(decoded_from);
306 return r;
307 }
308 * col = 1;
309 }
310 }
311
312 free(decoded_from);
313
314 r = mailimf_string_write(f, col, " <", 2);
315 if (r != MAILIMF_NO_ERROR)
316 return ERROR_FILE;
317
318 r = mailimf_string_write(f, col,
319 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
320 if (r != MAILIMF_NO_ERROR)
321 return ERROR_FILE;
322
323 r = mailimf_string_write(f, col, ">", 1);
324 if (r != MAILIMF_NO_ERROR)
325 return ERROR_FILE;
326 }
327 else {
328 r = mailimf_string_write(f, col,
329 mb->mb_addr_spec, strlen(mb->mb_addr_spec));
330 if (r != MAILIMF_NO_ERROR)
331 return ERROR_FILE;
332 }
333
334
335 return NO_ERROR;
336
337}
338
339/* write decoded mailbox list */
340
341int
342etpan_mailbox_list_write(FILE * f, int * col,
343 struct mailimf_mailbox_list * mb_list)
344{
345 clistiter * cur;
346 int r;
347 int first;
348
349 first = 1;
350
351 for(cur = clist_begin(mb_list->mb_list) ; cur != NULL ;
352 cur = clist_next(cur)) {
353 struct mailimf_mailbox * mb;
354
355 mb = cur->data;
356
357 if (!first) {
358 r = mailimf_string_write(f, col, ", ", 2);
359 if (r != MAILIMF_NO_ERROR)
360 return ERROR_FILE;
361 }
362 else {
363 first = 0;
364 }
365
366 r = etpan_mailbox_write(f, col, mb);
367 if (r != NO_ERROR)
368 return r;
369 }
370
371 return NO_ERROR;
372}
373
374/* write decoded group */
375
376static int
377etpan_group_write(FILE * f, int * col,
378 struct mailimf_group * group)
379{
380 int r;
381
382 r = mailimf_string_write(f, col, group->grp_display_name,
383 strlen(group->grp_display_name));
384 if (r != MAILIMF_NO_ERROR)
385 return ERROR_FILE;
386
387 r = mailimf_string_write(f, col, ": ", 2);
388 if (r != MAILIMF_NO_ERROR)
389 return ERROR_FILE;
390
391 if (group->grp_mb_list != NULL) {
392 r = etpan_mailbox_list_write(f, col, group->grp_mb_list);
393 if (r != NO_ERROR)
394 return r;
395 }
396
397 r = mailimf_string_write(f, col, ";", 1);
398 if (r != MAILIMF_NO_ERROR)
399 return ERROR_FILE;
400
401 return NO_ERROR;
402}
403
404/* write decoded address */
405
406int
407etpan_address_write(FILE * f, int * col,
408 struct mailimf_address * addr)
409{
410 int r;
411
412 switch(addr->ad_type) {
413 case MAILIMF_ADDRESS_MAILBOX:
414 r = etpan_mailbox_write(f, col, addr->ad_data.ad_mailbox);
415 if (r != NO_ERROR)
416 return r;
417
418 break;
419
420 case MAILIMF_ADDRESS_GROUP:
421 r = etpan_group_write(f, col, addr->ad_data.ad_group);
422 if (r != NO_ERROR)
423 return r;
424
425 break;
426 }
427
428 return MAILIMF_NO_ERROR;
429}
430
431/* write decoded address list */
432
433int
434etpan_address_list_write(FILE * f, int * col,
435 struct mailimf_address_list * addr_list)
436{
437 clistiter * cur;
438 int r;
439 int first;
440
441 first = 1;
442
443 for(cur = clist_begin(addr_list->ad_list) ; cur != NULL ;
444 cur = clist_next(cur)) {
445 struct mailimf_address * addr;
446
447 addr = clist_content(cur);
448
449 if (!first) {
450 r = mailimf_string_write(f, col, ", ", 2);
451 if (r != MAILIMF_NO_ERROR)
452 return ERROR_FILE;
453 }
454 else {
455 first = 0;
456 }
457
458 r = etpan_address_write(f, col, addr);
459 if (r != NO_ERROR)
460 return r;
461 }
462
463 return NO_ERROR;
464}
465
466/* write decoded subject */
467
468static int etpan_subject_write(FILE * f, int * col,
469 char * subject)
470{
471 int r;
472 char * decoded_subject;
473 size_t cur_token;
474
475 r = mailimf_string_write(f, col, "Subject: ", 9);
476 if (r != MAILIMF_NO_ERROR) {
477 return ERROR_FILE;
478 }
479
480 cur_token = 0;
481 r = mailmime_encoded_phrase_parse(DEST_CHARSET,
482 subject, strlen(subject),
483 &cur_token, DEST_CHARSET,
484 &decoded_subject);
485 if (r != MAILIMF_NO_ERROR) {
486 decoded_subject = strdup(subject);
487 if (decoded_subject == NULL)
488 return ERROR_MEMORY;
489 }
490
491 r = mailimf_string_write(f, col, decoded_subject, strlen(decoded_subject));
492 if (r != MAILIMF_NO_ERROR) {
493 free(decoded_subject);
494 return ERROR_FILE;
495 }
496
497 free(decoded_subject);
498
499 r = mailimf_string_write(f, col, "\r\n", 2);
500 if (r != MAILIMF_NO_ERROR) {
501 return ERROR_FILE;
502 }
503 * col = 0;
504
505 return NO_ERROR;
506}
507
508/* write decoded fields */
509
510int fields_write(FILE * f, int * col,
511 struct mailimf_fields * fields)
512{
513 clistiter * cur;
514 int r;
515
516 for(cur = clist_begin(fields->fld_list) ; cur != NULL ;
517 cur = clist_next(cur)) {
518 struct mailimf_field * field;
519
520 field = clist_content(cur);
521
522 switch (field->fld_type) {
523 case MAILIMF_FIELD_FROM:
524 r = mailimf_string_write(f, col, "From: ", 6);
525 if (r != MAILIMF_NO_ERROR)
526 goto err;
527
528 r = etpan_mailbox_list_write(f, col,
529 field->fld_data.fld_from->frm_mb_list);
530 if (r != NO_ERROR)
531 goto err;
532
533 r = mailimf_string_write(f, col, "\r\n", 2);
534 if (r != MAILIMF_NO_ERROR)
535 goto err;
536 * col = 0;
537
538 break;
539
540 case MAILIMF_FIELD_REPLY_TO:
541 r = mailimf_string_write(f, col, "Reply-To: ", 10);
542 if (r != MAILIMF_NO_ERROR)
543 goto err;
544
545 r = etpan_address_list_write(f, col,
546 field->fld_data.fld_reply_to->rt_addr_list);
547 if (r != NO_ERROR)
548 goto err;
549
550 r = mailimf_string_write(f, col, "\r\n", 2);
551 if (r != MAILIMF_NO_ERROR)
552 goto err;
553 * col = 0;
554
555 break;
556
557 case MAILIMF_FIELD_TO:
558 r = mailimf_string_write(f, col, "To: ", 4);
559 if (r != MAILIMF_NO_ERROR)
560 goto err;
561
562 r = etpan_address_list_write(f, col,
563 field->fld_data.fld_to->to_addr_list);
564 if (r != NO_ERROR)
565 goto err;
566
567 r = mailimf_string_write(f, col, "\r\n", 2);
568 if (r != MAILIMF_NO_ERROR)
569 goto err;
570 * col = 0;
571
572 break;
573
574 case MAILIMF_FIELD_CC:
575 r = mailimf_string_write(f, col, "Cc: ", 4);
576 if (r != MAILIMF_NO_ERROR)
577 goto err;
578
579 r = etpan_address_list_write(f, col,
580 field->fld_data.fld_cc->cc_addr_list);
581 if (r != NO_ERROR)
582 goto err;
583
584 r = mailimf_string_write(f, col, "\r\n", 2);
585 if (r != MAILIMF_NO_ERROR)
586 goto err;
587 * col = 0;
588
589 break;
590
591 case MAILIMF_FIELD_BCC:
592 r = mailimf_string_write(f, col, "Bcc: ", 10);
593 if (r != MAILIMF_NO_ERROR)
594 goto err;
595
596 if (field->fld_data.fld_bcc->bcc_addr_list != NULL) {
597 r = etpan_address_list_write(f, col,
598 field->fld_data.fld_bcc->bcc_addr_list);
599 if (r != NO_ERROR)
600 goto err;
601 }
602
603 r = mailimf_string_write(f, col, "\r\n", 2);
604 if (r != MAILIMF_NO_ERROR)
605 goto err;
606 * col = 0;
607
608 break;
609
610 case MAILIMF_FIELD_SUBJECT:
611 r = etpan_subject_write(f, col, field->fld_data.fld_subject->sbj_value);
612 if (r != MAILIMF_NO_ERROR)
613 goto err;
614 break;
615
616 case MAILIMF_FIELD_RESENT_FROM:
617 r = mailimf_string_write(f, col, "Resent-From: ", 13);
618 if (r != MAILIMF_NO_ERROR)
619 goto err;
620
621 r = etpan_mailbox_list_write(f, col,
622 field->fld_data.fld_resent_from->frm_mb_list);
623 if (r != NO_ERROR)
624 goto err;
625
626 r = mailimf_string_write(f, col, "\r\n", 2);
627 if (r != MAILIMF_NO_ERROR)
628 goto err;
629 * col = 0;
630 break;
631
632 case MAILIMF_FIELD_RESENT_TO:
633 r = mailimf_string_write(f, col, "Resent-To: ", 11);
634 if (r != MAILIMF_NO_ERROR)
635 goto err;
636
637 r = etpan_address_list_write(f, col,
638 field->fld_data.fld_resent_to->to_addr_list);
639 if (r != NO_ERROR)
640 goto err;
641
642 r = mailimf_string_write(f, col, "\r\n", 2);
643 if (r != MAILIMF_NO_ERROR)
644 goto err;
645 * col = 0;
646
647 break;
648 case MAILIMF_FIELD_RESENT_CC:
649 r = mailimf_string_write(f, col, "Resent-Cc: ", 11);
650 if (r != MAILIMF_NO_ERROR)
651 goto err;
652
653 r = etpan_address_list_write(f, col,
654 field->fld_data.fld_resent_cc->cc_addr_list);
655 if (r != NO_ERROR)
656 goto err;
657
658 r = mailimf_string_write(f, col, "\r\n", 2);
659 if (r != MAILIMF_NO_ERROR)
660 goto err;
661 * col = 0;
662
663 break;
664 case MAILIMF_FIELD_RESENT_BCC:
665 r = mailimf_string_write(f, col, "Resent-Bcc: ", 12);
666 if (r != MAILIMF_NO_ERROR)
667 goto err;
668
669 if (field->fld_data.fld_resent_bcc->bcc_addr_list != NULL) {
670 r = etpan_address_list_write(f, col,
671 field->fld_data.fld_resent_bcc->bcc_addr_list);
672 if (r != NO_ERROR)
673 goto err;
674 }
675
676 r = mailimf_string_write(f, col, "\r\n", 2);
677 if (r != MAILIMF_NO_ERROR)
678 goto err;
679 * col = 0;
680
681 break;
682
683 case MAILIMF_FIELD_ORIG_DATE:
684 case MAILIMF_FIELD_RESENT_DATE:
685 r = mailimf_field_write(f, col, field);
686 if (r != MAILIMF_NO_ERROR)
687 goto err;
688 break;
689
690 case MAILIMF_FIELD_OPTIONAL_FIELD:
691 if ((strcasecmp(field->fld_data.fld_optional_field->fld_name,
692 "X-Mailer") == 0)
693 || (strncasecmp(field->fld_data.fld_optional_field->fld_name,
694 "Resent-", 7) == 0)
695 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
696 "Newsgroups") == 0)
697 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
698 "Followup-To") == 0)
699 || (strcasecmp(field->fld_data.fld_optional_field->fld_name,
700 "User-Agent") == 0)) {
701 r = mailimf_field_write(f, col, field);
702 if (r != MAILIMF_NO_ERROR)
703 goto err;
704 }
705 break;
706
707 case MAILIMF_FIELD_MESSAGE_ID:
708 case MAILIMF_FIELD_SENDER:
709 case MAILIMF_FIELD_IN_REPLY_TO:
710 case MAILIMF_FIELD_REFERENCES:
711 default:
712 break;
713 }
714 }
715
716 return NO_ERROR;
717
718 err:
719 return ERROR_FILE;
720}
diff --git a/kmicromail/libetpan/tests/readmsg-common.h b/kmicromail/libetpan/tests/readmsg-common.h
new file mode 100644
index 0000000..70265f2
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-common.h
@@ -0,0 +1,34 @@
1#ifndef READMSG_COMMON_H
2
3#define READMSG_COMMON_H
4
5#include <libetpan/libetpan.h>
6
7#define DEST_CHARSET "iso-8859-1"
8
9enum {
10 NO_ERROR,
11 ERROR_FILE,
12 ERROR_MEMORY,
13 ERROR_INVAL,
14 ERROR_FETCH,
15};
16
17int etpan_mime_is_text(struct mailmime * build_info);
18
19int show_part_info(FILE * f,
20 struct mailmime_single_fields * mime_fields,
21 struct mailmime_content * content);
22
23int etpan_fetch_message(mailmessage * msg_info,
24 struct mailmime * mime_part,
25 struct mailmime_single_fields * fields,
26 char ** result, size_t * result_len);
27
28struct mailimf_fields * fetch_fields(mailmessage * msg_info,
29 struct mailmime * mime);
30
31int fields_write(FILE * f, int * col,
32 struct mailimf_fields * fields);
33
34#endif
diff --git a/kmicromail/libetpan/tests/readmsg-simple.c b/kmicromail/libetpan/tests/readmsg-simple.c
new file mode 100644
index 0000000..ea57d6d
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg-simple.c
@@ -0,0 +1,133 @@
1#include <unistd.h>
2#include <string.h>
3#include <stdlib.h>
4
5#include <libetpan/libetpan.h>
6
7#include "option-parser.h"
8
9int main(int argc, char ** argv)
10{
11 int r;
12 int driver;
13 char * server;
14 int port;
15 int connection_type;
16 char * user;
17 char * password;
18 int auth_type;
19 char * path;
20 char * cache_directory;
21 char * flags_directory;
22 struct mailstorage * storage;
23 int cached;
24 struct mailfolder * folder;
25
26 /* get options */
27
28 r = parse_options(argc, argv,
29 &driver, &server, &port, &connection_type,
30 &user, &password, &auth_type,
31 &path, &cache_directory, &flags_directory);
32
33 cached = (cache_directory != NULL);
34
35 /* build the storage structure */
36
37 storage = mailstorage_new(NULL);
38 if (storage == NULL) {
39 printf("error initializing storage\n");
40 goto free_opt;
41 }
42
43 r = init_storage(storage, driver, server, port, connection_type,
44 user, password, auth_type, path, cache_directory, flags_directory);
45 if (r != MAIL_NO_ERROR) {
46 printf("error initializing storage\n");
47 goto free_opt;
48 }
49
50 /* get the folder structure */
51
52 folder = mailfolder_new(storage, path, NULL);
53 if (folder == NULL) {
54 printf("error initializing folder\n");
55 goto free_storage;
56 }
57
58 r = mailfolder_connect(folder);
59 if (r != MAIL_NO_ERROR) {
60 printf("error initializing folder\n");
61 goto free_folder;
62 }
63
64 while (optind < argc) {
65 mailmessage * msg;
66 uint32_t msg_num;
67 char * data;
68 size_t size;
69
70 msg_num = strtoul(argv[optind], NULL, 10);
71
72 r = mailsession_get_message(folder->fld_session, msg_num, &msg);
73 if (r != MAIL_NO_ERROR) {
74 printf("** message %i not found **\n", msg_num);
75 optind ++;
76 continue;
77 }
78
79 r = mailmessage_fetch(msg, &data, &size);
80 if (r != MAIL_NO_ERROR) {
81 printf("** message %i not found - %s **\n", msg_num,
82 maildriver_strerror(r));
83 mailmessage_free(msg);
84 optind ++;
85 continue;
86 }
87
88 fwrite(data, 1, size, stdout);
89
90 mailmessage_fetch_result_free(msg, data);
91
92 mailmessage_free(msg);
93
94 optind ++;
95 }
96
97 mailfolder_free(folder);
98 mailstorage_free(storage);
99
100 if (server != NULL)
101 free(server);
102 if (user != NULL)
103 free(user);
104 if (password != NULL)
105 free(password);
106 if (path != NULL)
107 free(path);
108 if (cache_directory != NULL)
109 free(cache_directory);
110 if (flags_directory != NULL)
111 free(flags_directory);
112
113 return 0;
114
115 free_folder:
116 mailfolder_free(folder);
117 free_storage:
118 mailstorage_free(storage);
119 free_opt:
120 if (server != NULL)
121 free(server);
122 if (user != NULL)
123 free(user);
124 if (password != NULL)
125 free(password);
126 if (path != NULL)
127 free(path);
128 if (cache_directory != NULL)
129 free(cache_directory);
130 if (flags_directory != NULL)
131 free(flags_directory);
132 return -1;
133}
diff --git a/kmicromail/libetpan/tests/readmsg.c b/kmicromail/libetpan/tests/readmsg.c
new file mode 100644
index 0000000..822c93c
--- a/dev/null
+++ b/kmicromail/libetpan/tests/readmsg.c
@@ -0,0 +1,355 @@
1#include <unistd.h>
2#include <string.h>
3#include <stdlib.h>
4
5#include <libetpan/charconv.h>
6#include <libetpan/libetpan.h>
7
8#include "option-parser.h"
9#include "readmsg-common.h"
10
11
12/* render message */
13
14static int etpan_render_mime(FILE * f, mailmessage * msg_info,
15 struct mailmime * mime)
16{
17 int r;
18 clistiter * cur;
19 int col;
20 int text;
21 int show;
22 struct mailmime_single_fields fields;
23 int res;
24
25 mailmime_single_fields_init(&fields, mime->mm_mime_fields,
26 mime->mm_content_type);
27
28 text = etpan_mime_is_text(mime);
29
30 r = show_part_info(f, &fields, mime->mm_content_type);
31 if (r != NO_ERROR) {
32 res = r;
33 goto err;
34 }
35
36 switch(mime->mm_type) {
37 case MAILMIME_SINGLE:
38 show = 0;
39 if (text)
40 show = 1;
41
42 if (show) {
43 char * data;
44 size_t len;
45 char * converted;
46 size_t converted_len;
47 char * source_charset;
48 size_t write_len;
49
50 /* viewable part */
51
52 r = etpan_fetch_message(msg_info, mime,
53 &fields, &data, &len);
54 if (r != NO_ERROR) {
55 res = r;
56 goto err;
57 }
58
59 source_charset = fields.fld_content_charset;
60 if (source_charset == NULL)
61 source_charset = DEST_CHARSET;
62
63 r = charconv_buffer(source_charset, DEST_CHARSET,
64 data, len, &converted, &converted_len);
65 if (r != MAIL_CHARCONV_NO_ERROR) {
66
67 r = fprintf(f, "[ error converting charset from %s to %s ]\n",
68 source_charset, DEST_CHARSET);
69 if (r < 0) {
70 res = ERROR_FILE;
71 goto err;
72 }
73
74 write_len = fwrite(data, 1, len, f);
75 if (write_len != len) {
76 mailmime_decoded_part_free(data);
77 res = r;
78 goto err;
79 }
80 }
81 else {
82 write_len = fwrite(converted, 1, converted_len, f);
83 if (write_len != len) {
84 charconv_buffer_free(converted);
85 mailmime_decoded_part_free(data);
86 res = r;
87 goto err;
88 }
89
90 charconv_buffer_free(converted);
91 }
92
93 write_len = fwrite("\r\n\r\n", 1, 4, f);
94 if (write_len < 4) {
95 mailmime_decoded_part_free(data);
96 res = ERROR_FILE;
97 goto err;
98 }
99
100 mailmime_decoded_part_free(data);
101 }
102 else {
103 /* not viewable part */
104
105 r = fprintf(f, " (not shown)\n\n");
106 if (r < 0) {
107 res = ERROR_FILE;
108 goto err;
109 }
110 }
111
112 break;
113
114 case MAILMIME_MULTIPLE:
115
116 if (strcasecmp(mime->mm_content_type->ct_subtype, "alternative") == 0) {
117 struct mailmime * prefered_body;
118 int prefered_score;
119
120 /* case of multiple/alternative */
121
122 /*
123 we choose the better part,
124 alternative preference :
125
126 text/plain => score 3
127 text/xxx => score 2
128 other => score 1
129 */
130
131 prefered_body = NULL;
132 prefered_score = 0;
133
134 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
135 cur != NULL ; cur = clist_next(cur)) {
136 struct mailmime * submime;
137 int score;
138
139 score = 1;
140 submime = clist_content(cur);
141 if (etpan_mime_is_text(submime))
142 score = 2;
143
144 if (submime->mm_content_type != NULL) {
145 if (strcasecmp(submime->mm_content_type->ct_subtype, "plain") == 0)
146 score = 3;
147 }
148
149 if (score > prefered_score) {
150 prefered_score = score;
151 prefered_body = submime;
152 }
153 }
154
155 if (prefered_body != NULL) {
156 r = etpan_render_mime(f, msg_info, prefered_body);
157 if (r != NO_ERROR) {
158 res = r;
159 goto err;
160 }
161 }
162 }
163 else {
164 for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
165 cur != NULL ; cur = clist_next(cur)) {
166
167 r = etpan_render_mime(f, msg_info, clist_content(cur));
168 if (r != NO_ERROR) {
169 res = r;
170 goto err;
171 }
172 }
173 }
174
175 break;
176
177 case MAILMIME_MESSAGE:
178
179 if (mime->mm_data.mm_message.mm_fields != NULL) {
180 struct mailimf_fields * fields;
181
182 if (msg_info != NULL) {
183 fields = fetch_fields(msg_info, mime);
184 if (fields == NULL) {
185 res = ERROR_FETCH;
186 goto err;
187 }
188
189 col = 0;
190 r = fields_write(f, &col, fields);
191 if (r != NO_ERROR) {
192 mailimf_fields_free(fields);
193 res = r;
194 goto err;
195 }
196
197 mailimf_fields_free(fields);
198 }
199 else {
200 col = 0;
201 r = fields_write(f, &col, mime->mm_data.mm_message.mm_fields);
202 if (r != NO_ERROR) {
203 res = r;
204 goto err;
205 }
206 }
207
208 r = fprintf(f, "\r\n");
209 if (r < 0) {
210 res = ERROR_FILE;
211 goto err;
212 }
213 }
214
215 if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
216 r = etpan_render_mime(f, msg_info, mime->mm_data.mm_message.mm_msg_mime);
217 if (r != NO_ERROR) {
218 res = r;
219 goto err;
220 }
221 }
222
223 break;
224 }
225
226 return NO_ERROR;
227
228 err:
229 return res;
230}
231
232
233int main(int argc, char ** argv)
234{
235 int r;
236 int driver;
237 char * server;
238 int port;
239 int connection_type;
240 char * user;
241 char * password;
242 int auth_type;
243 char * path;
244 char * cache_directory;
245 char * flags_directory;
246 struct mailstorage * storage;
247 int cached;
248 struct mailfolder * folder;
249
250 /* get options */
251
252 r = parse_options(argc, argv,
253 &driver, &server, &port, &connection_type,
254 &user, &password, &auth_type,
255 &path, &cache_directory, &flags_directory);
256
257 cached = (cache_directory != NULL);
258
259 /* build the storage structure */
260
261 storage = mailstorage_new(NULL);
262 if (storage == NULL) {
263 printf("error initializing storage\n");
264 goto free_opt;
265 }
266
267 r = init_storage(storage, driver, server, port, connection_type,
268 user, password, auth_type, path, cache_directory, flags_directory);
269 if (r != MAIL_NO_ERROR) {
270 printf("error initializing storage\n");
271 goto free_opt;
272 }
273
274 /* get the folder structure */
275
276 folder = mailfolder_new(storage, path, NULL);
277 if (folder == NULL) {
278 printf("error initializing folder\n");
279 goto free_storage;
280 }
281
282 r = mailfolder_connect(folder);
283 if (r != MAIL_NO_ERROR) {
284 printf("error initializing folder\n");
285 goto free_folder;
286 }
287
288 while (optind < argc) {
289 mailmessage * msg;
290 uint32_t msg_num;
291 struct mailmime * mime;
292
293 msg_num = strtoul(argv[optind], NULL, 10);
294
295 r = mailsession_get_message(folder->fld_session, msg_num, &msg);
296 if (r != MAIL_NO_ERROR) {
297 printf("** message %i not found ** - %s\n", msg_num,
298 maildriver_strerror(r));
299 optind ++;
300 continue;
301 }
302
303 r = mailmessage_get_bodystructure(msg, &mime);
304 if (r != MAIL_NO_ERROR) {
305 printf("** message %i not found - %s **\n", msg_num,
306 maildriver_strerror(r));
307 mailmessage_free(msg);
308 optind ++;
309 continue;
310 }
311
312 r = etpan_render_mime(stdout, msg, mime);
313
314 mailmessage_free(msg);
315
316 optind ++;
317 }
318
319 mailfolder_free(folder);
320 mailstorage_free(storage);
321
322 if (server != NULL)
323 free(server);
324 if (user != NULL)
325 free(user);
326 if (password != NULL)
327 free(password);
328 if (path != NULL)
329 free(path);
330 if (cache_directory != NULL)
331 free(cache_directory);
332 if (flags_directory != NULL)
333 free(flags_directory);
334
335 return 0;
336
337 free_folder:
338 mailfolder_free(folder);
339 free_storage:
340 mailstorage_free(storage);
341 free_opt:
342 if (server != NULL)
343 free(server);
344 if (user != NULL)
345 free(user);
346 if (password != NULL)
347 free(password);
348 if (path != NULL)
349 free(path);
350 if (cache_directory != NULL)
351 free(cache_directory);
352 if (flags_directory != NULL)
353 free(flags_directory);
354 return -1;
355}
diff --git a/kmicromail/libetpan/tests/smtpsend.c b/kmicromail/libetpan/tests/smtpsend.c
new file mode 100644
index 0000000..d5229d9
--- a/dev/null
+++ b/kmicromail/libetpan/tests/smtpsend.c
@@ -0,0 +1,278 @@
1/*
2 * Simple Mail Submission Agent using SMTP with libEtPan!
3 * TODO: Full sendmail like interface
4 */
5
6#include <libetpan/libetpan.h>
7#include <netdb.h>
8#include <netinet/in.h>
9#include <sys/socket.h>
10#include <stdlib.h>
11#include <string.h>
12#include <sys/types.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <unistd.h>
16#include <sys/ioctl.h>
17#include <fcntl.h>
18#include <pwd.h>
19
20#define _GNU_SOURCE
21#include <getopt.h>
22
23/* globals */
24char *smtp_server;
25uint smtp_port = 25;
26char *smtp_user;
27char *smtp_password;
28char *smtp_from;
29int smtp_tls = 0;
30int smtp_esmtp = 1;
31
32struct mem_message {
33 char *data;
34 size_t len;
35 MMAPString *mstring;
36};
37
38#define BLOCKSIZE 4096
39
40int collect(struct mem_message *message) {
41 struct stat sb;
42 int len;
43
44 memset(message, 0, sizeof(struct mem_message));
45
46 /* if stdin is a file whose size is known, try to mmap it */
47 if (!fstat(0, &sb) && S_ISREG(sb.st_mode) && sb.st_size >= 0) {
48 message->len = sb.st_size;
49 if ((message->data = mmap(NULL, message->len, PROT_READ, MAP_SHARED,
50 STDIN_FILENO, 0)) != MAP_FAILED)
51 return 0;
52 }
53
54 /* read the buffer from stdin by blocks, until EOF or error.
55 save the message in a mmap_string */
56 if ((message->mstring = mmap_string_sized_new(BLOCKSIZE)) == NULL) {
57 perror("mmap_string_new");
58 goto error;
59 }
60 message->len = 0;
61
62 while ((len = read(STDIN_FILENO,
63 message->mstring->str + message->len, BLOCKSIZE)) > 0) {
64 message->len += len;
65 /* reserve room for next block */
66 if ((mmap_string_set_size(message->mstring,
67 message->len + BLOCKSIZE)) == NULL) {
68 perror("mmap_string_set_size");
69 goto error;
70 }
71 }
72
73 if (len == 0) {
74 message->data = message->mstring->str;
75 return 0; /* OK */
76 }
77
78 perror("read");
79
80 error:
81 if (message->mstring != NULL)
82 mmap_string_free(message->mstring);
83 return -1;
84}
85
86char *guessfrom() {
87 uid_t uid;
88 struct passwd *pw;
89 char hostname[256];
90 int len;
91 char *gfrom;
92
93 if (gethostname(hostname, sizeof(hostname))) {
94 perror("gethostname");
95 return NULL;
96 }
97 hostname[sizeof(hostname) - 1] = '\0';
98
99 uid = getuid();
100 pw = getpwuid(uid);
101
102 len = ((pw != NULL) ? strlen(pw->pw_name) : 12)
103 + strlen(hostname) + 2;
104
105 if ((gfrom = malloc(len)) == NULL) {
106 perror("malloc");
107 return NULL;
108 }
109 if (pw != NULL && pw->pw_name != NULL)
110 snprintf(gfrom, len, "%s@%s", pw->pw_name, hostname);
111 else
112 snprintf(gfrom, len, "#%u@%s", uid, hostname);
113 return gfrom;
114}
115
116void release(struct mem_message *message) {
117 if (message->mstring != NULL)
118 mmap_string_free(message->mstring);
119 else if (message->data != NULL)
120 munmap(message->data, message->len);
121}
122
123int send_message(char *data, size_t len, char**rcpts) {
124 int s = -1;
125 int ret;
126 char **r;
127 int esmtp = 0;
128 mailsmtp *smtp = NULL;
129
130 if ((smtp = mailsmtp_new(0, NULL)) == NULL) {
131 perror("mailsmtp_new");
132 goto error;
133 }
134
135 /* first open the stream */
136 if ((ret = mailsmtp_socket_connect(smtp,
137 (smtp_server != NULL ? smtp_server : "localhost"),
138 smtp_port)) != MAILSMTP_NO_ERROR) {
139 fprintf(stderr, "mailsmtp_socket_connect: %s\n", mailsmtp_strerror(ret));
140 goto error;
141 }
142
143 /* then introduce ourselves */
144 if (smtp_esmtp && (ret = mailesmtp_ehlo(smtp)) == MAILSMTP_NO_ERROR)
145 esmtp = 1;
146 else if (!smtp_esmtp || ret == MAILSMTP_ERROR_NOT_IMPLEMENTED)
147 ret = mailsmtp_helo(smtp);
148 if (ret != MAILSMTP_NO_ERROR) {
149 fprintf(stderr, "mailsmtp_helo: %s\n", mailsmtp_strerror(ret));
150 goto error;
151 }
152
153 if (esmtp && smtp_tls &&
154 (ret = mailsmtp_socket_starttls(smtp)) != MAILSMTP_NO_ERROR) {
155 fprintf(stderr, "mailsmtp_starttls: %s\n", mailsmtp_strerror(ret));
156 goto error;
157 }
158
159 if (esmtp && smtp_user != NULL &&
160 (ret = mailsmtp_auth(smtp, smtp_user,
161 (smtp_password != NULL) ? smtp_password : ""))
162 != MAILSMTP_NO_ERROR) {
163 fprintf(stderr, "mailsmtp_auth: %s: %s\n", smtp_user, mailsmtp_strerror(ret));
164 goto error;
165 }
166
167 /* source */
168 if ((ret = (esmtp ?
169 mailesmtp_mail(smtp, smtp_from, 1, "etPanSMTPTest") :
170 mailsmtp_mail(smtp, smtp_from))) != MAILSMTP_NO_ERROR) {
171 fprintf(stderr, "mailsmtp_mail: %s, %s\n", smtp_from, mailsmtp_strerror(ret));
172 goto error;
173 }
174
175 /* recipients */
176 for (r = rcpts; *r != NULL; r++) {
177 if ((ret = (esmtp ?
178 mailesmtp_rcpt(smtp, *r,
179 MAILSMTP_DSN_NOTIFY_FAILURE|MAILSMTP_DSN_NOTIFY_DELAY,
180 NULL) :
181 mailsmtp_rcpt(smtp, *r))) != MAILSMTP_NO_ERROR) {
182 fprintf(stderr, "mailsmtp_rcpt: %s: %s\n", *r, mailsmtp_strerror(ret));
183 goto error;
184 }
185 }
186
187 /* message */
188 if ((ret = mailsmtp_data(smtp)) != MAILSMTP_NO_ERROR) {
189 fprintf(stderr, "mailsmtp_data: %s\n", mailsmtp_strerror(ret));
190 goto error;
191 }
192 if ((ret = mailsmtp_data_message(smtp, data, len)) != MAILSMTP_NO_ERROR) {
193 fprintf(stderr, "mailsmtp_data_message: %s\n", mailsmtp_strerror(ret));
194 goto error;
195 }
196 mailsmtp_free(smtp);
197 return 0;
198
199 error:
200 if (smtp != NULL)
201 mailsmtp_free(smtp);
202 if (s >= 0)
203 close(s);
204 return -1;
205}
206
207int main(int argc, char **argv) {
208 struct mem_message message;
209 int index, r;
210
211 static struct option long_options[] = {
212 {"server", 1, 0, 's'},
213 {"port", 1, 0, 'p'},
214 {"user", 1, 0, 'u'},
215 {"password", 1, 0, 'v'},
216 {"from", 1, 0, 'f'},
217 {"tls", 0, 0, 'S'},
218 {"no-esmtp", 0, 0, 'E'},
219 };
220
221 while(1) {
222 if ((r = getopt_long(argc, argv, "s:p:u:v:f:SE", long_options, &index)) < 0)
223 break;
224 switch (r) {
225 case 's':
226 if (smtp_server != NULL)
227 free(smtp_server);
228 smtp_server = strdup(optarg);
229 break;
230 case 'p':
231 smtp_port = strtoul(optarg, NULL, 10);
232 break;
233 case 'u':
234 if (smtp_user != NULL)
235 free(smtp_user);
236 smtp_user = strdup(optarg);
237 break;
238 case 'v':
239 if (smtp_password != NULL)
240 free(smtp_password);
241 smtp_password = strdup(optarg);
242 break;
243 case 'f':
244 if (smtp_from != NULL)
245 free(smtp_from);
246 smtp_from = strdup(optarg);
247 break;
248 case 'S':
249 smtp_tls = 1;
250 break;
251 case 'E':
252 smtp_esmtp = 0;
253 break;
254 }
255 }
256
257 argc -= optind;
258 argv += optind;
259
260 if (argc < 1) {
261 fprintf(stderr, "usage: smtpsend [-f from] [-u user] [-v password] [-s server] [-p port] [-S] <rcpts>...\n");
262 return EXIT_FAILURE;
263 }
264
265 if (smtp_from == NULL && (smtp_from = guessfrom()) == NULL) {
266 fprintf(stderr, "can't guess a valid from, please use -f option.\n");
267 return EXIT_FAILURE;
268 }
269
270 /* reads message from stdin */
271 if (collect(&message))
272 return EXIT_FAILURE;
273
274 send_message(message.data, message.len, argv);
275
276 release(&message);
277 return EXIT_SUCCESS;
278}