Commit d971eaba d971eaba5417d3a06c332d1a6bf1929bb51f4d90 by Sergey Poznyakoff

Improve RFC822 address parsing.

* examples/addr.c: Allow to modify hints via command line (-v)
and within the shell (\...).
* include/mailutils/address.h (MU_ADDR_HINT_*): New defines.
(struct _mu_address): Definition.
(mu_address_create_hint): New prototype.
* include/mailutils/parse822.h (mu_parse822_address_list)
(mu_parse822_mail_box, mu_parse822_group)
(mu_parse822_address, mu_parse822_route_addr)
(mu_parse822_route, mu_parse822_addr_spec)
(mu_parse822_unix_mbox, mu_parse822_local_part): Take hint and hint flags.
* mailbox/parse822.c: Likewise.

* libproto/include/Makefile.am (noinst_HEADERS): Remove address0.h
* libproto/include/address0.h: Removed.
* mailbox/address.c (mu_address_create_hint): New function.
(mu_address_create): Rewrite using mu_address_create_hint.

* mh/mh_init.c (mh_expand_aliases): Use mu_header_sget_field_name
* mh/mh_whom.c (mh_alias_expand): Rewrite using mu_address_create_hint.
This fixes parsing addresses similar to "a@b <a@b>".
* mh/send.c: New command line option --preserve (--keep)
1 parent b1594c2a
...@@ -26,10 +26,14 @@ ...@@ -26,10 +26,14 @@
26 26
27 #include <mailutils/address.h> 27 #include <mailutils/address.h>
28 #include <mailutils/errno.h> 28 #include <mailutils/errno.h>
29 #include <mailutils/kwd.h>
29 #include <mailutils/mutil.h> 30 #include <mailutils/mutil.h>
30 31
31 #define EPARSE MU_ERR_NOENT 32 #define EPARSE MU_ERR_NOENT
32 33
34 struct _mu_address hint;
35 int hflags;
36
33 static int 37 static int
34 parse (const char *str) 38 parse (const char *str)
35 { 39 {
...@@ -39,8 +43,7 @@ parse (const char *str) ...@@ -39,8 +43,7 @@ parse (const char *str)
39 const char *buf; 43 const char *buf;
40 mu_address_t address = NULL; 44 mu_address_t address = NULL;
41 45
42 mu_set_user_email_domain ("localhost"); 46 status = mu_address_create_hint (&address, str, &hint, hflags);
43 status = mu_address_create (&address, str);
44 mu_address_get_count (address, &pcount); 47 mu_address_get_count (address, &pcount);
45 48
46 if (status) 49 if (status)
...@@ -96,6 +99,73 @@ parse (const char *str) ...@@ -96,6 +99,73 @@ parse (const char *str)
96 return 0; 99 return 0;
97 } 100 }
98 101
102 struct mu_kwd hintnames[] = {
103 { "comments", MU_ADDR_HINT_COMMENTS },
104 { "personal", MU_ADDR_HINT_PERSONAL },
105 { "email", MU_ADDR_HINT_EMAIL },
106 { "local", MU_ADDR_HINT_LOCAL },
107 { "domain", MU_ADDR_HINT_DOMAIN },
108 { "route", MU_ADDR_HINT_ROUTE },
109 { NULL }
110 };
111
112 static char **
113 addr_fieldptr_by_mask (mu_address_t addr, int mask)
114 {
115 switch (mask)
116 {
117 case MU_ADDR_HINT_ADDR:
118 return &addr->addr;
119
120 case MU_ADDR_HINT_COMMENTS:
121 return &addr->comments;
122
123 case MU_ADDR_HINT_PERSONAL:
124 return &addr->personal;
125
126 case MU_ADDR_HINT_EMAIL:
127 return &addr->email;
128
129 case MU_ADDR_HINT_LOCAL:
130 return &addr->local_part;
131
132 case MU_ADDR_HINT_DOMAIN:
133 return &addr->domain;
134
135 case MU_ADDR_HINT_ROUTE:
136 return &addr->route;
137 }
138 return NULL;
139 }
140
141 void
142 sethint (char *str)
143 {
144 int mask;
145 char *p = strchr (str, '=');
146
147 if (!p)
148 {
149 printf ("%s=> bad assignment\n\n", str);
150 return;
151 }
152 *p++ = 0;
153 if (mu_kwd_xlat_name (hintnames, str, &mask) == 0)
154 {
155 char **fptr = addr_fieldptr_by_mask (&hint, mask);
156
157 if (*p == 0)
158 hflags &= ~mask;
159 else
160 {
161 *fptr = strdup (p);
162 hflags |= mask;
163 }
164 }
165 else
166 printf ("%s=> unknown hint name\n\n", str);
167 }
168
99 static int 169 static int
100 parseinput (void) 170 parseinput (void)
101 { 171 {
...@@ -104,26 +174,34 @@ parseinput (void) ...@@ -104,26 +174,34 @@ parseinput (void)
104 while (fgets (buf, sizeof (buf), stdin) != 0) 174 while (fgets (buf, sizeof (buf), stdin) != 0)
105 { 175 {
106 buf[strlen (buf) - 1] = 0; 176 buf[strlen (buf) - 1] = 0;
107 parse (buf); 177 if (buf[0] == '\\')
178 sethint (buf + 1);
179 else
180 parse (buf);
108 } 181 }
109 182
110 return 0; 183 return 0;
111 } 184 }
112 185
113 int 186 int
114 main (int argc, const char *argv[]) 187 main (int argc, char *argv[])
115 { 188 {
116 argc = 1; 189 int i;
117 190
118 if (!argv[argc]) 191 hint.domain = "localhost";
192 hflags = MU_ADDR_HINT_DOMAIN;
193
194 if (argc == 1)
119 return parseinput (); 195 return parseinput ();
120 196
121 for (; argv[argc]; argc++) 197 for (i = 1; i < argc; i++)
122 { 198 {
123 if (strcmp (argv[argc], "-") == 0) 199 if (strcmp (argv[i], "-") == 0)
124 parseinput (); 200 parseinput ();
201 else if (strncmp (argv[i], "-v", 2) == 0)
202 sethint (argv[i] + 2);
125 else 203 else
126 parse (argv[argc]); 204 parse (argv[i]);
127 } 205 }
128 206
129 return 0; 207 return 0;
......
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, 2005, 2006, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2005, 2006, 2007,
3 2009 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -25,6 +26,46 @@ ...@@ -25,6 +26,46 @@
25 extern "C" { 26 extern "C" {
26 #endif 27 #endif
27 28
29 #define MU_ADDR_HINT_ADDR 0x0001 /* Not used yet */
30 #define MU_ADDR_HINT_COMMENTS 0x0002
31 #define MU_ADDR_HINT_PERSONAL 0x0004
32 #define MU_ADDR_HINT_EMAIL 0x0008
33 #define MU_ADDR_HINT_LOCAL 0x0010
34 #define MU_ADDR_HINT_DOMAIN 0x0020
35 #define MU_ADDR_HINT_ROUTE 0x0040
36
37 /*
38 * The data-structure representing an RFC822 MAILBOX. It may be
39 * one MAILBOX or a list of them, as found in an ADDRESS or
40 * a MAILBOX list (as found in a GROUP).
41 *
42 * Capitalized names are from RFC 822, section 6.1 (Address Syntax).
43 */
44 struct _mu_address
45 {
46 char *addr;
47 /* the original string that this list of addresses was created
48 * from, only present at the head of the list */
49
50 char *comments;
51 /* the collection of comments stripped during parsing this MAILBOX */
52 char *personal;
53 /* the PHRASE portion of a MAILBOX, called the DISPLAY-NAME in drums */
54 char *email;
55 /* the ADDR-SPEC, the LOCAL-PART@DOMAIN */
56 char *local_part;
57 /* the LOCAL-PART of a MAILBOX */
58 char *domain;
59 /* the DOMAIN of a MAILBOX */
60 char *route;
61 /* the optional ROUTE in the ROUTE-ADDR form of MAILBOX */
62
63 struct _mu_address *next;
64 };
65
66 extern int mu_address_create_hint (mu_address_t *, const char *,
67 mu_address_t, int);
68
28 extern int mu_address_create (mu_address_t *, const char *); 69 extern int mu_address_create (mu_address_t *, const char *);
29 extern int mu_address_createv (mu_address_t *, const char *v[], size_t); 70 extern int mu_address_createv (mu_address_t *, const char *v[], size_t);
30 extern void mu_address_destroy (mu_address_t *); 71 extern void mu_address_destroy (mu_address_t *);
......
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, 2001, 2005, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2005, 2007,
3 2009 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -49,57 +50,89 @@ extern int mu_parse822_is_q_text (char c); ...@@ -49,57 +50,89 @@ extern int mu_parse822_is_q_text (char c);
49 extern int mu_parse822_is_d_text (char c); 50 extern int mu_parse822_is_d_text (char c);
50 extern int mu_parse822_is_smtp_q (char c); 51 extern int mu_parse822_is_smtp_q (char c);
51 52
52 extern int mu_parse822_skip_crlf (const char** p, const char* e); 53 extern int mu_parse822_skip_crlf (const char **p, const char *e);
53 extern int mu_parse822_skip_lwsp_char (const char** p, const char* e); 54 extern int mu_parse822_skip_lwsp_char (const char **p, const char *e);
54 extern int mu_parse822_skip_lwsp (const char** p, const char* e); 55 extern int mu_parse822_skip_lwsp (const char **p, const char *e);
55 extern int mu_parse822_skip_comments (const char** p, const char* e); 56 extern int mu_parse822_skip_comments (const char **p, const char *e);
56 extern int mu_parse822_skip_nl (const char** p, const char* e); 57 extern int mu_parse822_skip_nl (const char **p, const char *e);
57 58
58 extern int mu_parse822_digits (const char** p, const char* e, int min, int max, int* digits); 59 extern int mu_parse822_digits (const char **p, const char *e,
59 extern int mu_parse822_special (const char** p, const char* e, char c); 60 int min, int max, int *digits);
60 extern int mu_parse822_comment (const char** p, const char* e, char** comment); 61 extern int mu_parse822_special (const char **p, const char *e, char c);
61 extern int mu_parse822_atom (const char** p, const char* e, char** atom); 62 extern int mu_parse822_comment (const char **p, const char *e,
62 extern int mu_parse822_quoted_pair (const char** p, const char* e, char** qpair); 63 char **comment);
63 extern int mu_parse822_quoted_string (const char** p, const char* e, char** qstr); 64 extern int mu_parse822_atom (const char **p, const char *e,
64 extern int mu_parse822_word (const char** p, const char* e, char** word); 65 char **atom);
65 extern int mu_parse822_phrase (const char** p, const char* e, char** phrase); 66 extern int mu_parse822_quoted_pair (const char **p, const char *e,
66 extern int mu_parse822_d_text (const char** p, const char* e, char** dtext); 67 char **qpair);
68 extern int mu_parse822_quoted_string (const char **p, const char *e,
69 char **qstr);
70 extern int mu_parse822_word (const char **p, const char *e,
71 char **word);
72 extern int mu_parse822_phrase (const char **p, const char *e,
73 char **phrase);
74 extern int mu_parse822_d_text (const char **p, const char *e,
75 char **dtext);
67 76
68 /* From RFC 822, 6.1 Address Specification Syntax */ 77 /* From RFC 822, 6.1 Address Specification Syntax */
69 78
70 extern int mu_parse822_address_list (mu_address_t* a, const char* s); 79 extern int mu_parse822_address_list (mu_address_t *a, const char *s,
71 extern int mu_parse822_mail_box (const char** p, const char* e, mu_address_t* a); 80 mu_address_t hint, int hflags);
72 extern int mu_parse822_group (const char** p, const char* e, mu_address_t* a); 81 extern int mu_parse822_mail_box (const char **p, const char *e,
73 extern int mu_parse822_address (const char** p, const char* e, mu_address_t* a); 82 mu_address_t *a,
74 extern int mu_parse822_route_addr (const char** p, const char* e, mu_address_t* a); 83 mu_address_t hint, int hflags);
75 extern int mu_parse822_route (const char** p, const char* e, char** route); 84 extern int mu_parse822_group (const char **p, const char *e,
76 extern int mu_parse822_addr_spec (const char** p, const char* e, mu_address_t* a); 85 mu_address_t *a,
77 extern int mu_parse822_unix_mbox (const char** p, const char* e, mu_address_t* a); 86 mu_address_t hint, int hflags);
78 extern int mu_parse822_local_part (const char** p, const char* e, char** local_part); 87 extern int mu_parse822_address (const char **p, const char *e,
79 extern int mu_parse822_domain (const char** p, const char* e, char** domain); 88 mu_address_t *a,
80 extern int mu_parse822_sub_domain (const char** p, const char* e, char** sub_domain); 89 mu_address_t hint, int hflags);
81 extern int mu_parse822_domain_ref (const char** p, const char* e, char** domain_ref); 90 extern int mu_parse822_route_addr (const char **p, const char *e,
82 extern int mu_parse822_domain_literal (const char** p, const char* e, char** domain_literal); 91 mu_address_t *a,
92 mu_address_t hint, int hflags);
93 extern int mu_parse822_route (const char **p, const char *e,
94 char **route);
95 extern int mu_parse822_addr_spec (const char **p, const char *e,
96 mu_address_t *a,
97 mu_address_t hint, int hflags);
98 extern int mu_parse822_unix_mbox (const char **p, const char *e,
99 mu_address_t *a,
100 mu_address_t hint, int hflags);
101 extern int mu_parse822_local_part (const char **p, const char *e,
102 char **local_part);
103 extern int mu_parse822_domain (const char **p, const char *e,
104 char **domain);
105 extern int mu_parse822_sub_domain (const char **p, const char *e,
106 char **sub_domain);
107 extern int mu_parse822_domain_ref (const char **p, const char *e,
108 char **domain_ref);
109 extern int mu_parse822_domain_literal (const char **p, const char *e,
110 char **domain_literal);
83 111
84 /* RFC 822 Quoting Functions 112 /* RFC 822 Quoting Functions
85 * Various elements must be quoted if then contain non-safe characters. What 113 * Various elements must be quoted if then contain non-safe characters. What
86 * characters are allowed depend on the element. The following functions will 114 * characters are allowed depend on the element. The following functions will
87 * allocate a quoted version of the raw element, it may not actually be 115 * allocate a quoted version of the raw element, it may not actually be
88 * quoted if no unsafe characters were in the raw string. 116 * quoted if no unsafe characters were in the raw string.
89 */ 117 */
90 118
91 extern int mu_parse822_quote_string (char** quoted, const char* raw); 119 extern int mu_parse822_quote_string (char **quoted, const char *raw);
92 extern int mu_parse822_quote_local_part (char** quoted, const char* raw); 120 extern int mu_parse822_quote_local_part (char **quoted, const char *raw);
93 121
94 extern int mu_parse822_field_body (const char** p, const char *e, char** fieldbody); 122 extern int mu_parse822_field_body (const char **p, const char *e,
95 extern int mu_parse822_field_name (const char** p, const char *e, char** fieldname); 123 char **fieldbody);
124 extern int mu_parse822_field_name (const char **p, const char *e,
125 char **fieldname);
96 126
97 /***** From RFC 822, 5.1 Date and Time Specification Syntax *****/ 127 /***** From RFC 822, 5.1 Date and Time Specification Syntax *****/
98 128
99 extern int mu_parse822_day (const char** p, const char* e, int* day); 129 extern int mu_parse822_day (const char **p, const char *e, int *day);
100 extern int mu_parse822_date (const char** p, const char* e, int* day, int* mon, int* year); 130 extern int mu_parse822_date (const char **p, const char *e, int *day,
101 extern int mu_parse822_time (const char** p, const char* e, int* h, int* m, int* s, int* tz, const char** tz_name); 131 int *mon, int *year);
102 extern int mu_parse822_date_time (const char** p, const char* e, struct tm* tm, mu_timezone* tz); 132 extern int mu_parse822_time (const char **p, const char *e, int *h,
133 int *m, int *s, int *tz, const char **tz_name);
134 extern int mu_parse822_date_time (const char **p, const char *e,
135 struct tm *tm, mu_timezone *tz);
103 136
104 137
105 #ifdef __cplusplus 138 #ifdef __cplusplus
......
1 ## Process this file with GNU Automake to create Makefile.in 1 ## Process this file with GNU Automake to create Makefile.in
2 2
3 ## Copyright (C) 2000, 2001, 2002, 2007 Free Software Foundation, Inc. 3 ## Copyright (C) 2000, 2001, 2002, 2007,
4 ## 2009 Free Software Foundation, Inc.
4 ## 5 ##
5 ## GNU Mailutils is free software; you can redistribute it and/or 6 ## GNU Mailutils is free software; you can redistribute it and/or
6 ## modify it under the terms of the GNU General Public License as 7 ## modify it under the terms of the GNU General Public License as
...@@ -18,7 +19,6 @@ ...@@ -18,7 +19,6 @@
18 ## 02110-1301 USA 19 ## 02110-1301 USA
19 20
20 noinst_HEADERS = \ 21 noinst_HEADERS = \
21 address0.h \
22 attribute0.h \ 22 attribute0.h \
23 amd.h \ 23 amd.h \
24 auth0.h \ 24 auth0.h \
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library; if not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301 USA */
18
19 #ifndef _ADDRESS0_H
20 #define _ADDRESS0_H
21
22 #ifdef DMALLOC
23 # include <dmalloc.h>
24 #endif
25
26 #include <mailutils/address.h>
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 /*
33 * The data-structure representing an RFC822 MAILBOX. It may be
34 * one MAILBOX or a list of them, as found in an ADDRESS or
35 * a MAILBOX list (as found in a GROUP).
36 *
37 * Capitalized names are from RFC 822, section 6.1 (Address Syntax).
38 */
39 struct _mu_address
40 {
41 char *addr;
42 /* the original string that this list of addresses was created
43 * from, only present at the head of the list */
44
45 char *comments;
46 /* the collection of comments stripped during parsing this MAILBOX */
47 char *personal;
48 /* the PHRASE portion of a MAILBOX, called the DISPLAY-NAME in drums */
49 char *email;
50 /* the ADDR-SPEC, the LOCAL-PART@DOMAIN */
51 char *local_part;
52 /* the LOCAL-PART of a MAILBOX */
53 char *domain;
54 /* the DOMAIN of a MAILBOX */
55 char *route;
56 /* the optional ROUTE in the ROUTE-ADDR form of MAILBOX */
57
58 struct _mu_address *next;
59 };
60
61 #ifdef __cplusplus
62 }
63 #endif
64
65 #endif /* _ADDRESS0_H */
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, 2001, 2005, 2006, 2 Copyright (C) 1999, 2000, 2001, 2005, 2006,
3 2007 Free Software Foundation, Inc. 3 2007, 2009 Free Software Foundation, Inc.
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -34,12 +34,12 @@ ...@@ -34,12 +34,12 @@
34 #include <mailutils/errno.h> 34 #include <mailutils/errno.h>
35 #include <mailutils/mutil.h> 35 #include <mailutils/mutil.h>
36 #include <mailutils/parse822.h> 36 #include <mailutils/parse822.h>
37 37 #include <mailutils/address.h>
38 #include <address0.h>
39 38
40 /* Get email addresses from rfc822 address. */ 39 /* Get email addresses from rfc822 address. */
41 int 40 int
42 mu_address_create (mu_address_t * a, const char *s) 41 mu_address_create_hint (mu_address_t *a, const char *s, mu_address_t hint,
42 int hflags)
43 { 43 {
44 /* 'a' must exist, and can't already have been initialized 44 /* 'a' must exist, and can't already have been initialized
45 */ 45 */
...@@ -52,7 +52,7 @@ mu_address_create (mu_address_t * a, const char *s) ...@@ -52,7 +52,7 @@ mu_address_create (mu_address_t * a, const char *s)
52 return EINVAL; 52 return EINVAL;
53 53
54 *a = NULL; 54 *a = NULL;
55 status = mu_parse822_address_list (a, s); 55 status = mu_parse822_address_list (a, s, hint, hflags);
56 if (status == 0) 56 if (status == 0)
57 { 57 {
58 /* And address-list may contain 0 addresses but parse correctly. 58 /* And address-list may contain 0 addresses but parse correctly.
...@@ -70,9 +70,20 @@ mu_address_create (mu_address_t * a, const char *s) ...@@ -70,9 +70,20 @@ mu_address_create (mu_address_t * a, const char *s)
70 return status; 70 return status;
71 } 71 }
72 72
73 /* Get email addresses from array of rfc822 addresses. */
74 int 73 int
75 mu_address_createv (mu_address_t * a, const char *sv[], size_t len) 74 mu_address_create (mu_address_t *a, const char *s)
75 {
76 struct _mu_address hint;
77 const char *d;
78 mu_get_user_email_domain (&d);
79 hint.domain = (char*) d;
80 return mu_address_create_hint (a, s, &hint, MU_ADDR_HINT_DOMAIN);
81 }
82
83 /* Get email addresses from array of rfc822 addresses.
84 FIXME: No hints? */
85 int
86 mu_address_createv (mu_address_t *a, const char *sv[], size_t len)
76 { 87 {
77 int status = 0; 88 int status = 0;
78 size_t buflen = 0; 89 size_t buflen = 0;
...@@ -130,7 +141,7 @@ mu_address_createv (mu_address_t * a, const char *sv[], size_t len) ...@@ -130,7 +141,7 @@ mu_address_createv (mu_address_t * a, const char *sv[], size_t len)
130 } 141 }
131 142
132 void 143 void
133 mu_address_destroy (mu_address_t * paddress) 144 mu_address_destroy (mu_address_t *paddress)
134 { 145 {
135 if (paddress && *paddress) 146 if (paddress && *paddress)
136 { 147 {
...@@ -160,7 +171,7 @@ mu_address_destroy (mu_address_t * paddress) ...@@ -160,7 +171,7 @@ mu_address_destroy (mu_address_t * paddress)
160 } 171 }
161 172
162 int 173 int
163 mu_address_concatenate (mu_address_t to, mu_address_t * from) 174 mu_address_concatenate (mu_address_t to, mu_address_t *from)
164 { 175 {
165 if (!to || !from || !*from) 176 if (!to || !from || !*from)
166 return EINVAL; 177 return EINVAL;
...@@ -254,7 +265,6 @@ ACCESSOR(sget,field) (mu_address_t addr, size_t no, char const **sptr) \ ...@@ -254,7 +265,6 @@ ACCESSOR(sget,field) (mu_address_t addr, size_t no, char const **sptr) \
254 subaddr = _address_get_nth (addr, no); \ 265 subaddr = _address_get_nth (addr, no); \
255 if (!subaddr) \ 266 if (!subaddr) \
256 return MU_ERR_NOENT; \ 267 return MU_ERR_NOENT; \
257 \
258 *sptr = subaddr->field; \ 268 *sptr = subaddr->field; \
259 return 0; \ 269 return 0; \
260 } 270 }
...@@ -262,7 +272,7 @@ ACCESSOR(sget,field) (mu_address_t addr, size_t no, char const **sptr) \ ...@@ -262,7 +272,7 @@ ACCESSOR(sget,field) (mu_address_t addr, size_t no, char const **sptr) \
262 #define DECL_GET(field) \ 272 #define DECL_GET(field) \
263 int \ 273 int \
264 ACCESSOR(get,field) (mu_address_t addr, size_t no, char *buf, size_t len, \ 274 ACCESSOR(get,field) (mu_address_t addr, size_t no, char *buf, size_t len, \
265 size_t * n) \ 275 size_t *n) \
266 { \ 276 { \
267 size_t i; \ 277 size_t i; \
268 const char *str; \ 278 const char *str; \
...@@ -429,7 +439,7 @@ mu_address_is_group (mu_address_t addr, size_t no, int *yes) ...@@ -429,7 +439,7 @@ mu_address_is_group (mu_address_t addr, size_t no, int *yes)
429 } 439 }
430 440
431 int 441 int
432 mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t * n) 442 mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t *n)
433 { 443 {
434 size_t i; 444 size_t i;
435 if (addr == NULL) 445 if (addr == NULL)
...@@ -453,7 +463,7 @@ mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t * n) ...@@ -453,7 +463,7 @@ mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t * n)
453 } 463 }
454 464
455 int 465 int
456 mu_address_get_count (mu_address_t addr, size_t * pcount) 466 mu_address_get_count (mu_address_t addr, size_t *pcount)
457 { 467 {
458 size_t j; 468 size_t j;
459 for (j = 0; addr; addr = addr->next, j++) 469 for (j = 0; addr; addr = addr->next, j++)
...@@ -464,7 +474,7 @@ mu_address_get_count (mu_address_t addr, size_t * pcount) ...@@ -464,7 +474,7 @@ mu_address_get_count (mu_address_t addr, size_t * pcount)
464 } 474 }
465 475
466 int 476 int
467 mu_address_get_group_count (mu_address_t addr, size_t * pcount) 477 mu_address_get_group_count (mu_address_t addr, size_t *pcount)
468 { 478 {
469 size_t j; 479 size_t j;
470 for (j = 0; addr; addr = addr->next) 480 for (j = 0; addr; addr = addr->next)
...@@ -478,7 +488,7 @@ mu_address_get_group_count (mu_address_t addr, size_t * pcount) ...@@ -478,7 +488,7 @@ mu_address_get_group_count (mu_address_t addr, size_t * pcount)
478 } 488 }
479 489
480 int 490 int
481 mu_address_get_email_count (mu_address_t addr, size_t * pcount) 491 mu_address_get_email_count (mu_address_t addr, size_t *pcount)
482 { 492 {
483 size_t j; 493 size_t j;
484 for (j = 0; addr; addr = addr->next) 494 for (j = 0; addr; addr = addr->next)
...@@ -492,7 +502,7 @@ mu_address_get_email_count (mu_address_t addr, size_t * pcount) ...@@ -492,7 +502,7 @@ mu_address_get_email_count (mu_address_t addr, size_t * pcount)
492 } 502 }
493 503
494 int 504 int
495 mu_address_get_unix_mailbox_count (mu_address_t addr, size_t * pcount) 505 mu_address_get_unix_mailbox_count (mu_address_t addr, size_t *pcount)
496 { 506 {
497 size_t j; 507 size_t j;
498 for (j = 0; addr; addr = addr->next) 508 for (j = 0; addr; addr = addr->next)
...@@ -522,6 +532,11 @@ mu_address_dup (mu_address_t src) ...@@ -522,6 +532,11 @@ mu_address_dup (mu_address_t src)
522 if (!dst) 532 if (!dst)
523 return NULL; 533 return NULL;
524 534
535 /* FIXME: How about:
536 if (src->addr)
537 dst->addr = strdup (src->addr);
538 ?
539 */
525 if (src->comments) 540 if (src->comments)
526 dst->comments = strdup (src->comments); 541 dst->comments = strdup (src->comments);
527 if (src->personal) 542 if (src->personal)
......
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, 2001, 2005, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2005, 2007,
3 2009 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -87,10 +88,9 @@ actually help. ...@@ -87,10 +88,9 @@ actually help.
87 # include <strings.h> 88 # include <strings.h>
88 #endif 89 #endif
89 90
90 #include "address0.h"
91
92 #include <mailutils/errno.h> 91 #include <mailutils/errno.h>
93 #include <mailutils/parse822.h> 92 #include <mailutils/parse822.h>
93 #include <mailutils/address.h>
94 94
95 #ifdef EOK 95 #ifdef EOK
96 # undef EOK 96 # undef EOK
...@@ -478,7 +478,7 @@ mu_parse822_atom (const char **p, const char *e, char **atom) ...@@ -478,7 +478,7 @@ mu_parse822_atom (const char **p, const char *e, char **atom)
478 478
479 save = *p; 479 save = *p;
480 480
481 while ((*p != e) && mu_parse822_is_atom_char (**p)) 481 while ((*p != e) && (**p == '.' || mu_parse822_is_atom_char (**p)))
482 { 482 {
483 rc = str_append_char (atom, **p); 483 rc = str_append_char (atom, **p);
484 *p += 1; 484 *p += 1;
...@@ -495,24 +495,18 @@ int ...@@ -495,24 +495,18 @@ int
495 parse822_atom_ex (const char **p, const char *e, char **atom) 495 parse822_atom_ex (const char **p, const char *e, char **atom)
496 { 496 {
497 /* atom = 1*<an atom char> */ 497 /* atom = 1*<an atom char> */
498 498 const char *ptr;
499 const char *save = *p; 499 int rc;
500 int rc = EPARSE;
501 500
502 mu_parse822_skip_comments (p, e); 501 mu_parse822_skip_comments (p, e);
503 502
504 save = *p; 503 for (ptr = *p; (ptr != e) && parse822_is_atom_char_ex (*ptr); ptr++)
505 504 ;
506 while ((*p != e) && parse822_is_atom_char_ex (**p)) 505 if (ptr - *p == 0)
507 { 506 return EPARSE;
508 rc = str_append_char (atom, **p); 507 rc = str_append_n (atom, *p, ptr - *p);
509 *p += 1; 508 if (rc == 0)
510 if (rc != EOK) 509 *p = ptr;
511 {
512 *p = save;
513 break;
514 }
515 }
516 return rc; 510 return rc;
517 } 511 }
518 512
...@@ -714,59 +708,133 @@ new_mb (void) ...@@ -714,59 +708,133 @@ new_mb (void)
714 return calloc (1, sizeof (struct _mu_address)); 708 return calloc (1, sizeof (struct _mu_address));
715 } 709 }
716 710
711 static char *
712 addr_field_by_mask (mu_address_t addr, int mask)
713 {
714 switch (mask)
715 {
716 case MU_ADDR_HINT_ADDR:
717 return addr->addr;
718
719 case MU_ADDR_HINT_COMMENTS:
720 return addr->comments;
721
722 case MU_ADDR_HINT_PERSONAL:
723 return addr->personal;
724
725 case MU_ADDR_HINT_EMAIL:
726 return addr->email;
727
728 case MU_ADDR_HINT_LOCAL:
729 return addr->local_part;
730
731 case MU_ADDR_HINT_DOMAIN:
732 return addr->domain;
733
734 case MU_ADDR_HINT_ROUTE:
735 return addr->route;
736 }
737 return NULL;
738 }
739
740 static char *
741 get_val (mu_address_t hint, int hflags, char *value, int mask, int *memflag)
742 {
743 if (!value && hint && (hflags & mask))
744 {
745 char *p = addr_field_by_mask (hint, mask);
746 if (p)
747 {
748 if (memflag)
749 *memflag |= mask;
750 value = strdup (p);
751 }
752 }
753 return value;
754 }
755
756 static void
757 addr_free_fields (mu_address_t a, int memflag)
758 {
759 char *p;
760
761 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_ADDR)))
762 free (p);
763 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_COMMENTS)))
764 free (p);
765 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_PERSONAL)))
766 free (p);
767 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_EMAIL)))
768 free (p);
769 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_LOCAL)))
770 free (p);
771 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_DOMAIN)))
772 free (p);
773 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_ROUTE)))
774 free (p);
775 }
776
717 static int 777 static int
718 fill_mb (mu_address_t * a, 778 fill_mb (mu_address_t *pa,
719 char *comments, char *personal, char *local, char *domain) 779 char *comments, char *personal, char *local, char *domain,
780 mu_address_t hint, int hflags)
720 { 781 {
721 int rc = EOK; 782 int rc = EOK;
783 mu_address_t a;
784 int memflag = 0;
722 785
723 *a = new_mb (); 786 a = new_mb ();
724 787
725 if (!*a) 788 if (!a)
726 { 789 return ENOMEM;
727 return ENOMEM;
728 }
729 790
730 (*a)->comments = comments; 791 a->comments = get_val (hint, hflags, comments, MU_ADDR_HINT_COMMENTS,
731 (*a)->personal = personal; 792 &memflag);
793 a->personal = get_val (hint, hflags, personal, MU_ADDR_HINT_PERSONAL,
794 &memflag);
732 795
796 domain = get_val (hint, hflags, domain, MU_ADDR_HINT_DOMAIN,
797 &memflag);
798 local = get_val (hint, hflags, local, MU_ADDR_HINT_LOCAL,
799 &memflag);
733 do 800 do
734 { 801 {
735 /* loop exists only to break out of */ 802 /* loop exists only to break out of */
736 const char *d = domain; 803 if (!local)
737 if (!d) 804 /* no email to construct */
738 {
739 mu_get_user_email_domain (&d);
740 }
741 if (!local || !d)
742 {
743 /* no email to construct */
744 break;
745 }
746 if ((rc = mu_parse822_quote_local_part (&(*a)->email, local)))
747 break;
748 if ((rc = str_append (&(*a)->email, "@")))
749 break; 805 break;
750 if ((rc = str_append (&(*a)->email, d))) 806
807 if ((rc = mu_parse822_quote_local_part (&a->email, local)))
751 break; 808 break;
809 if (domain)
810 {
811 if ((rc = str_append (&a->email, "@")))
812 break;
813 if ((rc = str_append (&a->email, domain)))
814 break;
815 }
752 } 816 }
753 while (0); 817 while (0);
754 818
755 (*a)->local_part = local; 819 a->local_part = local;
756 (*a)->domain = domain; 820 a->domain = domain;
757 821
758 if (rc != EOK) 822 if (rc != EOK)
759 { 823 {
824 addr_free_fields (a, memflag);
760 /* note that the arguments have NOT been freed, we only own 825 /* note that the arguments have NOT been freed, we only own
761 * them on success. */ 826 * them on success. */
762 free (*a); 827 free (a);
763 } 828 }
829 else
830 *pa = a;
764 831
765 return rc; 832 return rc;
766 } 833 }
767 834
768 int 835 int
769 mu_parse822_address_list (mu_address_t * a, const char *s) 836 mu_parse822_address_list (mu_address_t *a, const char *s,
837 mu_address_t hint, int hflags)
770 { 838 {
771 /* address-list = #(address) */ 839 /* address-list = #(address) */
772 840
...@@ -775,7 +843,7 @@ mu_parse822_address_list (mu_address_t * a, const char *s) ...@@ -775,7 +843,7 @@ mu_parse822_address_list (mu_address_t * a, const char *s)
775 int rc = EOK; 843 int rc = EOK;
776 mu_address_t *n = a; /* the next address we'll be creating */ 844 mu_address_t *n = a; /* the next address we'll be creating */
777 845
778 rc = mu_parse822_address (p, e, n); 846 rc = mu_parse822_address (p, e, n, hint, hflags);
779 847
780 /* A list may start with a leading <,>, we'll find out if 848 /* A list may start with a leading <,>, we'll find out if
781 * that's not the case at the top of the while, but give 849 * that's not the case at the top of the while, but give
...@@ -808,7 +876,7 @@ mu_parse822_address_list (mu_address_t * a, const char *s) ...@@ -808,7 +876,7 @@ mu_parse822_address_list (mu_address_t * a, const char *s)
808 } 876 }
809 mu_parse822_skip_comments (p, e); 877 mu_parse822_skip_comments (p, e);
810 878
811 rc = mu_parse822_address (p, e, n); 879 rc = mu_parse822_address (p, e, n, hint, hflags);
812 880
813 if (rc == EOK || rc == EPARSE) 881 if (rc == EOK || rc == EPARSE)
814 { 882 {
...@@ -833,20 +901,24 @@ mu_parse822_address_list (mu_address_t * a, const char *s) ...@@ -833,20 +901,24 @@ mu_parse822_address_list (mu_address_t * a, const char *s)
833 } 901 }
834 902
835 int 903 int
836 mu_parse822_address (const char **p, const char *e, mu_address_t * a) 904 mu_parse822_address (const char **p, const char *e, mu_address_t *a,
905 mu_address_t hint, int hflags)
837 { 906 {
838 /* address = mailbox / group / unix-mbox */ 907 /* address = mailbox / group / unix-mbox */
839 908
840 int rc; 909 int rc;
841 910
842 if ((rc = mu_parse822_mail_box (p, e, a)) == EPARSE) 911 if ((rc = mu_parse822_mail_box (p, e, a, hint, hflags)) == EPARSE)
843 { 912 {
844 if ((rc = mu_parse822_group (p, e, a)) == EPARSE) 913 if ((rc = mu_parse822_group (p, e, a, hint, hflags)) == EPARSE)
845 { 914 {
846 rc = mu_parse822_unix_mbox (p, e, a); 915 rc = mu_parse822_unix_mbox (p, e, a, hint, hflags);
847 } 916 }
848 } 917 }
849 918
919 if (rc == 0 && *a && !(*a)->route)
920 (*a)->route = get_val (hint, hflags, NULL, MU_ADDR_HINT_ROUTE, NULL);
921
850 return rc; 922 return rc;
851 } 923 }
852 924
...@@ -856,7 +928,8 @@ mu_parse822_address (const char **p, const char *e, mu_address_t * a) ...@@ -856,7 +928,8 @@ mu_parse822_address (const char **p, const char *e, mu_address_t * a)
856 */ 928 */
857 #undef ADD_GROUPS 929 #undef ADD_GROUPS
858 int 930 int
859 mu_parse822_group (const char **p, const char *e, mu_address_t * a) 931 mu_parse822_group (const char **p, const char *e, mu_address_t *a,
932 mu_address_t hint, int hflags)
860 { 933 {
861 /* group = phrase ":" [#mailbox] ";" */ 934 /* group = phrase ":" [#mailbox] ";" */
862 935
...@@ -886,7 +959,7 @@ mu_parse822_group (const char **p, const char *e, mu_address_t * a) ...@@ -886,7 +959,7 @@ mu_parse822_group (const char **p, const char *e, mu_address_t * a)
886 /* fake up an address node for the group's descriptive phrase, if 959 /* fake up an address node for the group's descriptive phrase, if
887 * it fails, clean-up will happen after the loop 960 * it fails, clean-up will happen after the loop
888 */ 961 */
889 if ((rc = fill_mb (a, 0, phrase, 0, 0)) == EOK) 962 if ((rc = fill_mb (a, 0, phrase, 0, 0, hint, hflags)) == EOK)
890 { 963 {
891 a = &(*a)->next; 964 a = &(*a)->next;
892 } 965 }
...@@ -907,7 +980,7 @@ mu_parse822_group (const char **p, const char *e, mu_address_t * a) ...@@ -907,7 +980,7 @@ mu_parse822_group (const char **p, const char *e, mu_address_t * a)
907 mu_parse822_skip_comments (p, e); 980 mu_parse822_skip_comments (p, e);
908 981
909 /* it's ok not be a mailbox, but other errors are fatal */ 982 /* it's ok not be a mailbox, but other errors are fatal */
910 rc = mu_parse822_mail_box (p, e, a); 983 rc = mu_parse822_mail_box (p, e, a, hint, hflags);
911 if (rc == EOK) 984 if (rc == EOK)
912 { 985 {
913 a = &(*a)->next; 986 a = &(*a)->next;
...@@ -941,7 +1014,8 @@ mu_parse822_group (const char **p, const char *e, mu_address_t * a) ...@@ -941,7 +1014,8 @@ mu_parse822_group (const char **p, const char *e, mu_address_t * a)
941 } 1014 }
942 1015
943 int 1016 int
944 mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a) 1017 mu_parse822_mail_box (const char **p, const char *e, mu_address_t *a,
1018 mu_address_t hint, int hflags)
945 { 1019 {
946 /* mailbox = 1020 /* mailbox =
947 * addr-spec [ "(" comment ")" ] / 1021 * addr-spec [ "(" comment ")" ] /
...@@ -956,7 +1030,7 @@ mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a) ...@@ -956,7 +1030,7 @@ mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a)
956 int rc; 1030 int rc;
957 1031
958 /* -> addr-spec */ 1032 /* -> addr-spec */
959 if ((rc = mu_parse822_addr_spec (p, e, a)) == EOK) 1033 if ((rc = mu_parse822_addr_spec (p, e, a, hint, hflags)) == EOK)
960 { 1034 {
961 mu_parse822_skip_lwsp (p, e); 1035 mu_parse822_skip_lwsp (p, e);
962 1036
...@@ -987,7 +1061,7 @@ mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a) ...@@ -987,7 +1061,7 @@ mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a)
987 return rc; 1061 return rc;
988 } 1062 }
989 1063
990 if ((rc = mu_parse822_route_addr (p, e, a)) == EOK) 1064 if ((rc = mu_parse822_route_addr (p, e, a, hint, hflags)) == EOK)
991 { 1065 {
992 /* add the phrase */ 1066 /* add the phrase */
993 (*a)->personal = phrase; 1067 (*a)->personal = phrase;
...@@ -1005,14 +1079,16 @@ mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a) ...@@ -1005,14 +1079,16 @@ mu_parse822_mail_box (const char **p, const char *e, mu_address_t * a)
1005 } 1079 }
1006 1080
1007 int 1081 int
1008 mu_parse822_route_addr (const char **p, const char *e, mu_address_t * a) 1082 mu_parse822_route_addr (const char **p, const char *e, mu_address_t *a,
1083 mu_address_t hint, int hflags)
1009 { 1084 {
1010 /* route-addr = "<" [route] addr-spec ">" */ 1085 /* route-addr = "<" [route] addr-spec ">" */
1011 1086
1012 const char *save = *p; 1087 const char *save = *p;
1013 char *route = 0; 1088 char *route = NULL;
1014 int rc; 1089 int rc;
1015 1090 int memflag = 0;
1091
1016 mu_parse822_skip_comments (p, e); 1092 mu_parse822_skip_comments (p, e);
1017 1093
1018 if ((rc = mu_parse822_special (p, e, '<'))) 1094 if ((rc = mu_parse822_special (p, e, '<')))
...@@ -1023,15 +1099,15 @@ mu_parse822_route_addr (const char **p, const char *e, mu_address_t * a) ...@@ -1023,15 +1099,15 @@ mu_parse822_route_addr (const char **p, const char *e, mu_address_t * a)
1023 } 1099 }
1024 if (!(rc = mu_parse822_special (p, e, '>'))) 1100 if (!(rc = mu_parse822_special (p, e, '>')))
1025 { 1101 {
1026 (void) (((rc = fill_mb (a, 0, 0, 0, 0)) == EOK) 1102 if ((rc = fill_mb (a, 0, 0, 0, 0, hint, hflags)) == EOK)
1027 && ((rc = str_append (&(*a)->email, "")) == EOK)); 1103 rc = str_append (&(*a)->email, "");
1028 1104
1029 return rc; 1105 return rc;
1030 } 1106 }
1031 1107
1032 mu_parse822_route (p, e, &route); 1108 mu_parse822_route (p, e, &route);
1033 1109
1034 if ((rc = mu_parse822_addr_spec (p, e, a))) 1110 if ((rc = mu_parse822_addr_spec (p, e, a, hint, hflags)))
1035 { 1111 {
1036 *p = save; 1112 *p = save;
1037 1113
...@@ -1040,7 +1116,8 @@ mu_parse822_route_addr (const char **p, const char *e, mu_address_t * a) ...@@ -1040,7 +1116,8 @@ mu_parse822_route_addr (const char **p, const char *e, mu_address_t * a)
1040 return rc; 1116 return rc;
1041 } 1117 }
1042 1118
1043 (*a)->route = route; /* now we don't have to free our local */ 1119 (*a)->route = get_val (hint, hflags, route, MU_ADDR_HINT_ROUTE,
1120 &memflag);
1044 1121
1045 mu_parse822_skip_comments (p, e); 1122 mu_parse822_skip_comments (p, e);
1046 1123
...@@ -1121,7 +1198,8 @@ mu_parse822_route (const char **p, const char *e, char **route) ...@@ -1121,7 +1198,8 @@ mu_parse822_route (const char **p, const char *e, char **route)
1121 } 1198 }
1122 1199
1123 int 1200 int
1124 mu_parse822_addr_spec (const char **p, const char *e, mu_address_t * a) 1201 mu_parse822_addr_spec (const char **p, const char *e, mu_address_t *a,
1202 mu_address_t hint, int hflags)
1125 { 1203 {
1126 /* addr-spec = local-part "@" domain */ 1204 /* addr-spec = local-part "@" domain */
1127 1205
...@@ -1137,18 +1215,16 @@ mu_parse822_addr_spec (const char **p, const char *e, mu_address_t * a) ...@@ -1137,18 +1215,16 @@ mu_parse822_addr_spec (const char **p, const char *e, mu_address_t * a)
1137 if (!rc) 1215 if (!rc)
1138 { 1216 {
1139 rc = mu_parse822_special (p, e, '@'); 1217 rc = mu_parse822_special (p, e, '@');
1140 } 1218
1141 1219 if (!rc)
1142 if (!rc) 1220 {
1143 { 1221 rc = mu_parse822_domain (p, e, &domain);
1144 rc = mu_parse822_domain (p, e, &domain);
1145 }
1146 1222
1147 if (!rc) 1223 if (!rc)
1148 { 1224 rc = fill_mb (a, 0, 0, local_part, domain, hint, hflags);
1149 rc = fill_mb (a, 0, 0, local_part, domain); 1225 }
1150 } 1226 }
1151 1227
1152 if (rc) 1228 if (rc)
1153 { 1229 {
1154 *p = save; 1230 *p = save;
...@@ -1159,7 +1235,8 @@ mu_parse822_addr_spec (const char **p, const char *e, mu_address_t * a) ...@@ -1159,7 +1235,8 @@ mu_parse822_addr_spec (const char **p, const char *e, mu_address_t * a)
1159 } 1235 }
1160 1236
1161 int 1237 int
1162 mu_parse822_unix_mbox (const char **p, const char *e, mu_address_t * a) 1238 mu_parse822_unix_mbox (const char **p, const char *e, mu_address_t *a,
1239 mu_address_t hint, int hflags)
1163 { 1240 {
1164 /* unix-mbox = atom */ 1241 /* unix-mbox = atom */
1165 1242
...@@ -1172,9 +1249,7 @@ mu_parse822_unix_mbox (const char **p, const char *e, mu_address_t * a) ...@@ -1172,9 +1249,7 @@ mu_parse822_unix_mbox (const char **p, const char *e, mu_address_t * a)
1172 rc = mu_parse822_atom (p, e, &mbox); 1249 rc = mu_parse822_atom (p, e, &mbox);
1173 1250
1174 if (!rc) 1251 if (!rc)
1175 { 1252 rc = fill_mb (a, 0, 0, mbox, 0, hint, hflags);
1176 rc = fill_mb (a, 0, 0, mbox, 0);
1177 }
1178 1253
1179 if (rc) 1254 if (rc)
1180 { 1255 {
......
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, 2001, 2002, 2003, 2 Copyright (C) 1999, 2000, 2001, 2002, 2003,
3 2005, 2006, 2007 Free Software Foundation, Inc. 3 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
4 4
5 GNU Mailutils is free software; you can redistribute it and/or modify 5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
...@@ -931,13 +931,13 @@ mh_expand_aliases (mu_message_t msg, ...@@ -931,13 +931,13 @@ mh_expand_aliases (mu_message_t msg,
931 { 931 {
932 mu_header_t hdr; 932 mu_header_t hdr;
933 size_t i, num; 933 size_t i, num;
934 char *buf; 934 const char *buf;
935 935
936 mu_message_get_header (msg, &hdr); 936 mu_message_get_header (msg, &hdr);
937 mu_header_get_field_count (hdr, &num); 937 mu_header_get_field_count (hdr, &num);
938 for (i = 1; i <= num; i++) 938 for (i = 1; i <= num; i++)
939 { 939 {
940 if (mu_header_aget_field_name (hdr, i, &buf) == 0) 940 if (mu_header_sget_field_name (hdr, i, &buf) == 0)
941 { 941 {
942 if (strcasecmp (buf, MU_HEADER_TO) == 0 942 if (strcasecmp (buf, MU_HEADER_TO) == 0
943 || strcasecmp (buf, MU_HEADER_CC) == 0 943 || strcasecmp (buf, MU_HEADER_CC) == 0
...@@ -958,7 +958,6 @@ mh_expand_aliases (mu_message_t msg, ...@@ -958,7 +958,6 @@ mh_expand_aliases (mu_message_t msg,
958 else if (strcasecmp (buf, MU_HEADER_BCC) == 0) 958 else if (strcasecmp (buf, MU_HEADER_BCC) == 0)
959 mu_address_union (addr_bcc ? addr_bcc : addr_to, addr); 959 mu_address_union (addr_bcc ? addr_bcc : addr_to, addr);
960 } 960 }
961 free (buf);
962 } 961 }
963 } 962 }
964 } 963 }
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc. 2 Copyright (C) 2003, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
3 3
4 GNU Mailutils is free software; you can redistribute it and/or modify 4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 5 it under the terms of the GNU General Public License as published by
...@@ -51,69 +51,47 @@ ismydomain (char *p) ...@@ -51,69 +51,47 @@ ismydomain (char *p)
51 return strcasecmp (domain, p + 1) == 0; 51 return strcasecmp (domain, p + 1) == 0;
52 } 52 }
53 53
54 /* FIXME: incl is not used */
54 int 55 int
55 mh_alias_expand (const char *str, mu_address_t *paddr, int *incl) 56 mh_alias_expand (const char *str, mu_address_t *paddr, int *incl)
56 { 57 {
57 int argc; 58 size_t i, count;
58 char **argv; 59 mu_address_t addr;
59 int i; 60 int status;
60 char *buf; 61
61 mu_address_t exaddr = NULL;
62
63 if (incl) 62 if (incl)
64 *incl = 0; 63 *incl = 0;
65 mu_argcv_get (str, ",", NULL, &argc, &argv); 64 status = mu_address_create_hint (&addr, str, NULL, 0);
66 for (i = 0; i < argc;) 65 if (status)
67 { 66 {
68 if (i + 1 == argc) 67 mu_error (_("Bad address `%s': %s"), str, mu_strerror (status));
69 { 68 return 1;
70 if (mh_alias_get_address (argv[i], &exaddr, incl) == 0) 69 }
71 { 70
72 free (argv[i]); 71 mu_address_get_count (addr, &count);
73 memcpy (&argv[i], &argv[i+1], 72 for (i = 1; i <= count; i++)
74 (argc - i + 1) * sizeof (argv[0])); 73 {
75 argc--; 74 mu_address_t subaddr = NULL;
76 } 75 const char *key;
77 else 76
78 i++; 77 if (mu_address_sget_domain (addr, i, &key) == 0 && key == NULL)
79 }
80 else if (argv[i + 1][0] == ',')
81 { 78 {
82 if (mh_alias_get_address (argv[i], &exaddr, incl) == 0) 79 if (mu_address_sget_local_part (addr, i, &key) == 0
83 { 80 && mh_alias_get_address (key, paddr, incl) == 0)
84 free (argv[i]); 81 continue;
85 free (argv[i+1]);
86 memcpy (&argv[i], &argv[i+2],
87 (argc - i) * sizeof (argv[0]));
88 argc -= 2;
89 }
90 else
91 i += 2;
92 } 82 }
93 else 83
84 status = mu_address_get_nth (addr, i, &subaddr);
85 if (status)
94 { 86 {
95 for (; i < argc; i++) 87 mu_error (_("%s: cannot get address #%lu: %s"),
96 if (argv[i][0] == ',') 88 str, (unsigned long) i, mu_strerror (status));
97 { 89 continue;
98 i++;
99 break;
100 }
101 } 90 }
102 }
103 91
104 if (argc) 92 mu_address_union (paddr, subaddr);
105 { 93 mu_address_destroy (&subaddr);
106 int status;
107 mu_argcv_string (argc, argv, &buf);
108 if ((status = mu_address_create (paddr, buf)))
109 mu_error (_("Bad address `%s': %s"), buf, mu_strerror (status));
110 free (buf);
111 } 94 }
112
113 mu_argcv_free (argc, argv);
114
115 mu_address_union (paddr, exaddr);
116 mu_address_destroy (&exaddr);
117 return 0; 95 return 0;
118 } 96 }
119 97
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. 2 Copyright (C) 2003, 2005, 2006, 2007, 2008,
3 2009 Free Software Foundation, Inc.
3 4
4 GNU Mailutils is free software; you can redistribute it and/or modify 5 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
...@@ -61,6 +62,9 @@ static struct argp_option options[] = { ...@@ -61,6 +62,9 @@ static struct argp_option options[] = {
61 {"push", ARG_PUSH, N_("BOOL"), OPTION_ARG_OPTIONAL, 62 {"push", ARG_PUSH, N_("BOOL"), OPTION_ARG_OPTIONAL,
62 N_("Run in the backround.") }, 63 N_("Run in the backround.") },
63 {"nopush", ARG_NOPUSH, NULL, OPTION_HIDDEN, "" }, 64 {"nopush", ARG_NOPUSH, NULL, OPTION_HIDDEN, "" },
65 {"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
66 N_("Keep draft files") },
67 {"keep", 0, NULL, OPTION_ALIAS, NULL},
64 {"split", ARG_SPLIT, N_("SECONDS"), 0, 68 {"split", ARG_SPLIT, N_("SECONDS"), 0,
65 N_("Split the draft into several partial messages and send them with SECONDS interval") }, 69 N_("Split the draft into several partial messages and send them with SECONDS interval") },
66 {"chunksize", ARG_CHUNKSIZE, N_("NUMBER"), 0, 70 {"chunksize", ARG_CHUNKSIZE, N_("NUMBER"), 0,
...@@ -91,7 +95,9 @@ struct mh_option mh_option[] = { ...@@ -91,7 +95,9 @@ struct mh_option mh_option[] = {
91 {"forward", 4, MH_OPT_BOOL, NULL}, 95 {"forward", 4, MH_OPT_BOOL, NULL},
92 {"mime", 2, MH_OPT_BOOL, NULL}, 96 {"mime", 2, MH_OPT_BOOL, NULL},
93 {"msgid", 2, MH_OPT_BOOL, NULL}, 97 {"msgid", 2, MH_OPT_BOOL, NULL},
94 {"push", 1, MH_OPT_BOOL, NULL}, 98 {"push", 2, MH_OPT_BOOL, NULL},
99 {"preserve", 2, MH_OPT_BOOL, NULL},
100 {"keep", 1, MH_OPT_BOOL, NULL},
95 {"split", 1, 0, "seconds"}, 101 {"split", 1, 0, "seconds"},
96 {"verbose", 1, MH_OPT_BOOL, NULL}, 102 {"verbose", 1, MH_OPT_BOOL, NULL},
97 {"watch", 2, MH_OPT_BOOL, NULL}, 103 {"watch", 2, MH_OPT_BOOL, NULL},
...@@ -116,6 +122,8 @@ static int verbose; /* Produce verbose diagnostics */ ...@@ -116,6 +122,8 @@ static int verbose; /* Produce verbose diagnostics */
116 static int watch; /* Watch the delivery process */ 122 static int watch; /* Watch the delivery process */
117 static unsigned width = 76; /* Maximum width of header fields */ 123 static unsigned width = 76; /* Maximum width of header fields */
118 124
125 static int keep_files; /* Keep draft files */
126
119 #define DEFAULT_X_MAILER "MH (" PACKAGE_STRING ")" 127 #define DEFAULT_X_MAILER "MH (" PACKAGE_STRING ")"
120 128
121 #define WATCH(c) do {\ 129 #define WATCH(c) do {\
...@@ -196,6 +204,10 @@ opt_handler (int key, char *arg, void *unused, struct argp_state *state) ...@@ -196,6 +204,10 @@ opt_handler (int key, char *arg, void *unused, struct argp_state *state)
196 case ARG_NOMSGID: 204 case ARG_NOMSGID:
197 append_msgid = 0; 205 append_msgid = 0;
198 break; 206 break;
207
208 case ARG_PRESERVE:
209 keep_files = is_true (arg);
210 break;
199 211
200 case ARG_PUSH: 212 case ARG_PUSH:
201 background = is_true (arg); 213 background = is_true (arg);
...@@ -690,7 +702,8 @@ _action_send (void *item, void *data) ...@@ -690,7 +702,8 @@ _action_send (void *item, void *data)
690 mu_mailer_close (mailer); 702 mu_mailer_close (mailer);
691 mu_mailer_destroy (&mailer); 703 mu_mailer_destroy (&mailer);
692 704
693 backup_file (elt->file_name); 705 if (!keep_files)
706 backup_file (elt->file_name);
694 707
695 return 0; 708 return 0;
696 } 709 }
......