diff options
Diffstat (limited to 'mh/mh_init.c')
-rw-r--r-- | mh/mh_init.c | 235 |
1 files changed, 184 insertions, 51 deletions
diff --git a/mh/mh_init.c b/mh/mh_init.c index 23f5e2007..3cc3625d5 100644 --- a/mh/mh_init.c +++ b/mh/mh_init.c | |||
@@ -91,74 +91,207 @@ mh_my_email (void) | |||
91 | } | 91 | } |
92 | return my_email; | 92 | return my_email; |
93 | } | 93 | } |
94 | |||
95 | enum part_match_mode | ||
96 | { | ||
97 | part_match_local, | ||
98 | part_match_domain | ||
99 | }; | ||
100 | |||
101 | enum part_match_result | ||
102 | { | ||
103 | part_match_false, | ||
104 | part_match_true, | ||
105 | part_match_abort | ||
106 | }; | ||
107 | |||
108 | static int match_char_class (char const **pexpr, char c, int icase); | ||
109 | |||
110 | static enum part_match_result | ||
111 | part_match (char const *expr, char const *name, enum part_match_mode mode) | ||
112 | { | ||
113 | int c; | ||
94 | 114 | ||
95 | int | 115 | while (*expr) |
96 | emailcmp (char *pattern, char *name) | 116 | { |
117 | if (*name == 0 && *expr != '*') | ||
118 | return part_match_abort; | ||
119 | switch (*expr) | ||
120 | { | ||
121 | case '*': | ||
122 | while (*++expr == '*') | ||
123 | ; | ||
124 | if (*expr == 0) | ||
125 | return part_match_true; | ||
126 | while (*name) | ||
127 | { | ||
128 | int res = part_match (expr, name++, mode); | ||
129 | if (res != part_match_false) | ||
130 | return res; | ||
131 | } | ||
132 | return part_match_abort; | ||
133 | |||
134 | case '?': | ||
135 | expr++; | ||
136 | if (*name == 0) | ||
137 | return part_match_false; | ||
138 | name++; | ||
139 | break; | ||
140 | |||
141 | case '[': | ||
142 | if (!match_char_class (&expr, *name, mode == part_match_domain)) | ||
143 | return part_match_false; | ||
144 | name++; | ||
145 | break; | ||
146 | |||
147 | case '\\': | ||
148 | if (expr[1]) | ||
149 | { | ||
150 | c = *++expr; expr++; | ||
151 | if (*name != mu_wordsplit_c_unquote_char (c)) | ||
152 | return part_match_false; | ||
153 | name++; | ||
154 | break; | ||
155 | } | ||
156 | /* fall through */ | ||
157 | |||
158 | default: | ||
159 | if (mode == part_match_local) | ||
160 | { | ||
161 | if (*expr != *name) | ||
162 | return part_match_false; | ||
163 | if ('@' == *name) | ||
164 | mode = part_match_domain; | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | if (mu_tolower (*expr) != mu_tolower (*name)) | ||
169 | return part_match_false; | ||
170 | } | ||
171 | expr++; | ||
172 | name++; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | if (*name == 0) | ||
177 | return part_match_true; | ||
178 | |||
179 | if (mode == part_match_local && *name == '@') | ||
180 | return part_match_true; | ||
181 | |||
182 | return part_match_false; | ||
183 | } | ||
184 | |||
185 | static int | ||
186 | match_char_class (char const **pexpr, char c, int icase) | ||
97 | { | 187 | { |
98 | char *p; | 188 | int res; |
189 | int rc; | ||
190 | char const *expr = *pexpr; | ||
99 | 191 | ||
100 | p = strchr (pattern, '@'); | 192 | if (icase) |
101 | if (p) | 193 | c = mu_toupper (c); |
102 | for (p++; *p; p++) | 194 | |
103 | *p = mu_toupper (*p); | 195 | expr++; |
196 | if (*expr == '^') | ||
197 | { | ||
198 | res = 0; | ||
199 | expr++; | ||
200 | } | ||
201 | else | ||
202 | res = 1; | ||
203 | |||
204 | if (*expr == '-' || *expr == ']') | ||
205 | rc = c == *expr++; | ||
206 | else | ||
207 | rc = !res; | ||
208 | |||
209 | for (; *expr && *expr != ']'; expr++) | ||
210 | { | ||
211 | if (rc == res) | ||
212 | { | ||
213 | if (*expr == '\\' && expr[1] == ']') | ||
214 | expr++; | ||
215 | } | ||
216 | else if (expr[1] == '-') | ||
217 | { | ||
218 | if (*expr == '\\') | ||
219 | rc = *++expr == c; | ||
220 | else | ||
221 | { | ||
222 | if (icase) | ||
223 | rc = mu_toupper (*expr) <= c && c <= mu_toupper (expr[2]); | ||
224 | else | ||
225 | rc = *expr <= c && c <= expr[2]; | ||
226 | expr += 2; | ||
227 | } | ||
228 | } | ||
229 | else if (*expr == '\\' && expr[1] == ']') | ||
230 | rc = *++expr == c; | ||
231 | else if (icase) | ||
232 | rc = mu_toupper(*expr) == c; | ||
233 | else | ||
234 | rc = *expr == c; | ||
235 | } | ||
236 | *pexpr = *expr ? expr + 1 : expr; | ||
237 | return rc == res; | ||
238 | } | ||
104 | 239 | ||
105 | return fnmatch (pattern, name, 0); | 240 | static int |
241 | email_match (char const *pattern, char const *name) | ||
242 | { | ||
243 | return part_match (pattern, name, part_match_local) == part_match_true; | ||
106 | } | 244 | } |
107 | 245 | ||
108 | int | 246 | int |
109 | mh_is_my_name (const char *name) | 247 | mh_is_my_name (const char *name) |
110 | { | 248 | { |
111 | char *pname, *p; | 249 | static mu_address_t addr; |
112 | int rc = 0; | 250 | mu_address_t p; |
113 | |||
114 | pname = mu_strdup (name); | ||
115 | p = strchr (pname, '@'); | ||
116 | if (p) | ||
117 | for (p++; *p; p++) | ||
118 | *p = mu_toupper (*p); | ||
119 | 251 | ||
120 | if (emailcmp (mh_my_email (), pname) == 0) | 252 | if (!addr) |
121 | rc = 1; | ||
122 | else | ||
123 | { | 253 | { |
124 | const char *nlist = mh_global_profile_get ("Alternate-Mailboxes", NULL); | 254 | const char *nlist; |
255 | int rc; | ||
256 | |||
257 | rc = mu_address_create (&addr, mh_my_email ()); | ||
258 | if (rc) | ||
259 | { | ||
260 | mu_diag_funcall (MU_DIAG_ERROR, "mu_address_create", mh_my_email (), | ||
261 | rc); | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | nlist = mh_global_profile_get ("Alternate-Mailboxes", NULL); | ||
125 | if (nlist) | 266 | if (nlist) |
126 | { | 267 | { |
127 | const char *end, *p; | 268 | mu_address_t tmp; |
128 | char *pat; | 269 | struct mu_address hint; |
129 | int len; | 270 | |
130 | 271 | hint.domain = NULL; | |
131 | for (p = nlist; rc == 0 && *p; p = end) | 272 | rc = mu_address_create_hint (&tmp, nlist, &hint, |
273 | MU_ADDR_HINT_DOMAIN); | ||
274 | if (rc == 0) | ||
132 | { | 275 | { |
133 | 276 | rc = mu_address_union (&addr, tmp); | |
134 | while (*p && mu_isspace (*p)) | 277 | if (rc) |
135 | p++; | 278 | mu_diag_funcall (MU_DIAG_ERROR, "mu_address_union", NULL, rc); |
136 | 279 | mu_address_destroy (&tmp); | |
137 | end = strchr (p, ','); | 280 | } |
138 | if (end) | 281 | else |
139 | { | 282 | { |
140 | len = end - p; | 283 | mu_error (_("bad Alternate-Mailboxes: %s; please fix"), |
141 | end++; | 284 | mu_strerror (rc)); |
142 | } | ||
143 | else | ||
144 | { | ||
145 | len = strlen (p); | ||
146 | end = p + len; | ||
147 | } | ||
148 | |||
149 | while (len > 0 && mu_isspace (p[len-1])) | ||
150 | len--; | ||
151 | |||
152 | pat = mu_alloc (len + 1); | ||
153 | memcpy (pat, p, len); | ||
154 | pat[len] = 0; | ||
155 | rc = emailcmp (pat, pname) == 0; | ||
156 | free (pat); | ||
157 | } | 285 | } |
158 | } | 286 | } |
159 | } | 287 | } |
160 | free (pname); |