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)
Showing
10 changed files
with
443 additions
and
276 deletions
... | @@ -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 \ | ... | ... |
libproto/include/address0.h
deleted
100644 → 0
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 | } | ... | ... |
-
Please register or sign in to post a comment