-rw-r--r-- | kmicromail/libetpan/tests/README | 58 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/compose-msg.c | 317 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/fetch-attachment.c | 274 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/frm-common.c | 158 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/frm-common.h | 14 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/frm-simple.c | 227 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/frm-tree.c | 234 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/frm.c | 158 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/option-parser.c | 234 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/option-parser.h | 28 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/readmsg-common.c | 720 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/readmsg-common.h | 34 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/readmsg-simple.c | 133 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/readmsg.c | 355 | ||||
-rw-r--r-- | kmicromail/libetpan/tests/smtpsend.c | 278 |
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 @@ | |||
1 | compose-msg | ||
2 | ----------- | ||
3 | |||
4 | creates a RFC 2822 message with MIME parts | ||
5 | |||
6 | syntax: compose-msg "text" filename | ||
7 | |||
8 | |||
9 | |||
10 | all 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 | |||
26 | the default driver is mbox with the path /var/mail/$USER | ||
27 | |||
28 | frm-simple, frm, frm-tree | ||
29 | ------------------------- | ||
30 | |||
31 | frm-simple will list all the mails of a mailbox without any MIME decoding. | ||
32 | |||
33 | frm will list all the mails of a mailbox and will decode the fields. | ||
34 | |||
35 | frm-tree will do the same thing as frm and will also show the threads | ||
36 | of the folder. | ||
37 | |||
38 | |||
39 | fetch-attachment | ||
40 | ---------------- | ||
41 | |||
42 | fetch-attachment gets all the named attachment of the given message | ||
43 | of the chosen mailbox and writes them on the current directory. | ||
44 | |||
45 | The program should be given message numbers (as given by frm) as | ||
46 | additionnal arguments. | ||
47 | |||
48 | |||
49 | readmsg-simple, readmsg | ||
50 | ----------------------- | ||
51 | |||
52 | readmsg-simple will display the content of the given messages. | ||
53 | All 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 | ||
58 | additionnal 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 | |||
9 | static struct mailmime_parameter * | ||
10 | mailmime_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 | |||
41 | static 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 | |||
106 | static 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 | |||
163 | static 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 | |||
233 | static 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 | |||
253 | int 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 | |||
14 | static 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 | |||
48 | static 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 | |||
99 | static 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 | |||
152 | int 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 | |||
10 | void 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 | |||
41 | void 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 | |||
55 | void 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 | |||
7 | void get_from_value(struct mailimf_single_fields * fields, | ||
8 | char ** from, int * is_addr); | ||
9 | |||
10 | void strip_crlf(char * str); | ||
11 | |||
12 | void 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 | |||
15 | static 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 | |||
79 | static 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 | |||
131 | int 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 | |||
13 | static void | ||
14 | display_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 | |||
69 | static 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 | |||
85 | static 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 | |||
138 | int 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 | |||
13 | static 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 | |||
65 | int 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 | |||
31 | struct storage_name { | ||
32 | int id; | ||
33 | char * name; | ||
34 | }; | ||
35 | |||
36 | static 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 | |||
45 | static 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 | |||
61 | int 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 | |||
163 | int 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 | |||
7 | enum { | ||
8 | POP3_STORAGE = 0, | ||
9 | IMAP_STORAGE, | ||
10 | NNTP_STORAGE, | ||
11 | MBOX_STORAGE, | ||
12 | MH_STORAGE, | ||
13 | MAILDIR_STORAGE, | ||
14 | }; | ||
15 | |||
16 | int 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 | |||
23 | int 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 | |||
12 | int 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 | |||
33 | int 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 | ||
87 | static 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 | |||
169 | int 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 | |||
231 | struct 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 | |||
262 | static int | ||
263 | etpan_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 | |||
341 | int | ||
342 | etpan_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 | |||
376 | static int | ||
377 | etpan_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 | |||
406 | int | ||
407 | etpan_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 | |||
433 | int | ||
434 | etpan_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 | |||
468 | static 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 | |||
510 | int 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 | |||
9 | enum { | ||
10 | NO_ERROR, | ||
11 | ERROR_FILE, | ||
12 | ERROR_MEMORY, | ||
13 | ERROR_INVAL, | ||
14 | ERROR_FETCH, | ||
15 | }; | ||
16 | |||
17 | int etpan_mime_is_text(struct mailmime * build_info); | ||
18 | |||
19 | int show_part_info(FILE * f, | ||
20 | struct mailmime_single_fields * mime_fields, | ||
21 | struct mailmime_content * content); | ||
22 | |||
23 | int 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 | |||
28 | struct mailimf_fields * fetch_fields(mailmessage * msg_info, | ||
29 | struct mailmime * mime); | ||
30 | |||
31 | int 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 | |||
9 | int 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 | |||
14 | static 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 | |||
233 | int 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 */ | ||
24 | char *smtp_server; | ||
25 | uint smtp_port = 25; | ||
26 | char *smtp_user; | ||
27 | char *smtp_password; | ||
28 | char *smtp_from; | ||
29 | int smtp_tls = 0; | ||
30 | int smtp_esmtp = 1; | ||
31 | |||
32 | struct mem_message { | ||
33 | char *data; | ||
34 | size_t len; | ||
35 | MMAPString *mstring; | ||
36 | }; | ||
37 | |||
38 | #define BLOCKSIZE 4096 | ||
39 | |||
40 | int 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 | |||
86 | char *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 | |||
116 | void 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 | |||
123 | int 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 | |||
207 | int 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 | } | ||