Commit be1380d7 be1380d7aa53c031a237b5e993187733eab3fa40 by Sergey Poznyakoff

Improve the algorithm for URL look up in wickets.

The new algorithm always returns the best match, i.e. the
one with the smallest number of wildcard comparisons.

* include/mailutils/auth.h (mu_wicket_stream_match_url)
(mu_wicket_file_match_url): New protos.
Remove unnecessary 'extern' qualifiers.
* include/mailutils/url.h (mu_url_is_ticket): Remove.
(mu_url_matches_ticket): New proto.
* libmailutils/base/url.c (mu_url_parse): Fix name corruption during
password obfuscation.
(defined): Remove static function.
(mu_url_is_ticket): Remove function.
(mu_url_matches_ticket): New function.
* libmailutils/base/wicket.c (get_ticket_url): Remove.
(mu_wicket_stream_match_url)
(mu_wicket_file_match_url): New functions.
(file_ticket_get_cred): Use mu_wicket_file_match_url.

* libmailutils/tests/wicket.c: New file.
* libmailutils/tests/Wicketfile: New file.
* libmailutils/tests/wicket.at: New file.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add wicket.
(EXTRA_DIST): Add Wicketfile
(TESTSUITE_AT): Add wicket.at
* libmailutils/tests/testsuite.at: Include wicket.at
* libmailutils/tests/.gitignore: Update.
1 parent d992b1b4
...@@ -25,55 +25,63 @@ ...@@ -25,55 +25,63 @@
25 extern "C" { 25 extern "C" {
26 #endif 26 #endif
27 27
28 extern int mu_ticket_create (mu_ticket_t *, void *); 28 int mu_ticket_create (mu_ticket_t *, void *);
29 extern int mu_ticket_ref (mu_ticket_t); 29 int mu_ticket_ref (mu_ticket_t);
30 extern int mu_ticket_unref (mu_ticket_t); 30 int mu_ticket_unref (mu_ticket_t);
31 extern void mu_ticket_destroy (mu_ticket_t *); 31 void mu_ticket_destroy (mu_ticket_t *);
32 extern int mu_ticket_set_destroy (mu_ticket_t, 32 int mu_ticket_set_destroy (mu_ticket_t,
33 void (*) (mu_ticket_t), void *); 33 void (*) (mu_ticket_t), void *);
34 extern void *mu_ticket_get_owner (mu_ticket_t); 34 void *mu_ticket_get_owner (mu_ticket_t);
35 35
36 extern int mu_ticket_get_cred (mu_ticket_t ticket, 36 int mu_ticket_get_cred (mu_ticket_t ticket,
37 mu_url_t url, const char *challenge, 37 mu_url_t url, const char *challenge,
38 char **pplain, mu_secret_t *psec); 38 char **pplain, mu_secret_t *psec);
39 39
40 extern int mu_ticket_set_get_cred (mu_ticket_t, 40 int mu_ticket_set_get_cred (mu_ticket_t,
41 int (*) (mu_ticket_t, mu_url_t, 41 int (*) (mu_ticket_t, mu_url_t,
42 const char *, 42 const char *,
43 char **, mu_secret_t *), 43 char **, mu_secret_t *),
44 void *); 44 void *);
45 45
46 extern int mu_ticket_set_data (mu_ticket_t, void *, void *owner); 46 int mu_ticket_set_data (mu_ticket_t, void *, void *owner);
47 extern void *mu_ticket_get_data (mu_ticket_t); 47 void *mu_ticket_get_data (mu_ticket_t);
48 48
49 extern int mu_ticket_set_secret (mu_ticket_t ticket, mu_secret_t secret); 49 int mu_ticket_set_secret (mu_ticket_t ticket, mu_secret_t secret);
50 int mu_ticket_set_plain (mu_ticket_t ticket, const char *text); 50 int mu_ticket_set_plain (mu_ticket_t ticket, const char *text);
51 51
52 extern int mu_authority_create (mu_authority_t *, mu_ticket_t, void *); 52 int mu_authority_create (mu_authority_t *, mu_ticket_t, void *);
53 extern void mu_authority_destroy (mu_authority_t *, void *); 53 void mu_authority_destroy (mu_authority_t *, void *);
54 extern void *mu_authority_get_owner (mu_authority_t); 54 void *mu_authority_get_owner (mu_authority_t);
55 extern int mu_authority_set_ticket (mu_authority_t, mu_ticket_t); 55 int mu_authority_set_ticket (mu_authority_t, mu_ticket_t);
56 extern int mu_authority_get_ticket (mu_authority_t, mu_ticket_t *); 56 int mu_authority_get_ticket (mu_authority_t, mu_ticket_t *);
57 extern int mu_authority_authenticate (mu_authority_t); 57 int mu_authority_authenticate (mu_authority_t);
58 extern int mu_authority_set_authenticate (mu_authority_t, 58 int mu_authority_set_authenticate (mu_authority_t,
59 int (*_authenticate) (mu_authority_t), void *); 59 int (*_authenticate) (mu_authority_t),
60 void *);
60 61
61 extern int mu_authority_create_null (mu_authority_t *pauthority, void *owner); 62 int mu_authority_create_null (mu_authority_t *pauthority, void *owner);
62 63
63 extern int mu_wicket_create (mu_wicket_t *); 64 int mu_wicket_create (mu_wicket_t *);
64 extern int mu_wicket_get_ticket (mu_wicket_t wicket, const char *user, 65 int mu_wicket_get_ticket (mu_wicket_t wicket, const char *user,
65 mu_ticket_t *pticket); 66 mu_ticket_t *pticket);
66 extern int mu_wicket_ref (mu_wicket_t wicket); 67 int mu_wicket_ref (mu_wicket_t wicket);
67 extern int mu_wicket_unref (mu_wicket_t wicket); 68 int mu_wicket_unref (mu_wicket_t wicket);
68 extern void mu_wicket_destroy (mu_wicket_t *pwicket); 69 void mu_wicket_destroy (mu_wicket_t *pwicket);
69 extern int mu_wicket_set_destroy (mu_wicket_t wicket, 70 int mu_wicket_set_destroy (mu_wicket_t wicket,
70 void (*_destroy) (mu_wicket_t)); 71 void (*_destroy) (mu_wicket_t));
71 extern int mu_wicket_set_data (mu_wicket_t wicket, void *data); 72 int mu_wicket_set_data (mu_wicket_t wicket, void *data);
72 extern void *mu_wicket_get_data (mu_wicket_t wicket); 73 void *mu_wicket_get_data (mu_wicket_t wicket);
73 extern int mu_wicket_set_get_ticket (mu_wicket_t wicket, 74 int mu_wicket_set_get_ticket (mu_wicket_t wicket,
74 int (*_get_ticket) (mu_wicket_t, void *, 75 int (*_get_ticket) (mu_wicket_t, void *,
75 const char *, mu_ticket_t *)); 76 const char *, mu_ticket_t *));
76 extern int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename); 77 int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename);
78
79 struct mu_debug_locus;
80 int mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc,
81 mu_url_t url, mu_url_t *pticket_url);
82 int mu_wicket_file_match_url (const char *name, mu_url_t url,
83 mu_url_t *pticket_url);
84
77 85
78 #ifdef __cplusplus 86 #ifdef __cplusplus
79 } 87 }
......
...@@ -104,7 +104,7 @@ int mu_url_is_same_port (mu_url_t, mu_url_t); ...@@ -104,7 +104,7 @@ int mu_url_is_same_port (mu_url_t, mu_url_t);
104 char *mu_url_decode_len (const char *s, size_t len); 104 char *mu_url_decode_len (const char *s, size_t len);
105 char *mu_url_decode (const char *s); 105 char *mu_url_decode (const char *s);
106 106
107 int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); 107 int mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *wcn);
108 int mu_url_init (mu_url_t url, int port, const char *scheme); 108 int mu_url_init (mu_url_t url, int port, const char *scheme);
109 109
110 #ifdef __cplusplus 110 #ifdef __cplusplus
......
...@@ -316,13 +316,18 @@ mu_url_parse (mu_url_t url) ...@@ -316,13 +316,18 @@ mu_url_parse (mu_url_t url)
316 char *newname; 316 char *newname;
317 317
318 memset (url->name + pstart, 0, plen); 318 memset (url->name + pstart, 0, plen);
319 if (len > nlen + 1)
320 {
319 newname = realloc (url->name, len); 321 newname = realloc (url->name, len);
320 if (!newname) 322 if (!newname)
321 goto CLEANUP; 323 goto CLEANUP;
324 url->name = newname;
325 }
326 else
327 newname = url->name;
322 memmove (newname + pstart + PASS_REPL_LEN, newname + pstart + plen, 328 memmove (newname + pstart + PASS_REPL_LEN, newname + pstart + plen,
323 nlen - (pstart + plen) + 1); 329 nlen - (pstart + plen) + 1);
324 memcpy (newname + pstart, PASS_REPL, PASS_REPL_LEN); 330 memcpy (newname + pstart, PASS_REPL, PASS_REPL_LEN);
325 url->name = newname;
326 } 331 }
327 332
328 /* Dup the strings we found. We wouldn't have to do this 333 /* Dup the strings we found. We wouldn't have to do this
...@@ -959,44 +964,68 @@ mu_url_decode (const char *s) ...@@ -959,44 +964,68 @@ mu_url_decode (const char *s)
959 return mu_url_decode_len (s, strlen (s)); 964 return mu_url_decode_len (s, strlen (s));
960 } 965 }
961 966
962 static int 967 #define is_wildcard(s) ((s)[0] == '*' && s[1] == 0)
963 defined (const char *s)
964 {
965 if (s && strcmp ("*", s) != 0)
966 return 1;
967 return 0;
968 }
969 968
970 int 969 int
971 mu_url_is_ticket (mu_url_t ticket, mu_url_t url) 970 mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *pwc)
972 { 971 {
973 if (!ticket || !url) 972 int wcnt = 0;
973
974 if (is_wildcard (ticket->scheme))
975 wcnt++;
976 else if (mu_c_strcasecmp (ticket->scheme, url->scheme))
974 return 0; 977 return 0;
975 978
976 /* If ticket has a scheme, host, port, or path, then the queries 979 if (ticket->flags & MU_URL_HOST)
977 equivalent must be defined and match. */
978 if (defined (ticket->scheme))
979 { 980 {
980 if (!url->scheme || mu_c_strcasecmp (ticket->scheme, url->scheme) != 0) 981 if (is_wildcard (ticket->host))
982 wcnt++;
983 else if (url->flags & MU_URL_HOST)
984 {
985 if (mu_c_strcasecmp (ticket->host, url->host))
986 /* FIXME: Compare IP addresses */
981 return 0; 987 return 0;
982 } 988 }
983 if (defined (ticket->host)) 989 else
984 {
985 if (!url->host || mu_c_strcasecmp (ticket->host, url->host) != 0)
986 return 0; 990 return 0;
987 } 991 }
988 if (ticket->port && ticket->port != url->port) 992 else
993 wcnt++;
994
995 if (ticket->flags & MU_URL_PORT)
996 {
997 /* FIXME: No way to put a wildcard in the ticket file */
998 if (url->port & MU_URL_PORT)
999 {
1000 if (ticket->port != url->port)
989 return 0; 1001 return 0;
1002 else
1003 wcnt++;
1004 }
1005 }
1006 else
1007 wcnt++;
1008
1009 if (ticket->flags & MU_URL_USER)
1010 {
1011 if (is_wildcard (ticket->user))
1012 wcnt += 2;
1013
990 /* If ticket has a user or pass, but url doesn't, that's OK, we were 1014 /* If ticket has a user or pass, but url doesn't, that's OK, we were
991 urling for this info. But if url does have a user/pass, it 1015 looking for this info. But if url does have a user/pass, it
992 must match the ticket. */ 1016 must match the ticket. */
993 if (url->user) 1017 else if (url->flags & MU_URL_USER)
994 { 1018 {
995 if (defined (ticket->user) && strcmp (ticket->user, url->user) != 0) 1019 if (strcmp (ticket->user, url->user))
996 return 0; 1020 return 0;
997 } 1021 }
1022 }
1023 else
1024 wcnt++;
998 1025
999 /* Guess it matches. */ 1026 /* Guess it matches. */
1027 if (pwc)
1028 *pwc = wcnt;
1000 return 1; 1029 return 1;
1001 } 1030 }
1002 1031
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
34 #include <mailutils/util.h> 34 #include <mailutils/util.h>
35 #include <mailutils/mu_auth.h> 35 #include <mailutils/mu_auth.h>
36 #include <mailutils/stream.h> 36 #include <mailutils/stream.h>
37 #include <mailutils/cstr.h>
38 #include <mailutils/nls.h>
39 #include <mailutils/errno.h>
37 40
38 #include <mailutils/sys/auth.h> 41 #include <mailutils/sys/auth.h>
39 #include <mailutils/sys/url.h> 42 #include <mailutils/sys/url.h>
...@@ -50,7 +53,8 @@ mu_wicket_create (mu_wicket_t *pwicket) ...@@ -50,7 +53,8 @@ mu_wicket_create (mu_wicket_t *pwicket)
50 } 53 }
51 54
52 int 55 int
53 mu_wicket_get_ticket (mu_wicket_t wicket, const char *user, mu_ticket_t *pticket) 56 mu_wicket_get_ticket (mu_wicket_t wicket, const char *user,
57 mu_ticket_t *pticket)
54 { 58 {
55 if (!wicket) 59 if (!wicket)
56 return EINVAL; 60 return EINVAL;
...@@ -168,8 +172,6 @@ file_ticket_destroy (mu_ticket_t ticket) ...@@ -168,8 +172,6 @@ file_ticket_destroy (mu_ticket_t ticket)
168 } 172 }
169 } 173 }
170 174
171 static int get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url);
172
173 int 175 int
174 file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, 176 file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge,
175 char **pplain, mu_secret_t *psec) 177 char **pplain, mu_secret_t *psec)
...@@ -178,7 +180,7 @@ file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, ...@@ -178,7 +180,7 @@ file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge,
178 180
179 if (!ft->tickurl) 181 if (!ft->tickurl)
180 { 182 {
181 int rc = get_ticket_url (ticket, url, &ft->tickurl); 183 int rc = mu_wicket_file_match_url (ft->filename, url, &ft->tickurl);
182 if (rc) 184 if (rc)
183 return rc; 185 return rc;
184 } 186 }
...@@ -241,37 +243,28 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data, ...@@ -241,37 +243,28 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data,
241 return 0; 243 return 0;
242 } 244 }
243 245
244 static int 246 int
245 get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) 247 mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc,
248 mu_url_t url, mu_url_t *pticket_url)
246 { 249 {
247 mu_stream_t stream;
248 struct file_ticket *ft = mu_ticket_get_data (ticket);
249 int rc; 250 int rc;
250 mu_url_t u = NULL; 251 mu_url_t u = NULL;
251 char *buf = NULL; 252 char *buf = NULL;
252 size_t bufsize = 0; 253 size_t bufsize = 0;
253 size_t len; 254 size_t len;
254 255 mu_url_t pret = NULL;
255 rc = mu_file_stream_create (&stream, ft->filename, MU_STREAM_READ); 256 int weight = 0;
256 if (rc) 257 int line = loc->line;
257 return rc;
258 258
259 while ((rc = mu_stream_getline (stream, &buf, &bufsize, &len)) == 0 259 while ((rc = mu_stream_getline (stream, &buf, &bufsize, &len)) == 0
260 && len > 0) 260 && len > 0)
261 { 261 {
262 char *p; 262 char *p;
263 int err; 263 int err;
264 int n;
264 265
265 /* Truncate a trailing newline. */ 266 loc->line++;
266 if (len && buf[len - 1] == '\n') 267 p = mu_str_stripws (buf);
267 buf[--len] = 0;
268
269 /* Skip leading spaces */
270 for (p = buf; *p == ' ' || *p == '\t'; p++)
271 ;
272 /* Skip trailing spaces */
273 for (; len > 0 && (p[len-1] == ' ' || p[len-1] == '\t'); )
274 p[--len] = 0;
275 268
276 /* Skip empty lines and comments. */ 269 /* Skip empty lines and comments. */
277 if (*p == 0 || *p == '#') 270 if (*p == 0 || *p == '#')
...@@ -280,43 +273,42 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) ...@@ -280,43 +273,42 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url)
280 if ((err = mu_url_create (&u, p)) != 0) 273 if ((err = mu_url_create (&u, p)) != 0)
281 { 274 {
282 /* Skip erroneous entry */ 275 /* Skip erroneous entry */
283 /* FIXME: Error message */ 276 mu_error (_("%s:%u: cannot create URL: %s"),
277 loc->file, loc->line, mu_strerror (err));
284 continue; 278 continue;
285 } 279 }
286 if ((err = mu_url_parse (u)) != 0) 280 if ((err = mu_url_parse (u)) != 0)
287 { 281 {
288 /* FIXME: See above */ 282 mu_error (_("%s:%u: cannot parse URL: %s"),
283 loc->file, loc->line, mu_strerror (err));
289 mu_url_destroy (&u); 284 mu_url_destroy (&u);
290 continue; 285 continue;
291 } 286 }
292 287
293 if (!mu_url_is_ticket (u, url)) 288 if (!mu_url_matches_ticket (u, url, &n))
294 { 289 {
295 mu_url_destroy (&u); 290 mu_url_destroy (&u);
296 continue; 291 continue;
297 } 292 }
298 293
299 if (ft->user) 294 if (!pret || n < weight)
300 {
301 if (u->name && strcmp (u->name, "*") != 0
302 && strcmp (ft->user, u->name) != 0)
303 { 295 {
304 mu_url_destroy (&u); 296 pret = u;
305 continue; 297 weight = n;
306 } 298 line = loc->line;
307 } 299 if (weight == 0)
308
309 break; 300 break;
310 } 301 }
311 mu_stream_close (stream); 302 }
312 free (buf); 303 free (buf);
313 304
314 mu_stream_destroy (&stream);
315
316 if (rc == 0) 305 if (rc == 0)
317 { 306 {
318 if (u) 307 if (pret)
319 *pticket_url = u; 308 {
309 *pticket_url = pret;
310 loc->line = line;
311 }
320 else 312 else
321 rc = MU_ERR_NOENT; 313 rc = MU_ERR_NOENT;
322 } 314 }
...@@ -325,6 +317,25 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) ...@@ -325,6 +317,25 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url)
325 } 317 }
326 318
327 int 319 int
320 mu_wicket_file_match_url (const char *name, mu_url_t url,
321 mu_url_t *pticket_url)
322 {
323 mu_stream_t stream;
324 int rc;
325 struct mu_debug_locus loc;
326
327 rc = mu_file_stream_create (&stream, name, MU_STREAM_READ);
328 if (rc)
329 return rc;
330 loc.file = name;
331 loc.line = 0;
332 rc = mu_wicket_stream_match_url (stream, &loc, url, pticket_url);
333 mu_stream_close (stream);
334 mu_stream_destroy (&stream);
335 return rc;
336 }
337
338 int
328 mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename) 339 mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename)
329 { 340 {
330 mu_wicket_t wicket; 341 mu_wicket_t wicket;
......
...@@ -12,3 +12,4 @@ fltst ...@@ -12,3 +12,4 @@ fltst
12 listop 12 listop
13 mailcap 13 mailcap
14 url-parse 14 url-parse
15 wicket
......
...@@ -47,11 +47,12 @@ noinst_PROGRAMS = \ ...@@ -47,11 +47,12 @@ noinst_PROGRAMS = \
47 fltst\ 47 fltst\
48 listop\ 48 listop\
49 mailcap\ 49 mailcap\
50 url-parse 50 url-parse\
51 wicket
51 52
52 LDADD = ${MU_LIB_MAILUTILS} 53 LDADD = ${MU_LIB_MAILUTILS}
53 54
54 EXTRA_DIST += Encode Decode 55 EXTRA_DIST += Encode Decode Wicketfile
55 56
56 ## ------------ ## 57 ## ------------ ##
57 ## Test suite. ## 58 ## Test suite. ##
...@@ -68,7 +69,8 @@ TESTSUITE_AT = \ ...@@ -68,7 +69,8 @@ TESTSUITE_AT = \
68 list.at\ 69 list.at\
69 mailcap.at\ 70 mailcap.at\
70 testsuite.at\ 71 testsuite.at\
71 url.at 72 url.at\
73 wicket.at
72 74
73 TESTSUITE = $(srcdir)/testsuite 75 TESTSUITE = $(srcdir)/testsuite
74 M4=m4 76 M4=m4
......
1 # A test wicket file.
2 *://foo:bar@localhost
3 pop://*:foo;AUTH=+APOP@localhost
4 pop://gray:test@localhost
5 smtp://gray:guessme@localhost
6 smtp://gray:adiviname@gnu.org
7 pop://gray:secret@gnu.org
...@@ -63,4 +63,5 @@ m4_include([base64d.at]) ...@@ -63,4 +63,5 @@ m4_include([base64d.at])
63 m4_include([decode2047.at]) 63 m4_include([decode2047.at])
64 m4_include([encode2047.at]) 64 m4_include([encode2047.at])
65 m4_include([fromflt.at]) 65 m4_include([fromflt.at])
66 m4_include([wicket.at])
66 67
......
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16
17 dnl ------------------------------------------------------------
18 dnl TESTWICKET(URL, [KW = `'], [STDOUT = `'],
19 dnl [STDERR = `'], [RUN-IF-FAIL], [RUN-IF-PASS])
20 dnl
21 m4_pushdef([TESTWICKET],[
22 AT_SETUP([Wicket: [$1]])
23 AT_KEYWORDS([wicket wicket-$2])
24 AT_CHECK([wicket $abs_top_srcdir/libmailutils/tests/Wicketfile "$1" | \
25 sed "s|$abs_top_srcdir/libmailutils/tests/Wicketfile|Wicketfile|"],
26 [0],
27 [$3],[$4],[$5],[$6])
28 AT_CLEANUP])
29
30 TESTWICKET([pop://localhost],[00],
31 [pop://localhost matches pop://gray:***@localhost at Wicketfile:4
32 ])
33 TESTWICKET([pop://smith@localhost],[01],
34 [pop://smith@localhost matches pop://*:***;AUTH=+APOP@localhost at Wicketfile:3
35 ])
36 TESTWICKET([pop://foo@localhost],[02],
37 [pop://foo@localhost matches *://foo:***@localhost at Wicketfile:2
38 ])
39 TESTWICKET([pop://gnu.org],[03],
40 [pop://gnu.org matches pop://gray:***@gnu.org at Wicketfile:7
41 ])
42 TESTWICKET([smtp://gnu.org],[04],
43 [smtp://gnu.org matches smtp://gray:***@gnu.org at Wicketfile:6
44 ])
45 TESTWICKET([smtp://gray@gnu.org],[05],
46 [smtp://gray@gnu.org matches smtp://gray:***@gnu.org at Wicketfile:6
47 ])
48 TESTWICKET([smtp://localhost],[06],
49 [smtp://localhost matches smtp://gray:***@localhost at Wicketfile:5
50 ])
51
52
...\ No newline at end of file ...\ No newline at end of file
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2010 Free Software
3 Foundation, Inc.
4
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
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
9
10 GNU Mailutils is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <mailutils/mailutils.h>
24
25 const char *name;
26 mu_stream_t stream;
27
28 void
29 match_string (const char *str)
30 {
31 int rc;
32 mu_url_t u, url;
33 struct mu_debug_locus loc;
34
35 if ((rc = mu_url_create (&u, str)) != 0)
36 {
37 fprintf (stderr, "mu_url_create %s ERROR: [%d] %s",
38 str, rc, mu_strerror (rc));
39 return;
40 }
41 if ((rc = mu_url_parse (u)) != 0)
42 {
43 fprintf (stderr, "%s\n", mu_errname (rc));
44 return;
45 }
46 MU_ASSERT (mu_stream_seek (stream, 0, MU_SEEK_SET, NULL));
47 loc.file = name;
48 loc.line = 0;
49 rc = mu_wicket_stream_match_url (stream, &loc, u, &url);
50 switch (rc)
51 {
52 case 0:
53 printf ("%s matches %s at %s:%d\n",
54 mu_url_to_string (u), mu_url_to_string (url),
55 loc.file, loc.line);
56 mu_url_destroy (&url);
57 break;
58
59 case MU_ERR_NOENT:
60 printf ("no matches for %s\n", mu_url_to_string (u));
61 break;
62
63 default:
64 mu_error ("mu_wicket_stream_match_url: %s", mu_strerror (rc));
65 exit (1);
66 }
67 mu_url_destroy (&u);
68 }
69
70
71 int
72 main (int argc, char **argv)
73 {
74 if (argc < 2)
75 {
76 fprintf (stderr, "usage: %s filename [url [url...]]\n", argv[0]);
77 return 1;
78 }
79
80 name = argv[1];
81 MU_ASSERT (mu_file_stream_create (&stream, name, MU_STREAM_READ));
82
83 if (argc > 2)
84 {
85 int i;
86
87 for (i = 2; i < argc; i++)
88 match_string (argv[i]);
89 }
90 else
91 {
92 mu_stream_t in;
93 char *buf = NULL;
94 size_t size = 0, n;
95 int rc;
96
97 MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0));
98
99 while ((rc = mu_stream_getline (in, &buf, &size, &n)) == 0
100 && n > 0)
101 match_string (mu_str_stripws (buf));
102 free (buf);
103 mu_stream_destroy (&in);
104 }
105 mu_stream_destroy (&stream);
106 return 0;
107 }
108
109
110
111