Commit 9f739684 9f73968409cff3e3d5b59dbb5b841d5fcffca582 by Alain Magloire

* mailbox/Makefile.am: filter_trans.c added, trans_stream.c deleted.

	* mailbox/attachment.c (message_create_attachment): use
	filter_create().
	(message_save_attachment): use filter_create().
	* mailbox/body.c (body_set_lines): Wrong comparison for the owner.
	* mailbox/mbx_mbox.c: Do not count the line separtor of part
	of the mailbox.

	* mailbox/url.c (url_is_same_sheme): New function.
	(url_is_same_user): New function.
	(url_is_same_path): New function.
	(url_is_same_host): New function.
	(url_is_same_port): New function.
	* mailbox/folder.c : Moved the is_same_*() functions in url.c
	they can be generally usefull.
	(is_same_sheme): Removed.
	(is_same_user): Removed.
	(is_same_path): Removed.
	(is_same_host): Removed.
	(is_same_port): Removed.

	* mailbox/folder_imap.c (folder_imap_create): New function,
	CREATE a new mailbox.
	(folder_imap_open): Calls folder_imap_create when the MU_STREAM_CREAT
	flag is set.
	* mailbox/mbx_imap.c: Appending messages implemented, if the message
	comes from the same imap folder, it is COPY otherwise APPEND.
	(is_same_folder): New function.
	(imap_append_message): Implemented.
	(attribute_string): New functions.
	(imap_copy_message): New function.
	* mailbox/include/imap0.h: New enum, IMAP_APPEND, IMAP_APPEND_ACK,
	IMAP_APPEND_CONT, IMAP_APPEND_SEND, IMAP_COPY, IMAP_COPY_ACK,
	IMAP_CREATE, IMAP_CREATE_ACK.


* mailbox/parse822.c: New parser.
	* include/mailutils/parse822.h: New file.
	* mailbox/address.c (address_create): Remove the old parsing and use
	parse822 as the underlying engine.
	(address_parse): Removed.
	(gettoken): Removed.
	(quotes): Removed.
	(address_get_personal): Remove the code to unquote, parse822 takes
	care if it. Return value when no field is ENOENT.
	(address_get_comments): Reutrn value when no field ENOENT.
	(address_get_local_part): Reutrn value when no field ENOENT.
	(address_get_domain): Reutrn value when no field ENOENT.
	(address_get_email): Reutrn value when no field ENOENT.
	(address_get_route): Reutrn value when no field ENOENT.
	* mailbox/message.c (message_sender): Use parse822 to retrieve
	the email from the From: field.
	(message_set_mailbox): New function.
	* mailbox/misc.c : Removed the old parsing code.
	(gettoken): Removed.
	(parseaddr): Removed.
	* mailbox/include/misc.h : Removed parseaddr() prototypes.
	From Sam Roberts, the new parse822 parser..
1 parent f9979c0e
...@@ -22,6 +22,7 @@ envelope.c \ ...@@ -22,6 +22,7 @@ envelope.c \
22 file_stream.c \ 22 file_stream.c \
23 filter.c \ 23 filter.c \
24 filter_rfc822.c \ 24 filter_rfc822.c \
25 filter_trans.c \
25 folder.c \ 26 folder.c \
26 folder_imap.c \ 27 folder_imap.c \
27 folder_mbox.c \ 28 folder_mbox.c \
...@@ -50,7 +51,6 @@ sendmail.c \ ...@@ -50,7 +51,6 @@ sendmail.c \
50 smtp.c \ 51 smtp.c \
51 stream.c \ 52 stream.c \
52 tcp.c \ 53 tcp.c \
53 trans_stream.c \
54 url.c \ 54 url.c \
55 url_file.c \ 55 url_file.c \
56 url_imap.c \ 56 url_imap.c \
......
...@@ -27,297 +27,38 @@ ...@@ -27,297 +27,38 @@
27 #include <stdlib.h> 27 #include <stdlib.h>
28 #include <errno.h> 28 #include <errno.h>
29 29
30 #include <address0.h> 30 #include <mailutils/parse822.h>
31 #include <misc.h> 31 #include <misc.h>
32 32 #include <address0.h>
33 /*
34 * parseaddr.c Read a valid RFC822 address with all the comments
35 * etc in it, and return _just_ the email address.
36 *
37 * Version: @(#)parseaddr.c 1.00 02-Apr-1999 miquels@cistron.nl
38 *
39 */
40
41 struct token
42 {
43 struct token *next;
44 char word[1];
45 };
46
47 #define SKIPSPACE(p) do { while(*p && isspace((unsigned char)*p)) p++; } while(0)
48
49 /* Skip everything between quotes. */
50 static void
51 quotes (const char **ptr)
52 {
53 const char *p = *ptr;
54
55 p++;
56 while (*p && *p != '"')
57 {
58 if (*p == '\\' && p[1])
59 p++;
60 p++;
61 }
62 *ptr = p;
63 }
64
65 /* Return the next token. A token can be "<>()," or any "word". */
66 static struct token *
67 gettoken (const char **ptr)
68 {
69 struct token *tok;
70 const char *p = *ptr;
71 const char *begin;
72 int l, quit = 0;
73
74 SKIPSPACE(p);
75 begin = p;
76
77 while (!quit)
78 {
79 switch (*p)
80 {
81 case 0:
82 case ' ':
83 case '\t':
84 case '\n':
85 quit = 1;
86 break;
87 case '(':
88 case ')':
89 case '<':
90 case '>':
91 case ',':
92 if (p == begin)
93 p++;
94 quit = 1;
95 break;
96 case '\\':
97 if (p[1])
98 p++;
99 break;
100 case '"':
101 quotes (&p);
102 break;
103 }
104 if (!quit)
105 p++;
106 }
107
108 l = p - begin;
109 if (l == 0)
110 return NULL;
111 tok = malloc (sizeof (struct token) + l);
112 if (tok == NULL)
113 return NULL;
114 tok->next = NULL;
115 strncpy (tok->word, begin, l);
116 tok->word[l] = 0;
117
118 SKIPSPACE (p);
119 *ptr = p;
120
121 return tok;
122 }
123 33
124 /* Get email address from rfc822 address. */ 34 /* Get email address from rfc822 address. */
125 /* Note: This again as for header.c an awfull way of doing things.
126 Meaning I need a correct rfc822 Parser. This one does not
127 understand group. There is not doubt a better way to do this. */
128
129 static int
130 address_parse (address_t *paddress, const char **paddr)
131 {
132 const char *p;
133 struct token *t, *tok, *last;
134 struct token *brace = NULL;
135 struct token *comments = NULL;
136 struct token *start_comments = NULL;
137 address_t address;
138 int in_comment = 0;
139 int status = 0;
140
141 tok = last = NULL;
142
143 address = *paddress = calloc (1, sizeof (*address));
144 if (address == NULL)
145 return ENOMEM;
146
147 /* Read address, remove comments right away. */
148 p = *paddr;
149 while ((t = gettoken(&p)) != NULL && (t->word[0] != ',' || in_comment))
150 {
151 if (t->word[0] == '(' || t->word[0] == ')' || in_comment)
152 {
153 if (t->word[0] == '(')
154 in_comment++;
155 if (t->word[0] == ')')
156 in_comment--;
157 if (!start_comments)
158 comments = start_comments = t;
159 else
160 {
161 comments->next = t;
162 comments = t;
163 }
164 continue;
165 }
166
167 if (t->word[0] == '<')
168 brace = t;
169
170 if (tok)
171 last->next = t;
172 else
173 tok = t;
174 last = t;
175 }
176
177 if (t != NULL)
178 free (t);
179
180 /* Put extracted address into email */
181 t = brace ? brace->next : tok;
182 for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
183 {
184 char *tmp;
185 if (address->email
186 && (tmp = realloc (address->email, strlen (address->email)
187 + strlen (t->word) + 1)) != NULL)
188 {
189 address->email = tmp;
190 strcat (address->email, t->word);
191 }
192 else if ((tmp = calloc (strlen (t->word) + 1, sizeof (char))) != NULL)
193 {
194 address->email = tmp;
195 strcat (address->email, t->word);
196 }
197 else
198 {
199 address_destroy (&address);
200 status = ENOMEM;
201 goto freenodes;
202 }
203 }
204
205 /* Extract Comments. */
206 for (t = start_comments; t ; t = t->next)
207 {
208 char *tmp;
209 if (t->word[0] == '(' || t->word[0] == ')')
210 continue;
211 if (address->comments
212 && (tmp = realloc (address->comments, strlen (address->comments)
213 + strlen (t->word) + 2)) != NULL)
214 {
215 address->comments = tmp;
216 strcat (address->comments, " ");
217 strcat (address->comments, t->word);
218 }
219 else if ((tmp = calloc (strlen (t->word) + 1, sizeof (char))) != NULL)
220 {
221 address->comments = tmp;
222 strcat (address->comments, t->word);
223 }
224 else
225 {
226 address_destroy (&address);
227 status = ENOMEM;
228 goto freenodes;
229 }
230 }
231
232 /* Extract Personal. */
233 if (brace == NULL)
234 {
235 address->personal = strdup ("");
236 }
237 else
238 {
239 int in_brace = 0;
240 for (t = tok; t ; t = t->next)
241 {
242 char *tmp;
243 if (t->word[0] == '<' || t->word[0] == '>' || in_brace)
244 {
245 if (t->word[0] == '<')
246 in_brace++;
247 else if (t->word[0] == '>')
248 in_brace--;
249 continue;
250 }
251 if (address->personal
252 && (tmp = realloc (address->personal, strlen (address->personal)
253 + strlen (t->word) + 2)) != NULL)
254 {
255 address->personal = tmp;
256 strcat (address->personal, " ");
257 strcat (address->personal, t->word);
258 }
259 else if ((tmp = calloc (strlen (t->word) + 1, sizeof (char))) != NULL)
260 {
261 address->personal = tmp;
262 strcat (address->personal, t->word);
263 }
264 else
265 {
266 address_destroy (&address);
267 status = ENOMEM;
268 goto freenodes;
269 }
270 }
271 }
272
273 /* Free list of tokens. */
274 freenodes:
275 for (t = tok; t; t = last)
276 {
277 last = t->next;
278 free (t);
279 }
280 for (t = start_comments; t; t = last)
281 {
282 last = t->next;
283 free (t);
284 }
285
286 *paddr = p;
287 return status;
288 }
289
290 int 35 int
291 address_create (address_t *paddress, const char *addr) 36 address_create (address_t *a, const char *s)
292 { 37 {
293 address_t address = NULL; 38 /* 'paddress' must exist, and can't already have been initialized
294 address_t current = NULL; 39 */
295 address_t head = NULL; 40 int status;
296 const char *p = addr;
297 int status = 0;
298 41
299 if (paddress == NULL) 42 if (!a)
300 return EINVAL; 43 return EINVAL;
301 if (addr) 44
45 *a = NULL;
46 status = parse822_address_list (a, (char*) s);
47 if (status == 0)
302 { 48 {
303 while (*addr != 0) 49 /* There was a group that got parsed correctly, but had
50 * no addresses...
51 */
52 if (!*a)
53 return ENOENT;
54
55 (*a)->addr = strdup (s);
56 if (!(*a)->addr)
304 { 57 {
305 status = address_parse (&address, &addr); 58 address_destroy (a);
306 if (status == 0) 59 return ENOMEM;
307 { 60 }
308 if (head == NULL)
309 {
310 head = address;
311 head->addr = strdup (p);
312 }
313 else
314 current->next = address;
315 current = address;
316 p = addr;
317 }
318 }
319 } 61 }
320 *paddress = head;
321 return status; 62 return status;
322 } 63 }
323 64
...@@ -356,7 +97,7 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len, ...@@ -356,7 +97,7 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len,
356 size_t *n) 97 size_t *n)
357 { 98 {
358 size_t i, j; 99 size_t i, j;
359 int status = EINVAL; 100 int status = ENOENT;
360 if (addr == NULL) 101 if (addr == NULL)
361 return EINVAL; 102 return EINVAL;
362 for (i = 0, j = 1; addr; addr = addr->next, j++) 103 for (i = 0, j = 1; addr; addr = addr->next, j++)
...@@ -368,18 +109,6 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len, ...@@ -368,18 +109,6 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len,
368 break; 109 break;
369 } 110 }
370 } 111 }
371 /* Remove the leading doublequotes. */
372 if (i && buf && *buf == '"')
373 {
374 memmove (buf, buf + 1, i - 1);
375 i--;
376 }
377 /* Remove the trailing doublequotes. */
378 if (i && buf && buf[i - 1] == '"')
379 {
380 buf[i - 1] = '\0';
381 i--;
382 }
383 if (n) 112 if (n)
384 *n = i; 113 *n = i;
385 return status; 114 return status;
...@@ -390,7 +119,7 @@ address_get_comments (address_t addr, size_t no, char *buf, size_t len, ...@@ -390,7 +119,7 @@ address_get_comments (address_t addr, size_t no, char *buf, size_t len,
390 size_t *n) 119 size_t *n)
391 { 120 {
392 size_t i, j; 121 size_t i, j;
393 int status = EINVAL; 122 int status = ENOENT;
394 if (addr == NULL) 123 if (addr == NULL)
395 return EINVAL; 124 return EINVAL;
396 for (j = 1; addr; addr = addr->next, j++) 125 for (j = 1; addr; addr = addr->next, j++)
...@@ -411,7 +140,7 @@ int ...@@ -411,7 +140,7 @@ int
411 address_get_email (address_t addr, size_t no, char *buf, size_t len, size_t *n) 140 address_get_email (address_t addr, size_t no, char *buf, size_t len, size_t *n)
412 { 141 {
413 size_t i, j; 142 size_t i, j;
414 int status = EINVAL; 143 int status = ENOENT;
415 if (addr == NULL) 144 if (addr == NULL)
416 return EINVAL; 145 return EINVAL;
417 for (j = 1; addr; addr = addr->next, j++) 146 for (j = 1; addr; addr = addr->next, j++)
...@@ -432,7 +161,7 @@ int ...@@ -432,7 +161,7 @@ int
432 address_get_local_part (address_t addr, size_t no, char *buf, size_t len, size_t *n) 161 address_get_local_part (address_t addr, size_t no, char *buf, size_t len, size_t *n)
433 { 162 {
434 size_t i, j; 163 size_t i, j;
435 int status = EINVAL; 164 int status = ENOENT;
436 if (addr == NULL) 165 if (addr == NULL)
437 return EINVAL; 166 return EINVAL;
438 for (j = 1; addr; addr = addr->next, j++) 167 for (j = 1; addr; addr = addr->next, j++)
...@@ -453,7 +182,7 @@ int ...@@ -453,7 +182,7 @@ int
453 address_get_domain (address_t addr, size_t no, char *buf, size_t len, size_t *n) 182 address_get_domain (address_t addr, size_t no, char *buf, size_t len, size_t *n)
454 { 183 {
455 size_t i, j; 184 size_t i, j;
456 int status = EINVAL; 185 int status = ENOENT;
457 if (addr == NULL) 186 if (addr == NULL)
458 return EINVAL; 187 return EINVAL;
459 for (j = 1; addr; addr = addr->next, j++) 188 for (j = 1; addr; addr = addr->next, j++)
...@@ -474,7 +203,7 @@ int ...@@ -474,7 +203,7 @@ int
474 address_get_route (address_t addr, size_t no, char *buf, size_t len, size_t *n) 203 address_get_route (address_t addr, size_t no, char *buf, size_t len, size_t *n)
475 { 204 {
476 size_t i, j; 205 size_t i, j;
477 int status = EINVAL; 206 int status = ENOENT;
478 if (addr == NULL) 207 if (addr == NULL)
479 return EINVAL; 208 return EINVAL;
480 for (j = 1; addr; addr = addr->next, j++) 209 for (j = 1; addr; addr = addr->next, j++)
......
...@@ -23,9 +23,11 @@ ...@@ -23,9 +23,11 @@
23 #include <stdio.h> 23 #include <stdio.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <string.h> 25 #include <string.h>
26 #include <unistd.h>
26 #include <ctype.h> 27 #include <ctype.h>
27 28
28 #include <mailutils/message.h> 29 #include <mailutils/message.h>
30 #include <mailutils/filter.h>
29 #include <mailutils/stream.h> 31 #include <mailutils/stream.h>
30 32
31 #define MAX_HDR_LEN 256 33 #define MAX_HDR_LEN 256
...@@ -75,7 +77,7 @@ int message_create_attachment(const char *content_type, const char *encoding, co ...@@ -75,7 +77,7 @@ int message_create_attachment(const char *content_type, const char *encoding, co
75 message_get_body(*newmsg, &body); 77 message_get_body(*newmsg, &body);
76 if ( ( ret = file_stream_create(&fstream) ) == 0 ) { 78 if ( ( ret = file_stream_create(&fstream) ) == 0 ) {
77 if ( ( ret = stream_open(fstream, filename, 0, MU_STREAM_READ) ) == 0 ) { 79 if ( ( ret = stream_open(fstream, filename, 0, MU_STREAM_READ) ) == 0 ) {
78 if ( ( ret = encoder_stream_create(&tstream, fstream, encoding) ) == 0 ) { 80 if ( ( ret = filter_create(&tstream, fstream, encoding, MU_FILTER_ENCODE, MU_STREAM_READ) ) == 0 ) {
79 body_set_stream(body, tstream, *newmsg); 81 body_set_stream(body, tstream, *newmsg);
80 message_set_header(*newmsg, hdr, NULL); 82 message_set_header(*newmsg, hdr, NULL);
81 } 83 }
...@@ -245,7 +247,7 @@ int message_save_attachment(message_t msg, const char *filename, void **data) ...@@ -245,7 +247,7 @@ int message_save_attachment(message_t msg, const char *filename, void **data)
245 header_get_value(hdr, "Content-Transfer-Encoding", content_encoding, size+1, 0); 247 header_get_value(hdr, "Content-Transfer-Encoding", content_encoding, size+1, 0);
246 } else 248 } else
247 content_encoding = (char *)"7bit"; 249 content_encoding = (char *)"7bit";
248 ret = decoder_stream_create(&info->ostream, fstream, content_encoding); 250 ret = filter_create(&info->ostream, fstream, content_encoding, MU_FILTER_DECODE, MU_STREAM_READ);
249 } 251 }
250 } 252 }
251 } 253 }
......
...@@ -211,7 +211,7 @@ body_set_lines (body_t body, int (*_lines)(body_t, size_t *), void *owner) ...@@ -211,7 +211,7 @@ body_set_lines (body_t body, int (*_lines)(body_t, size_t *), void *owner)
211 { 211 {
212 if (body == NULL) 212 if (body == NULL)
213 return EINVAL; 213 return EINVAL;
214 if (body->owner == owner) 214 if (body->owner != owner)
215 return EACCES; 215 return EACCES;
216 body->_lines = _lines; 216 body->_lines = _lines;
217 return 0; 217 return 0;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 # include <pthread.h> 28 # include <pthread.h>
29 #endif 29 #endif
30 30
31 #include <mailutils/filter.h> 31 #include <filter0.h>
32 #include <mailutils/property.h> 32 #include <mailutils/property.h>
33 33
34 static int rfc822_property __P ((property_t, const char *, const char *)); 34 static int rfc822_property __P ((property_t, const char *, const char *));
...@@ -46,23 +46,17 @@ struct rfc822 ...@@ -46,23 +46,17 @@ struct rfc822
46 int residue; 46 int residue;
47 }; 47 };
48 48
49 static struct _filter _rfc822_filter = 49 static struct _filter_record _rfc822_filter =
50 { 50 {
51 "RFC822", 51 "RFC822",
52 rfc822_init, 52 rfc822_init,
53 rfc822_read,
54 rfc822_readline,
55 NULL, 53 NULL,
56 rfc822_destroy,
57 NULL, 54 NULL,
58 NULL, 55 NULL,
59 NULL,
60 0,
61 NULL
62 }; 56 };
63 57
64 /* Exported. */ 58 /* Exported. */
65 filter_t rfc822_filter = &_rfc822_filter; 59 filter_record_t rfc822_filter = &_rfc822_filter;
66 60
67 static int 61 static int
68 rfc822_property (property_t property, const char *key, const char *value) 62 rfc822_property (property_t property, const char *key, const char *value)
...@@ -82,6 +76,11 @@ rfc822_init (filter_t filter) ...@@ -82,6 +76,11 @@ rfc822_init (filter_t filter)
82 filter->data = calloc (1, sizeof (struct rfc822)); 76 filter->data = calloc (1, sizeof (struct rfc822));
83 if (filter->data == NULL) 77 if (filter->data == NULL)
84 return ENOMEM; 78 return ENOMEM;
79
80 filter->_read = rfc822_read;
81 filter->_readline = rfc822_readline;
82 filter->_destroy = rfc822_destroy;
83
85 /* We are interested in this property. */ 84 /* We are interested in this property. */
86 if ((status = stream_get_property (filter->filter_stream, &property) != 0) 85 if ((status = stream_get_property (filter->filter_stream, &property) != 0)
87 || (status = property_add_defaults (property, "LINES", "0", 86 || (status = property_add_defaults (property, "LINES", "0",
......
...@@ -34,11 +34,6 @@ ...@@ -34,11 +34,6 @@
34 /* Internal folder list. */ 34 /* Internal folder list. */
35 static list_t known_folder_list; 35 static list_t known_folder_list;
36 static int is_known_folder __P ((url_t, folder_t *)); 36 static int is_known_folder __P ((url_t, folder_t *));
37 static int is_same_scheme __P ((url_t, url_t));
38 static int is_same_user __P ((url_t, url_t));
39 static int is_same_path __P ((url_t, url_t));
40 static int is_same_host __P ((url_t, url_t));
41 static int is_same_port __P ((url_t, url_t));
42 37
43 /* Static folder lock. */ 38 /* Static folder lock. */
44 static struct _monitor folder_lock = MU_MONITOR_INITIALIZER; 39 static struct _monitor folder_lock = MU_MONITOR_INITIALIZER;
...@@ -200,6 +195,7 @@ folder_destroy (folder_t *pfolder) ...@@ -200,6 +195,7 @@ folder_destroy (folder_t *pfolder)
200 if (folder->stream) 195 if (folder->stream)
201 stream_destroy (&(folder->stream), folder); 196 stream_destroy (&(folder->stream), folder);
202 if (folder->url) 197 if (folder->url)
198
203 url_destroy (&(folder->url)); 199 url_destroy (&(folder->url));
204 free (folder); 200 free (folder);
205 } 201 }
...@@ -210,7 +206,6 @@ folder_destroy (folder_t *pfolder) ...@@ -210,7 +206,6 @@ folder_destroy (folder_t *pfolder)
210 } 206 }
211 } 207 }
212 208
213
214 /* Cover functions. */ 209 /* Cover functions. */
215 int 210 int
216 folder_open (folder_t folder, int flags) 211 folder_open (folder_t folder, int flags)
...@@ -410,8 +405,6 @@ folder_get_url (folder_t folder, url_t *purl) ...@@ -410,8 +405,6 @@ folder_get_url (folder_t folder, url_t *purl)
410 return 0; 405 return 0;
411 } 406 }
412 407
413 /* ---------------------- Private ---------------------- */
414
415 static int is_known_folder (url_t url, folder_t *pfolder) 408 static int is_known_folder (url_t url, folder_t *pfolder)
416 { 409 {
417 int ret = 0; 410 int ret = 0;
...@@ -430,126 +423,18 @@ static int is_known_folder (url_t url, folder_t *pfolder) ...@@ -430,126 +423,18 @@ static int is_known_folder (url_t url, folder_t *pfolder)
430 iterator_current (iterator, (void **)&folder); 423 iterator_current (iterator, (void **)&folder);
431 /* Check if the same URL type. */ 424 /* Check if the same URL type. */
432 if (folder && folder->url 425 if (folder && folder->url
433 && is_same_scheme (url, folder->url) 426 && url_is_same_scheme (url, folder->url)
434 && is_same_user (url, folder->url) 427 && url_is_same_user (url, folder->url)
435 && is_same_path (url, folder->url) 428 && url_is_same_host (url, folder->url)
436 && is_same_host (url, folder->url) 429 /*&& url_is_same_path (url, folder->url) */
437 && is_same_port (url, folder->url)) 430 && url_is_same_port (url, folder->url))
438 { 431 {
439 ret = 1; 432 ret = 1;
440 break; 433 break;
441 } 434 }
442 } 435 }
436 if (ret)
437 *pfolder = folder;
443 iterator_destroy (&iterator); 438 iterator_destroy (&iterator);
444 return ret; 439 return ret;
445 } 440 }
446
447 static int
448 is_same_scheme (url_t url1, url_t url2)
449 {
450 size_t i = 0, j = 0;
451 char *s1, *s2;
452 int ret = 1;
453
454 url_get_scheme (url1, NULL, 0, &i);
455 url_get_scheme (url2, NULL, 0, &j);
456 s1 = calloc (i + 1, sizeof (char));
457 if (s1)
458 {
459 url_get_scheme (url1, s1, i + 1, NULL);
460 s2 = calloc (j + 1, sizeof (char));
461 if (s2)
462 {
463 url_get_scheme (url2, s2, j + 1, NULL);
464 ret = !strcasecmp (s1, s2);
465 free (s2);
466 }
467 free (s1);
468 }
469 return ret;
470 }
471
472 static int
473 is_same_user (url_t url1, url_t url2)
474 {
475 size_t i = 0, j = 0;
476 char *s1, *s2;
477 int ret = 0;
478
479 url_get_user (url1, NULL, 0, &i);
480 url_get_user (url2, NULL, 0, &j);
481 s1 = calloc (i + 1, sizeof (char));
482 if (s1)
483 {
484 url_get_user (url1, s1, i + 1, NULL);
485 s2 = calloc (j + 1, sizeof (char));
486 if (s2)
487 {
488 url_get_user (url2, s2, j + 1, NULL);
489 ret = !strcasecmp (s1, s2);
490 free (s2);
491 }
492 free (s1);
493 }
494 return ret;
495 }
496
497 static int
498 is_same_path (url_t url1, url_t url2)
499 {
500 size_t i = 0, j = 0;
501 char *s1, *s2;
502 int ret = 0;
503
504 url_get_path (url1, NULL, 0, &i);
505 url_get_path (url2, NULL, 0, &j);
506 s1 = calloc (i + 1, sizeof (char));
507 if (s1)
508 {
509 url_get_path (url1, s1, i + 1, NULL);
510 s2 = calloc (j + 1, sizeof (char));
511 if (s2)
512 {
513 url_get_path (url2, s2, j + 1, NULL);
514 ret = !strcasecmp (s1, s2);
515 free (s2);
516 }
517 free (s1);
518 }
519 return ret;
520 }
521
522 static int
523 is_same_host (url_t url1, url_t url2)
524 {
525 size_t i = 0, j = 0;
526 char *s1, *s2;
527 int ret = 0;
528
529 url_get_host (url1, NULL, 0, &i);
530 url_get_host (url2, NULL, 0, &j);
531 s1 = calloc (i + 1, sizeof (char));
532 if (s1)
533 {
534 url_get_host (url1, s1, i + 1, NULL);
535 s2 = calloc (j + 1, sizeof (char));
536 if (s2)
537 {
538 url_get_host (url2, s2, j + 1, NULL);
539 ret = !strcasecmp (s1, s2);
540 free (s2);
541 }
542 free (s1);
543 }
544 return ret;
545 }
546
547 static int
548 is_same_port (url_t url1, url_t url2)
549 {
550 long p1 = 0, p2 = 0;
551
552 url_get_port (url1, &p1);
553 url_get_port (url2, &p2);
554 return (p1 == p2);
555 }
......
...@@ -53,6 +53,7 @@ record_t imap_record = &_imap_record; ...@@ -53,6 +53,7 @@ record_t imap_record = &_imap_record;
53 53
54 /* Concrete IMAP implementation. */ 54 /* Concrete IMAP implementation. */
55 static int folder_imap_open __P ((folder_t, int)); 55 static int folder_imap_open __P ((folder_t, int));
56 static int folder_imap_create __P ((folder_t));
56 static int folder_imap_close __P ((folder_t)); 57 static int folder_imap_close __P ((folder_t));
57 static void folder_imap_destroy __P ((folder_t)); 58 static void folder_imap_destroy __P ((folder_t));
58 static int folder_imap_delete __P ((folder_t, const char *)); 59 static int folder_imap_delete __P ((folder_t, const char *));
...@@ -211,7 +212,9 @@ folder_imap_open (folder_t folder, int flags) ...@@ -211,7 +212,9 @@ folder_imap_open (folder_t folder, int flags)
211 monitor_wrlock (folder->monitor); 212 monitor_wrlock (folder->monitor);
212 if (f_imap->isopen) 213 if (f_imap->isopen)
213 { 214 {
214 monitor_wrlock (folder->monitor); 215 monitor_unlock (folder->monitor);
216 if (flags & MU_STREAM_CREAT)
217 status = folder_imap_create (folder);
215 return 0; 218 return 0;
216 } 219 }
217 monitor_unlock (folder->monitor); 220 monitor_unlock (folder->monitor);
...@@ -324,6 +327,11 @@ folder_imap_open (folder_t folder, int flags) ...@@ -324,6 +327,11 @@ folder_imap_open (folder_t folder, int flags)
324 monitor_wrlock (folder->monitor); 327 monitor_wrlock (folder->monitor);
325 f_imap->isopen++; 328 f_imap->isopen++;
326 monitor_unlock (folder->monitor); 329 monitor_unlock (folder->monitor);
330 if (flags & MU_STREAM_CREAT)
331 {
332 status = folder_imap_create (folder);
333 CHECK_EAGAIN (f_imap, status);
334 }
327 return 0; 335 return 0;
328 } 336 }
329 337
...@@ -372,6 +380,51 @@ folder_imap_close (folder_t folder) ...@@ -372,6 +380,51 @@ folder_imap_close (folder_t folder)
372 return 0; 380 return 0;
373 } 381 }
374 382
383 /* Create a folder/mailbox. */
384 static int
385 folder_imap_create (folder_t folder)
386 {
387 f_imap_t f_imap = folder->data;
388 int status = 0;
389
390 switch (f_imap->state)
391 {
392 case IMAP_NO_STATE:
393 {
394 char *path;
395 size_t len;
396 url_get_path (folder->url, NULL, 0, &len);
397 if (len == 0)
398 return 0;
399 path = calloc (len + 1, sizeof (*path));
400 if (path == NULL)
401 return ENOMEM;
402 url_get_path (folder->url, path, len + 1, NULL);
403 status = imap_writeline (f_imap, "g%d CREATE %s\r\n", f_imap->seq++,
404 path);
405 free (path);
406 CHECK_ERROR (f_imap, status);
407 FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
408 f_imap->state = IMAP_CREATE;
409 }
410
411 case IMAP_CREATE:
412 status = imap_send (f_imap);
413 CHECK_EAGAIN (f_imap, status);
414 f_imap->state = IMAP_DELETE_ACK;
415
416 case IMAP_CREATE_ACK:
417 status = imap_parse (f_imap);
418 CHECK_EAGAIN (f_imap, status);
419 FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
420
421 default:
422 break;
423 }
424 f_imap->state = IMAP_NO_STATE;
425 return status;
426 }
427
375 /* Remove a mailbox. */ 428 /* Remove a mailbox. */
376 static int 429 static int
377 folder_imap_delete (folder_t folder, const char *name) 430 folder_imap_delete (folder_t folder, const char *name)
...@@ -1528,9 +1581,9 @@ int ...@@ -1528,9 +1581,9 @@ int
1528 imap_send (f_imap_t f_imap) 1581 imap_send (f_imap_t f_imap)
1529 { 1582 {
1530 int status = 0; 1583 int status = 0;
1531 size_t len;
1532 if (f_imap->ptr > f_imap->buffer) 1584 if (f_imap->ptr > f_imap->buffer)
1533 { 1585 {
1586 size_t len;
1534 len = f_imap->ptr - f_imap->buffer; 1587 len = f_imap->ptr - f_imap->buffer;
1535 status = stream_write (f_imap->folder->stream, f_imap->buffer, len, 1588 status = stream_write (f_imap->folder->stream, f_imap->buffer, len,
1536 0, &len); 1589 0, &len);
...@@ -1543,7 +1596,6 @@ imap_send (f_imap_t f_imap) ...@@ -1543,7 +1596,6 @@ imap_send (f_imap_t f_imap)
1543 else 1596 else
1544 { 1597 {
1545 f_imap->ptr = f_imap->buffer; 1598 f_imap->ptr = f_imap->buffer;
1546 len = 0;
1547 } 1599 }
1548 return status; 1600 return status;
1549 } 1601 }
...@@ -1823,18 +1875,18 @@ imap_parse (f_imap_t f_imap) ...@@ -1823,18 +1875,18 @@ imap_parse (f_imap_t f_imap)
1823 { 1875 {
1824 /* Not sure why we would get an untagged ok...but we do... */ 1876 /* Not sure why we would get an untagged ok...but we do... */
1825 /* Still should we be verbose about is ? */ 1877 /* Still should we be verbose about is ? */
1826 printf("Untagged OK: %s\n", remainder); 1878 fprintf (stderr, "Untagged OK: %s\n", remainder);
1827 } 1879 }
1828 } 1880 }
1829 else if (strcasecmp (response, "NO") == 0) 1881 else if (strcasecmp (response, "NO") == 0)
1830 { 1882 {
1831 /* This does not mean failure but rather a strong warning. */ 1883 /* This does not mean failure but rather a strong warning. */
1832 printf ("Untagged NO: %s\n", remainder); 1884 fprintf (stderr, "Untagged NO: %s\n", remainder);
1833 } 1885 }
1834 else if (strcasecmp (response, "BAD") == 0) 1886 else if (strcasecmp (response, "BAD") == 0)
1835 { 1887 {
1836 /* We're dead, protocol/syntax error. */ 1888 /* We're dead, protocol/syntax error. */
1837 printf ("Untagged BAD: %s\n", remainder); 1889 fprintf (stderr, "Untagged BAD: %s\n", remainder);
1838 } 1890 }
1839 else if (strcasecmp (response, "PREAUTH") == 0) 1891 else if (strcasecmp (response, "PREAUTH") == 0)
1840 { 1892 {
...@@ -1893,8 +1945,8 @@ imap_parse (f_imap_t f_imap) ...@@ -1893,8 +1945,8 @@ imap_parse (f_imap_t f_imap)
1893 else 1945 else
1894 { 1946 {
1895 /* Once again, check for something strange. */ 1947 /* Once again, check for something strange. */
1896 printf("unknown untagged response: \"%s\" %s\n", 1948 fprintf (stderr, "unknown untagged response: \"%s\" %s\n",
1897 response, remainder); 1949 response, remainder);
1898 } 1950 }
1899 } 1951 }
1900 /* Continuation token ???. */ 1952 /* Continuation token ???. */
...@@ -1917,7 +1969,7 @@ imap_parse (f_imap_t f_imap) ...@@ -1917,7 +1969,7 @@ imap_parse (f_imap_t f_imap)
1917 folder_get_observable (f_imap->folder, &observable); 1969 folder_get_observable (f_imap->folder, &observable);
1918 observable_notify (observable, MU_EVT_AUTHORITY_FAILED); 1970 observable_notify (observable, MU_EVT_AUTHORITY_FAILED);
1919 } 1971 }
1920 printf("NO/Bad Tagged: %s %s\n", response, remainder); 1972 fprintf (stderr, "NO/Bad Tagged: %s %s\n", response, remainder);
1921 status = EINVAL; 1973 status = EINVAL;
1922 } 1974 }
1923 } 1975 }
......
...@@ -5,6 +5,7 @@ auth0.h \ ...@@ -5,6 +5,7 @@ auth0.h \
5 body0.h \ 5 body0.h \
6 debug0.h \ 6 debug0.h \
7 envelope0.h \ 7 envelope0.h \
8 filter0.h \
8 folder0.h \ 9 folder0.h \
9 header0.h \ 10 header0.h \
10 iterator0.h \ 11 iterator0.h \
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 /* Notes:
19
20 */
21
22 #ifndef _FILTER0_H
23 #define _FILTER0_H
24
25 #include <mailutils/filter.h>
26 #include <mailutils/list.h>
27 #include <mailutils/monitor.h>
28 #include <mailutils/property.h>
29
30 #ifndef __P
31 # ifdef __STDC__
32 # define __P(args) args
33 # else
34 # define __P(args) ()
35 # endif
36 #endif /*__P */
37
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41
42 struct _filter
43 {
44 stream_t stream;
45 stream_t filter_stream;
46 property_t property;
47 int direction;
48 int type;
49 void *data;
50 int (*_read) __P ((filter_t, char *, size_t, off_t, size_t *));
51 int (*_readline) __P ((filter_t, char *, size_t, off_t, size_t *));
52 int (*_write) __P ((filter_t, const char *, size_t, off_t, size_t *));
53 void (*_destroy) __P ((filter_t));
54 };
55
56 #ifdef __cplusplus
57 }
58 #endif
59
60 #endif /* _FILTER0_H */
...@@ -93,8 +93,11 @@ enum imap_state ...@@ -93,8 +93,11 @@ enum imap_state
93 { 93 {
94 IMAP_NO_STATE=0, 94 IMAP_NO_STATE=0,
95 IMAP_AUTH, IMAP_AUTH_DONE, 95 IMAP_AUTH, IMAP_AUTH_DONE,
96 IMAP_APPEND, IMAP_APPEND_CONT, IMAP_APPEND_SEND, IMAP_APPEND_ACK,
96 IMAP_BODY, 97 IMAP_BODY,
97 IMAP_CLOSE, IMAP_CLOSE_ACK, 98 IMAP_CLOSE, IMAP_CLOSE_ACK,
99 IMAP_COPY, IMAP_COPY_ACK,
100 IMAP_CREATE, IMAP_CREATE_ACK,
98 IMAP_DELETE, IMAP_DELETE_ACK, 101 IMAP_DELETE, IMAP_DELETE_ACK,
99 IMAP_FETCH, IMAP_FETCH_ACK, 102 IMAP_FETCH, IMAP_FETCH_ACK,
100 IMAP_GREETINGS, 103 IMAP_GREETINGS,
......
1 /* GNU mailutils - a suite of utilities for electronic mail 1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 3
4 This program is free software; you can redistribute it and/or modify 4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by 5 it under the terms of the GNU General Library Public License as published by
...@@ -39,8 +39,8 @@ extern "C" { ...@@ -39,8 +39,8 @@ extern "C" {
39 # define __P(x) 39 # define __P(x)
40 # endif 40 # endif
41 #endif 41 #endif
42
42 extern size_t _cpystr __P ((char *dst, const char *src, size_t size)); 43 extern size_t _cpystr __P ((char *dst, const char *src, size_t size));
43 extern int parseaddr __P ((const char *addr, char *buf, size_t bufsz));
44 44
45 #ifdef __cplusplus 45 #ifdef __cplusplus
46 } 46 }
......
...@@ -69,7 +69,7 @@ mailbox_create (mailbox_t *pmbox, const char *name) ...@@ -69,7 +69,7 @@ mailbox_create (mailbox_t *pmbox, const char *name)
69 if (found) 69 if (found)
70 { 70 {
71 url_t url = NULL; 71 url_t url = NULL;
72 mailbox_t mbox = NULL; 72 mailbox_t mbox;
73 73
74 /* Allocate memory for mbox. */ 74 /* Allocate memory for mbox. */
75 mbox = calloc (1, sizeof (*mbox)); 75 mbox = calloc (1, sizeof (*mbox));
......
...@@ -1124,7 +1124,7 @@ mbox_body_size (body_t body, size_t *psize) ...@@ -1124,7 +1124,7 @@ mbox_body_size (body_t body, size_t *psize)
1124 if (mum == NULL) 1124 if (mum == NULL)
1125 return EINVAL; 1125 return EINVAL;
1126 if (psize) 1126 if (psize)
1127 *psize = mum->body_end - mum->body + 1; 1127 *psize = mum->body_end - mum->body;
1128 return 0; 1128 return 0;
1129 } 1129 }
1130 1130
......
...@@ -1770,9 +1770,9 @@ static int ...@@ -1770,9 +1770,9 @@ static int
1770 pop_write (pop_data_t mpd) 1770 pop_write (pop_data_t mpd)
1771 { 1771 {
1772 int status = 0; 1772 int status = 0;
1773 size_t len;
1774 if (mpd->ptr > mpd->buffer) 1773 if (mpd->ptr > mpd->buffer)
1775 { 1774 {
1775 size_t len;
1776 len = mpd->ptr - mpd->buffer; 1776 len = mpd->ptr - mpd->buffer;
1777 status = stream_write (mpd->mbox->stream, mpd->buffer, len, 0, &len); 1777 status = stream_write (mpd->mbox->stream, mpd->buffer, len, 0, &len);
1778 if (status == 0) 1778 if (status == 0)
...@@ -1782,10 +1782,7 @@ pop_write (pop_data_t mpd) ...@@ -1782,10 +1782,7 @@ pop_write (pop_data_t mpd)
1782 } 1782 }
1783 } 1783 }
1784 else 1784 else
1785 { 1785 mpd->ptr = mpd->buffer;
1786 mpd->ptr = mpd->buffer;
1787 len = 0;
1788 }
1789 return status; 1786 return status;
1790 } 1787 }
1791 1788
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
30 30
31 #include "md5.h" 31 #include "md5.h"
32 32
33 #include <misc.h>
34 #include <message0.h> 33 #include <message0.h>
34 #include <mailutils/address.h>
35 35
36 static int message_read __P ((stream_t is, char *buf, size_t buflen, 36 static int message_read __P ((stream_t is, char *buf, size_t buflen,
37 off_t off, size_t *pnread )); 37 off_t off, size_t *pnread ));
...@@ -213,6 +213,15 @@ message_get_property (message_t msg, property_t *pproperty) ...@@ -213,6 +213,15 @@ message_get_property (message_t msg, property_t *pproperty)
213 } 213 }
214 214
215 int 215 int
216 message_get_mailbox (message_t msg, mailbox_t *pmailbox)
217 {
218 if (msg == NULL || pmailbox == NULL)
219 return EINVAL;
220 *pmailbox = msg->mailbox;
221 return 0;
222 }
223
224 int
216 message_set_mailbox (message_t msg, mailbox_t mailbox, void *owner) 225 message_set_mailbox (message_t msg, mailbox_t mailbox, void *owner)
217 { 226 {
218 if (msg == NULL) 227 if (msg == NULL)
...@@ -894,34 +903,16 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) ...@@ -894,34 +903,16 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
894 if (status == 0 && n != 0) 903 if (status == 0 && n != 0)
895 { 904 {
896 char *sender; 905 char *sender;
897 char *addr; 906 address_t address = NULL;
898 sender = calloc (1, n + 1); 907 sender = calloc (1, n + 1);
899 if (sender == NULL) 908 if (sender == NULL)
900 return ENOMEM; 909 return ENOMEM;
901 addr = calloc (1, n + 1);
902 if (addr == NULL)
903 {
904 free (sender);
905 return ENOMEM;
906 }
907 header_get_value (header, MU_HEADER_FROM, sender, n + 1, NULL); 910 header_get_value (header, MU_HEADER_FROM, sender, n + 1, NULL);
908 if (parseaddr (sender, addr, n + 1) == 0) 911 if (address_create (&address, sender) == 0)
909 { 912 address_get_email (address, 1, buf, n + 1, pnwrite);
910 size_t i = strlen (addr);
911 n = (i > len) ? len : i;
912 if (buf && len > 0)
913 {
914 memcpy (buf, addr, n);
915 buf[n] = '\0';
916 }
917 free (addr);
918 free (sender);
919 if (pnwrite)
920 *pnwrite = n;
921 return 0;
922 }
923 free (addr);
924 free (sender); 913 free (sender);
914 address_destroy (&address);
915 return 0;
925 } 916 }
926 else if (status == EAGAIN) 917 else if (status == EAGAIN)
927 return status; 918 return status;
......
1 /* GNU mailutils - a suite of utilities for electronic mail 1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 3
4 This program is free software; you can redistribute it and/or modify 4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by 5 it under the terms of the GNU General Library Public License as published by
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
27 #include <ctype.h> 27 #include <ctype.h>
28 #include <stdlib.h> 28 #include <stdlib.h>
29 29
30 /* Smart strncpy that always add the null and returns the number of bytes
31 written. */
30 size_t 32 size_t
31 _cpystr (char *dst, const char *src, size_t size) 33 _cpystr (char *dst, const char *src, size_t size)
32 { 34 {
...@@ -39,153 +41,3 @@ _cpystr (char *dst, const char *src, size_t size) ...@@ -39,153 +41,3 @@ _cpystr (char *dst, const char *src, size_t size)
39 dst[len] = '\0'; 41 dst[len] = '\0';
40 return len; 42 return len;
41 } 43 }
42
43 /*
44 * parseaddr.c Read a valid RFC822 address with all the comments
45 * etc in it, and return _just_ the email address.
46 *
47 * Version: @(#)parseaddr.c 1.00 02-Apr-1999 miquels@cistron.nl
48 *
49 */
50
51
52 struct token
53 {
54 struct token *next;
55 char word[1];
56 };
57
58 #define SKIPSPACE(p) do { while(*p && isspace((unsigned char)*p)) p++; } while(0)
59
60 /* Skip everything between quotes. */
61 static void
62 quotes (const char **ptr)
63 {
64 const char *p = *ptr;
65
66 p++;
67 while (*p && *p != '"')
68 {
69 if (*p == '\\' && p[1])
70 p++;
71 p++;
72 }
73 *ptr = p;
74 }
75
76 /* Return the next token. A token can be "<>()," or any "word". */
77 static struct token *
78 gettoken (const char **ptr)
79 {
80 struct token *tok;
81 const char *p = *ptr;
82 const char *begin;
83 int l, quit = 0;
84
85 SKIPSPACE(p);
86 begin = p;
87
88 while (!quit)
89 {
90 switch (*p)
91 {
92 case 0:
93 case ' ':
94 case '\t':
95 case '\n':
96 quit = 1;
97 break;
98 case '(':
99 case ')':
100 case '<':
101 case '>':
102 case ',':
103 if (p == begin)
104 p++;
105 quit = 1;
106 break;
107 case '\\':
108 if (p[1])
109 p++;
110 break;
111 case '"':
112 quotes (&p);
113 break;
114 }
115 if (!quit)
116 p++;
117 }
118
119 l = p - begin;
120 if (l == 0)
121 return NULL;
122 tok = malloc (sizeof (struct token) + l);
123 if (tok == NULL)
124 return NULL;
125 tok->next = NULL;
126 strncpy (tok->word, begin, l);
127 tok->word[l] = 0;
128
129 SKIPSPACE (p);
130 *ptr = p;
131
132 return tok;
133 }
134
135 /* Get email address from rfc822 address. */
136 int
137 parseaddr (const char *addr, char *buf, size_t bufsz)
138 {
139 const char *p;
140 struct token *t, *tok, *last;
141 struct token *brace = NULL;
142 int comment = 0;
143 int status = 0;
144
145 tok = last = NULL;
146
147 /* Read address, remove comments right away. */
148 p = addr;
149 while ((t = gettoken(&p)) != NULL && t->word[0] != ',')
150 {
151 if (t->word[0] == '(' || t->word[0] == ')' || comment)
152 {
153 free (t);
154 if (t->word[0] == '(')
155 comment++;
156 if (t->word[0] == ')')
157 comment--;
158 continue;
159 }
160 if (t->word[0] == '<')
161 brace = t;
162 if (tok)
163 last->next = t;
164 else
165 tok = t;
166 last = t;
167 }
168
169 /* Put extracted address into "buf" */
170 buf[0] = 0;
171 t = brace ? brace->next : tok;
172 for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
173 {
174 if (strlen (t->word) >= bufsz)
175 {
176 status = -1;
177 break;
178 }
179 bufsz -= strlen (t->word);
180 strcat (buf, t->word);
181 }
182
183 /* Free list of tokens. */
184 for (t = tok; t; t = last)
185 {
186 last = t->next;
187 free (t);
188 }
189
190 return status;
191 }
......
...@@ -95,7 +95,7 @@ static int str_append_n(char** to, const char* from, size_t n) ...@@ -95,7 +95,7 @@ static int str_append_n(char** to, const char* from, size_t n)
95 if(!bigger) { 95 if(!bigger) {
96 return ENOMEM; 96 return ENOMEM;
97 } 97 }
98 98
99 *to = bigger; 99 *to = bigger;
100 } else { 100 } else {
101 *to = malloc(n + 1); 101 *to = malloc(n + 1);
...@@ -283,7 +283,7 @@ int parse822_comment(const char** p, const char* e, char** comment) ...@@ -283,7 +283,7 @@ int parse822_comment(const char** p, const char* e, char** comment)
283 if((rc = parse822_special(p, e, '('))) { 283 if((rc = parse822_special(p, e, '('))) {
284 return rc; 284 return rc;
285 } 285 }
286 286
287 while(*p != e) { 287 while(*p != e) {
288 char c = **p; 288 char c = **p;
289 289
...@@ -307,7 +307,7 @@ int parse822_comment(const char** p, const char* e, char** comment) ...@@ -307,7 +307,7 @@ int parse822_comment(const char** p, const char* e, char** comment)
307 if(rc != EOK) 307 if(rc != EOK)
308 break; 308 break;
309 } 309 }
310 310
311 if(*p == e) { 311 if(*p == e) {
312 rc = EPARSE; /* end-of-comment not found */ 312 rc = EPARSE; /* end-of-comment not found */
313 } 313 }
...@@ -536,6 +536,8 @@ static int fill_mb( ...@@ -536,6 +536,8 @@ static int fill_mb(
536 return rc; 536 return rc;
537 } 537 }
538 538
539 /* FIXME: Delete this one. adddress.c do the work now. */
540 #if 0
539 int address_create0 (address_t* a, const char* s) 541 int address_create0 (address_t* a, const char* s)
540 { 542 {
541 /* 'a' must exist, and can't already have been initialized 543 /* 'a' must exist, and can't already have been initialized
...@@ -546,7 +548,7 @@ int address_create0 (address_t* a, const char* s) ...@@ -546,7 +548,7 @@ int address_create0 (address_t* a, const char* s)
546 if(!a || *a) { 548 if(!a || *a) {
547 return EINVAL; 549 return EINVAL;
548 } 550 }
549 551
550 status = parse822_address_list(a, (char*) s); 552 status = parse822_address_list(a, (char*) s);
551 553
552 if(status == EOK) { 554 if(status == EOK) {
...@@ -566,6 +568,7 @@ int address_create0 (address_t* a, const char* s) ...@@ -566,6 +568,7 @@ int address_create0 (address_t* a, const char* s)
566 568
567 return status; 569 return status;
568 } 570 }
571 #endif
569 572
570 int parse822_address_list(address_t* a, const char* s) 573 int parse822_address_list(address_t* a, const char* s)
571 { 574 {
...@@ -585,7 +588,7 @@ int parse822_address_list(address_t* a, const char* s) ...@@ -585,7 +588,7 @@ int parse822_address_list(address_t* a, const char* s)
585 { 588 {
586 /* An address can contain a group, so an entire 589 /* An address can contain a group, so an entire
587 * list of addresses may have been appended, or no 590 * list of addresses may have been appended, or no
588 * addresses at all. Walk to the end. 591 * addresses at all. Walk to the end.
589 */ 592 */
590 while(*n) { 593 while(*n) {
591 n = &(*n)->next; 594 n = &(*n)->next;
...@@ -626,7 +629,7 @@ int parse822_address(const char** p, const char* e, address_t* a) ...@@ -626,7 +629,7 @@ int parse822_address(const char** p, const char* e, address_t* a)
626 /* address = mailbox / group */ 629 /* address = mailbox / group */
627 630
628 int rc; 631 int rc;
629 632
630 if((rc = parse822_mail_box(p, e, a)) == EPARSE) 633 if((rc = parse822_mail_box(p, e, a)) == EPARSE)
631 rc = parse822_group(p, e, a); 634 rc = parse822_group(p, e, a);
632 635
...@@ -672,7 +675,7 @@ int parse822_group(const char** p, const char* e, address_t* a) ...@@ -672,7 +675,7 @@ int parse822_group(const char** p, const char* e, address_t* a)
672 } else if(rc != EPARSE) { 675 } else if(rc != EPARSE) {
673 break; 676 break;
674 } 677 }
675 678
676 if((rc = parse822_special(p, e, ','))) { 679 if((rc = parse822_special(p, e, ','))) {
677 /* the commas aren't optional */ 680 /* the commas aren't optional */
678 break; 681 break;
...@@ -785,7 +788,7 @@ int parse822_route_addr(const char** p, const char* e, address_t* a) ...@@ -785,7 +788,7 @@ int parse822_route_addr(const char** p, const char* e, address_t* a)
785 *p = save; 788 *p = save;
786 789
787 address_destroy(a); 790 address_destroy(a);
788 791
789 return rc; 792 return rc;
790 } 793 }
791 794
...@@ -898,7 +901,7 @@ int parse822_local_part(const char** p, const char* e, char** local_part) ...@@ -898,7 +901,7 @@ int parse822_local_part(const char** p, const char* e, char** local_part)
898 return rc; 901 return rc;
899 } 902 }
900 /* We've got a local-part, but keep looking for more. */ 903 /* We've got a local-part, but keep looking for more. */
901 904
902 parse822_skip_comments(p, e); 905 parse822_skip_comments(p, e);
903 906
904 /* If we get a parse error, we roll back to save2, but if 907 /* If we get a parse error, we roll back to save2, but if
...@@ -992,7 +995,7 @@ int parse822_sub_domain(const char** p, const char* e, char** sub_domain) ...@@ -992,7 +995,7 @@ int parse822_sub_domain(const char** p, const char* e, char** sub_domain)
992 */ 995 */
993 996
994 int rc; 997 int rc;
995 998
996 if((rc = parse822_domain_ref(p, e, sub_domain)) == EPARSE) 999 if((rc = parse822_domain_ref(p, e, sub_domain)) == EPARSE)
997 rc = parse822_domain_literal(p, e, sub_domain); 1000 rc = parse822_domain_literal(p, e, sub_domain);
998 1001
...@@ -1157,6 +1160,4 @@ int parse822_field_body(const char** p, const char* e, Rope& fieldbody) ...@@ -1157,6 +1160,4 @@ int parse822_field_body(const char** p, const char* e, Rope& fieldbody)
1157 1160
1158 return 1; 1161 return 1;
1159 } 1162 }
1160
1161 #endif 1163 #endif
1162
......
1 /* GNU mailutils - a suite of utilities for electronic mail 1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 3
4 This program is free software; you can redistribute it and/or modify 4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by 5 it under the terms of the GNU General Library Public License as published by
...@@ -196,3 +196,113 @@ url_to_string (const url_t url) ...@@ -196,3 +196,113 @@ url_to_string (const url_t url)
196 return ""; 196 return "";
197 return url->name; 197 return url->name;
198 } 198 }
199
200 int
201 url_is_same_scheme (url_t url1, url_t url2)
202 {
203 size_t i = 0, j = 0;
204 char *s1, *s2;
205 int ret = 1;
206
207 url_get_scheme (url1, NULL, 0, &i);
208 url_get_scheme (url2, NULL, 0, &j);
209 s1 = calloc (i + 1, sizeof (char));
210 if (s1)
211 {
212 url_get_scheme (url1, s1, i + 1, NULL);
213 s2 = calloc (j + 1, sizeof (char));
214 if (s2)
215 {
216 url_get_scheme (url2, s2, j + 1, NULL);
217 ret = !strcasecmp (s1, s2);
218 free (s2);
219 }
220 free (s1);
221 }
222 return ret;
223 }
224
225 int
226 url_is_same_user (url_t url1, url_t url2)
227 {
228 size_t i = 0, j = 0;
229 char *s1, *s2;
230 int ret = 0;
231
232 url_get_user (url1, NULL, 0, &i);
233 url_get_user (url2, NULL, 0, &j);
234 s1 = calloc (i + 1, sizeof (char));
235 if (s1)
236 {
237 url_get_user (url1, s1, i + 1, NULL);
238 s2 = calloc (j + 1, sizeof (char));
239 if (s2)
240 {
241 url_get_user (url2, s2, j + 1, NULL);
242 ret = !strcasecmp (s1, s2);
243 free (s2);
244 }
245 free (s1);
246 }
247 return ret;
248 }
249
250 int
251 url_is_same_path (url_t url1, url_t url2)
252 {
253 size_t i = 0, j = 0;
254 char *s1, *s2;
255 int ret = 0;
256
257 url_get_path (url1, NULL, 0, &i);
258 url_get_path (url2, NULL, 0, &j);
259 s1 = calloc (i + 1, sizeof (char));
260 if (s1)
261 {
262 url_get_path (url1, s1, i + 1, NULL);
263 s2 = calloc (j + 1, sizeof (char));
264 if (s2)
265 {
266 url_get_path (url2, s2, j + 1, NULL);
267 ret = !strcasecmp (s1, s2);
268 free (s2);
269 }
270 free (s1);
271 }
272 return ret;
273 }
274
275 int
276 url_is_same_host (url_t url1, url_t url2)
277 {
278 size_t i = 0, j = 0;
279 char *s1, *s2;
280 int ret = 0;
281
282 url_get_host (url1, NULL, 0, &i);
283 url_get_host (url2, NULL, 0, &j);
284 s1 = calloc (i + 1, sizeof (char));
285 if (s1)
286 {
287 url_get_host (url1, s1, i + 1, NULL);
288 s2 = calloc (j + 1, sizeof (char));
289 if (s2)
290 {
291 url_get_host (url2, s2, j + 1, NULL);
292 ret = !strcasecmp (s1, s2);
293 free (s2);
294 }
295 free (s1);
296 }
297 return ret;
298 }
299
300 int
301 url_is_same_port (url_t url1, url_t url2)
302 {
303 long p1 = 0, p2 = 0;
304
305 url_get_port (url1, &p1);
306 url_get_port (url2, &p2);
307 return (p1 == p2);
308 }
......