Commit 3327a23a 3327a23a49e532c068972a0b2d64021361540f7b by Sergey Poznyakoff

Rewrite URL support.

The purpose is to make it modular and flexible.  URLs are
parsed out as they are created.  Missing URL parts can be
supplied via a "URL hint" at creation time (similar to
the approach used in creating mu_address_t).  Ports
can be specified either as numbers or as service names.
Original port string representation can be retrieved from
the URL, as well as its numeric value.

* libmailutils/url/accessor.h: New file.
* libmailutils/url/copy.c: New file.
* libmailutils/url/create.c: New file.
* libmailutils/url/decode.c: New file.
* libmailutils/url/destroy.c: New file.
* libmailutils/url/dup.c: New file.
* libmailutils/url/expand.c: New file.
* libmailutils/url/flag.c: New file.
* libmailutils/url/get-auth.c: New file.
* libmailutils/url/get-host.c: New file.
* libmailutils/url/get-param.c: New file.
* libmailutils/url/get-path.c: New file.
* libmailutils/url/get-portstr.c: New file.
* libmailutils/url/get-query.c: New file.
* libmailutils/url/get-scheme.c: New file.
* libmailutils/url/get-secret.c: New file.
* libmailutils/url/get-user.c: New file.
* libmailutils/url/match.c: New file.
* libmailutils/url/port.c: New file.
* libmailutils/url/scheme.c: New file.
* libmailutils/url/uplevel.c: New file.
* libmailutils/url/urlstr.c: New file.

* configure.ac (AC_CONFIG_FILES): Add libmailutils/url/Makefile
* libmailutils/Makefile.am (SUBDIRS): Add url.
(libmailutils_la_LIBADD): Link with liburl.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Remove url.c
* libmailutils/base/url.c: Remove.

* libmailutils/string/Makefile.am (libstring_la_SOURCES): Add xdecode.c
* libmailutils/string/xdecode.c: New file.

* include/mailutils/sys/url.h (_mu_url): Change type to short.
<_get_port>: Change second argument to unsigned.
<_get_portstr>: New method.
* include/mailutils/url.h (MU_URL_SCHEME): New flag.
(MU_URL_PARSE_HEXCODE, MU_URL_PARSE_HIDEPASS)
(MU_URL_PARSE_PORTSRV, MU_URL_PARSE_PORTWC)
(MU_URL_PARSE_PIPE, MU_URL_PARSE_SLASH): New flags.
(mu_url_create_hint, mu_url_copy_hints): New prototypes.
(mu_url_parse): Remove.
(mu_url_get_port): Change second argument to unsigned.
(mu_url_decode_len,mu_url_decode): Remove.
(mu_url_decode): New proto.
(mu_url_sget_portstr, mu_url_aget_portstr)
(mu_url_get_portstr): New protos.

* include/mailutils/util.h (mu_str_url_decode)
(mu_str_url_decode_inline): New protos.
* libproto/pop/mbox.c (pop_open): Port is unsigned.

* libproto/imap/folder.c: Use MU_URL_SCHEME in url_may_have.
* libproto/maildir/folder.c: Likewise.
* libproto/mailer/prog.c: Likewise.
* libproto/mailer/remote.c: Likewise.
* libproto/mailer/sendmail.c: Likewise.
* libproto/mailer/smtp.c: Likewise.
* libproto/mbox/folder.c: Likewise.
* libproto/mh/folder.c: Likewise.
* libproto/nntp/folder.c: Likewise.
* libproto/pop/folder.c: Likewise.

* imap4d/imap4d.c: Remove calls to mu_url_parse.
* libmailutils/base/registrar.c: Likewise.
* libmailutils/base/wicket.c: Likewise.
* libmailutils/mailbox/folder.c: Likewise.
* libmailutils/mailbox/mailbox.c: Likewise.
* libmailutils/mailer/mailer.c: Likewise.
* libmailutils/tests/url-parse.c: Likewise.
* libmailutils/tests/wicket.c: Likewise.
* libproto/mailer/smtp_auth.c: Likewise.
* maidag/deliver.c: Likewise.
* mu/wicket.c: Likewise.

* libmailutils/mime/mimehdr.c (mu_mimehdr_decode_param): Use
mu_str_url_decode, instead of mu_url_decode.
* libmailutils/stream/tcp.c (_tcp_instance)<port>: Change type
to unsigned short. All uses updated.
(mu_tcp_stream_create_with_source_ip)
(mu_tcp_stream_create_with_source_host)
(mu_tcp_stream_create): Port is unsigned.
* include/mailutils/stream.h (mu_tcp_stream_create_with_source_ip)
(mu_tcp_stream_create_with_source_host)
(mu_tcp_stream_create): Port is unsigned.
* include/mailutils/cpp/url.h (get_port): Return unsigned.
* libmu_cpp/url.cc (get_port): Return unsigned.
(parse): Empty function. Schedule for removal.
* python/libmu_py/url.c (api_url_parse): Empty function.
Schedule for removal.
(api_url_get_port): Port is unsigned.

* libmailutils/base/wicket.c (mu_wicket_file_match_url)
(mu_wicket_file_match_url): New parameter: parse_flags.
* mu/wicket.c (wicket_match): Use parse_flags to control
whether or not to show the plaintext password.

* doc/texinfo/url.texi: Update.
1 parent 6203ae65
Showing 62 changed files with 2120 additions and 1414 deletions
...@@ -1387,6 +1387,7 @@ AC_CONFIG_FILES([ ...@@ -1387,6 +1387,7 @@ AC_CONFIG_FILES([
1387 libmailutils/server/Makefile 1387 libmailutils/server/Makefile
1388 libmailutils/string/Makefile 1388 libmailutils/string/Makefile
1389 libmailutils/stream/Makefile 1389 libmailutils/stream/Makefile
1390 libmailutils/url/Makefile
1390 libmailutils/Makefile 1391 libmailutils/Makefile
1391 messages/Makefile 1392 messages/Makefile
1392 mh/Makefile 1393 mh/Makefile
......
...@@ -186,7 +186,7 @@ for any particular scheme. ...@@ -186,7 +186,7 @@ for any particular scheme.
186 @deftypefun int mu_url_get_host (const mu_url_t, char *, size_t, size_t *) 186 @deftypefun int mu_url_get_host (const mu_url_t, char *, size_t, size_t *)
187 @end deftypefun 187 @end deftypefun
188 188
189 @deftypefun int mu_url_get_port (const mu_url_t, long *) 189 @deftypefun int mu_url_get_port (const mu_url_t, unsigned *)
190 @end deftypefun 190 @end deftypefun
191 191
192 @deftypefun int mu_url_get_path (const mu_url_t, char *, size_t, size_t *) 192 @deftypefun int mu_url_get_path (const mu_url_t, char *, size_t, size_t *)
......
...@@ -172,7 +172,7 @@ parse_preauth_scheme (mu_debug_t debug, const char *scheme, mu_url_t url) ...@@ -172,7 +172,7 @@ parse_preauth_scheme (mu_debug_t debug, const char *scheme, mu_url_t url)
172 else if (strcmp (scheme, "ident") == 0) 172 else if (strcmp (scheme, "ident") == 0)
173 { 173 {
174 struct servent *sp; 174 struct servent *sp;
175 long n; 175 unsigned n;
176 if (url && mu_url_get_port (url, &n) == 0) 176 if (url && mu_url_get_port (url, &n) == 0)
177 ident_port = (short) n; 177 ident_port = (short) n;
178 else if ((sp = getservbyname ("auth", "tcp"))) 178 else if ((sp = getservbyname ("auth", "tcp")))
...@@ -219,13 +219,6 @@ cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val) ...@@ -219,13 +219,6 @@ cb_preauth (mu_debug_t debug, void *data, mu_config_value_t *val)
219 mu_diag_funcall (MU_DIAG_ERROR, "mu_url_create", val->v.string, rc); 219 mu_diag_funcall (MU_DIAG_ERROR, "mu_url_create", val->v.string, rc);
220 return 1; 220 return 1;
221 } 221 }
222 rc = mu_url_parse (url);
223 if (rc)
224 {
225 mu_cfg_format_error (debug, MU_DEBUG_ERROR,
226 "%s: %s", val->v.string, mu_strerror (rc));
227 return 1;
228 }
229 222
230 rc = mu_url_aget_scheme (url, &scheme); 223 rc = mu_url_aget_scheme (url, &scheme);
231 if (rc) 224 if (rc)
......
...@@ -78,8 +78,10 @@ int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename); ...@@ -78,8 +78,10 @@ int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename);
78 78
79 struct mu_debug_locus; 79 struct mu_debug_locus;
80 int mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc, 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); 81 mu_url_t url, int parse_flags,
82 mu_url_t *pticket_url);
82 int mu_wicket_file_match_url (const char *name, mu_url_t url, 83 int mu_wicket_file_match_url (const char *name, mu_url_t url,
84 int parse_flags,
83 mu_url_t *pticket_url); 85 mu_url_t *pticket_url);
84 86
85 87
......
...@@ -42,7 +42,7 @@ class Url ...@@ -42,7 +42,7 @@ class Url
42 ~Url (); 42 ~Url ();
43 43
44 void parse (); 44 void parse ();
45 long get_port (); 45 unsigned get_port ();
46 std::string get_scheme (); 46 std::string get_scheme ();
47 std::string get_user (); 47 std::string get_user ();
48 std::string get_auth (); 48 std::string get_auth ();
......
...@@ -176,14 +176,14 @@ int mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str, ...@@ -176,14 +176,14 @@ int mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str,
176 int mu_streamref_create (mu_stream_t *pref, mu_stream_t str); 176 int mu_streamref_create (mu_stream_t *pref, mu_stream_t str);
177 177
178 int mu_tcp_stream_create_with_source_ip (mu_stream_t *stream, 178 int mu_tcp_stream_create_with_source_ip (mu_stream_t *stream,
179 const char *host, int port, 179 const char *host, unsigned port,
180 unsigned long source_ip, 180 unsigned long source_ip,
181 int flags); 181 int flags);
182 int mu_tcp_stream_create_with_source_host (mu_stream_t *stream, 182 int mu_tcp_stream_create_with_source_host (mu_stream_t *stream,
183 const char *host, int port, 183 const char *host, unsigned port,
184 const char *source_host, 184 const char *source_host,
185 int flags); 185 int flags);
186 int mu_tcp_stream_create (mu_stream_t *stream, const char *host, int port, 186 int mu_tcp_stream_create (mu_stream_t *stream, const char *host, unsigned port,
187 int flags); 187 int flags);
188 188
189 /* Transcript output levels */ 189 /* Transcript output levels */
......
...@@ -35,7 +35,8 @@ struct _mu_url ...@@ -35,7 +35,8 @@ struct _mu_url
35 mu_secret_t secret; 35 mu_secret_t secret;
36 char *auth; 36 char *auth;
37 char *host; 37 char *host;
38 long port; 38 short port;
39 char *portstr;
39 char *path; 40 char *path;
40 char **fvpairs; 41 char **fvpairs;
41 int fvcount; 42 int fvcount;
...@@ -53,7 +54,8 @@ struct _mu_url ...@@ -53,7 +54,8 @@ struct _mu_url
53 int (*_get_secret) (const mu_url_t, mu_secret_t *); 54 int (*_get_secret) (const mu_url_t, mu_secret_t *);
54 int (*_get_auth) (const mu_url_t, char *, size_t, size_t *); 55 int (*_get_auth) (const mu_url_t, char *, size_t, size_t *);
55 int (*_get_host) (const mu_url_t, char *, size_t, size_t *); 56 int (*_get_host) (const mu_url_t, char *, size_t, size_t *);
56 int (*_get_port) (const mu_url_t, long *); 57 int (*_get_port) (const mu_url_t, unsigned *);
58 int (*_get_portstr)(const mu_url_t, char *, size_t, size_t *);
57 int (*_get_path) (const mu_url_t, char *, size_t, size_t *); 59 int (*_get_path) (const mu_url_t, char *, size_t, size_t *);
58 int (*_get_query) (const mu_url_t, char *, size_t, size_t *); 60 int (*_get_query) (const mu_url_t, char *, size_t, size_t *);
59 int (*_uplevel) (const mu_url_t, mu_url_t *); 61 int (*_uplevel) (const mu_url_t, mu_url_t *);
......
...@@ -25,14 +25,15 @@ ...@@ -25,14 +25,15 @@
25 extern "C" { 25 extern "C" {
26 #endif 26 #endif
27 27
28 #define MU_URL_USER 0x0001 /* Has a user part */ 28 #define MU_URL_SCHEME 0x0001
29 #define MU_URL_SECRET 0x0002 /* Has a secret (password) part */ 29 #define MU_URL_USER 0x0002 /* Has a user part */
30 #define MU_URL_AUTH 0x0004 /* Has auth part */ 30 #define MU_URL_SECRET 0x0004 /* Has a secret (password) part */
31 #define MU_URL_HOST 0x0008 /* Has host part */ 31 #define MU_URL_AUTH 0x0008 /* Has auth part */
32 #define MU_URL_PORT 0x0010 /* Has port part */ 32 #define MU_URL_HOST 0x0010 /* Has host part */
33 #define MU_URL_PATH 0x0020 /* Has path */ 33 #define MU_URL_PORT 0x0020 /* Has port part */
34 #define MU_URL_PARAM 0x0040 /* Has parameters */ 34 #define MU_URL_PATH 0x0040 /* Has path */
35 #define MU_URL_QUERY 0x0080 /* Has query */ 35 #define MU_URL_PARAM 0x0080 /* Has parameters */
36 #define MU_URL_QUERY 0x0100 /* Has query */
36 37
37 #define MU_URL_CRED (MU_URL_USER | MU_URL_SECRET | MU_URL_AUTH) 38 #define MU_URL_CRED (MU_URL_USER | MU_URL_SECRET | MU_URL_AUTH)
38 /* Has some of authentication credentials */ 39 /* Has some of authentication credentials */
...@@ -45,6 +46,28 @@ extern "C" { ...@@ -45,6 +46,28 @@ extern "C" {
45 MU_URL_PARAM | \ 46 MU_URL_PARAM | \
46 MU_URL_QUERY) 47 MU_URL_QUERY)
47 48
49 /* Parser flags */
50 #define MU_URL_PARSE_HEXCODE 0x0001 /* Decode % notations (RFC 1738,
51 section 2.2) */
52 #define MU_URL_PARSE_HIDEPASS 0x0002 /* Hide password in the URL */
53 #define MU_URL_PARSE_PORTSRV 0x0004 /* Use getservbyname to determine
54 port number */
55 #define MU_URL_PARSE_PORTWC 0x0008 /* Allow wildcard (*) as a port
56 number (for tickets) */
57 #define MU_URL_PARSE_PIPE 0x0010 /* Translate "| ..." to
58 "prog://..." */
59 #define MU_URL_PARSE_SLASH 0x0020 /* Translate "/..." to
60 "file:///..." */
61
62 #define MU_URL_PARSE_DEFAULT \
63 (MU_URL_PARSE_HEXCODE|MU_URL_PARSE_HIDEPASS|MU_URL_PARSE_PORTSRV|\
64 MU_URL_PARSE_PIPE|MU_URL_PARSE_SLASH)
65 #define MU_URL_PARSE_ALL (MU_URL_PARSE_DEFAULT|MU_URL_PARSE_PORTWC)
66
67 int mu_url_create_hint (mu_url_t *purl, const char *str, int flags,
68 mu_url_t hint);
69 int mu_url_copy_hints (mu_url_t url, mu_url_t hint);
70
48 int mu_url_create (mu_url_t *, const char *name); 71 int mu_url_create (mu_url_t *, const char *name);
49 int mu_url_dup (mu_url_t old_url, mu_url_t *new_url); 72 int mu_url_dup (mu_url_t old_url, mu_url_t *new_url);
50 int mu_url_uplevel (mu_url_t url, mu_url_t *upurl); 73 int mu_url_uplevel (mu_url_t url, mu_url_t *upurl);
...@@ -53,7 +76,6 @@ int mu_url_get_flags (mu_url_t, int *); ...@@ -53,7 +76,6 @@ int mu_url_get_flags (mu_url_t, int *);
53 int mu_url_has_flag (mu_url_t, int); 76 int mu_url_has_flag (mu_url_t, int);
54 77
55 void mu_url_destroy (mu_url_t *); 78 void mu_url_destroy (mu_url_t *);
56 int mu_url_parse (mu_url_t);
57 79
58 int mu_url_sget_scheme (const mu_url_t, const char **); 80 int mu_url_sget_scheme (const mu_url_t, const char **);
59 int mu_url_aget_scheme (const mu_url_t, char **); 81 int mu_url_aget_scheme (const mu_url_t, char **);
...@@ -80,7 +102,11 @@ int mu_url_get_path (const mu_url_t, char *, size_t, size_t *); ...@@ -80,7 +102,11 @@ int mu_url_get_path (const mu_url_t, char *, size_t, size_t *);
80 int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv); 102 int mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv);
81 int mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv); 103 int mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv);
82 104
83 int mu_url_get_port (const mu_url_t, long *); 105 int mu_url_sget_portstr (const mu_url_t, const char **);
106 int mu_url_aget_portstr (const mu_url_t, char **);
107 int mu_url_get_portstr (const mu_url_t, char *, size_t, size_t *);
108
109 int mu_url_get_port (const mu_url_t, unsigned *);
84 110
85 int mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp); 111 int mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp);
86 int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp); 112 int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp);
...@@ -101,11 +127,9 @@ int mu_url_is_same_path (mu_url_t, mu_url_t); ...@@ -101,11 +127,9 @@ int mu_url_is_same_path (mu_url_t, mu_url_t);
101 int mu_url_is_same_host (mu_url_t, mu_url_t); 127 int mu_url_is_same_host (mu_url_t, mu_url_t);
102 int mu_url_is_same_port (mu_url_t, mu_url_t); 128 int mu_url_is_same_port (mu_url_t, mu_url_t);
103 129
104 char *mu_url_decode_len (const char *s, size_t len);
105 char *mu_url_decode (const char *s);
106
107 int mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *wcn); 130 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); 131
132 int mu_url_decode (mu_url_t url);
109 133
110 #ifdef __cplusplus 134 #ifdef __cplusplus
111 } 135 }
......
...@@ -42,7 +42,8 @@ int mu_unre_set_regex (const char *str, int caseflag, char **errp); ...@@ -42,7 +42,8 @@ int mu_unre_set_regex (const char *str, int caseflag, char **errp);
42 int mu_unre_subject (const char *subject, const char **new_subject); 42 int mu_unre_subject (const char *subject, const char **new_subject);
43 int mu_is_proto (const char *p); 43 int mu_is_proto (const char *p);
44 int mu_mh_delim (const char *str); 44 int mu_mh_delim (const char *str);
45 45 void mu_str_url_decode_inline (char *str);
46 int mu_str_url_decode (char **ptr, const char *s);
46 47
47 /* ----------------------- */ 48 /* ----------------------- */
48 /* Date & time functions */ 49 /* Date & time functions */
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 # <http://www.gnu.org/licenses/>. 17 # <http://www.gnu.org/licenses/>.
18 18
19 SUBDIRS = auth base address cfg diag filter mailbox mailer mime\ 19 SUBDIRS = auth base address cfg diag filter mailbox mailer mime\
20 server string stream . tests 20 server string stream url . tests
21 21
22 lib_LTLIBRARIES = libmailutils.la 22 lib_LTLIBRARIES = libmailutils.la
23 23
...@@ -36,7 +36,8 @@ libmailutils_la_LIBADD = \ ...@@ -36,7 +36,8 @@ libmailutils_la_LIBADD = \
36 mime/libmime.la\ 36 mime/libmime.la\
37 server/libserver.la\ 37 server/libserver.la\
38 string/libstring.la\ 38 string/libstring.la\
39 stream/libstream.la 39 stream/libstream.la\
40 url/liburl.la
40 41
41 libmailutils_la_LDFLAGS = -version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ 42 libmailutils_la_LDFLAGS = -version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@
42 43
......
...@@ -61,7 +61,6 @@ libbase_la_SOURCES = \ ...@@ -61,7 +61,6 @@ libbase_la_SOURCES = \
61 tempfile.c\ 61 tempfile.c\
62 ticket.c\ 62 ticket.c\
63 tilde.c\ 63 tilde.c\
64 url.c\
65 usremail.c\ 64 usremail.c\
66 vartab.c\ 65 vartab.c\
67 version.c\ 66 version.c\
......
...@@ -220,8 +220,6 @@ mu_registrar_lookup (const char *name, int flags, ...@@ -220,8 +220,6 @@ mu_registrar_lookup (const char *name, int flags,
220 rc = mu_url_create (&url, name); 220 rc = mu_url_create (&url, name);
221 if (rc) 221 if (rc)
222 return rc; 222 return rc;
223 rc = mu_url_parse (url);
224 if (rc == 0)
225 rc = mu_registrar_lookup_url (url, flags, precord, pflags); 223 rc = mu_registrar_lookup_url (url, flags, precord, pflags);
226 mu_url_destroy (&url); 224 mu_url_destroy (&url);
227 return rc; 225 return rc;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2007, 2008, 2009, 2010 Free Software
3 Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <ctype.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #ifdef HAVE_STRINGS_H
28 # include <strings.h>
29 #endif
30
31 #include <mailutils/util.h>
32 #include <mailutils/errno.h>
33 #include <mailutils/argcv.h>
34 #include <mailutils/secret.h>
35 #include <mailutils/cctype.h>
36 #include <mailutils/cstr.h>
37 #include <mailutils/sys/url.h>
38
39 #define AC2(a,b) a ## b
40 #define AC4(a,b,c,d) a ## b ## c ## d
41
42 static int url_parse0 (mu_url_t, char *, size_t *poff, int *decode);
43
44 static int
45 parse_query (const char *query,
46 char *delim,
47 int *pargc, char ***pargv, const char **pend)
48 {
49 size_t count, i;
50 char **v;
51 const char *p;
52
53 for (p = query, count = 0; ; count++)
54 {
55 size_t len = strcspn (p, delim);
56 p += len;
57 if (!*p || *p == delim[1])
58 break;
59 p++;
60 }
61
62 if (pend)
63 *pend = p;
64 if (p == query)
65 return 0;
66 count++;
67
68 v = calloc (count + 1, sizeof (v[0]));
69 for (i = 0, p = query; i < count; i++)
70 {
71 size_t len = strcspn (p, delim);
72 v[i] = mu_url_decode_len (p, len);
73 if (v[i] == NULL)
74 {
75 mu_argcv_free (i, v);
76 return 1;
77 }
78 p += len + 1;
79 }
80 v[i] = NULL;
81
82 *pargc = count;
83 *pargv = v;
84 return 0;
85 }
86
87 int
88 mu_url_create (mu_url_t *purl, const char *name)
89 {
90 mu_url_t url = calloc (1, sizeof (*url));
91 if (url == NULL)
92 return ENOMEM;
93
94 url->name = strdup (name);
95 if (url->name == NULL)
96 {
97 free (url);
98 return ENOMEM;
99 }
100 *purl = url;
101 return 0;
102 }
103
104 static char **
105 argcv_copy (size_t argc, char **argv)
106 {
107 size_t i;
108 char **nv = calloc (argc + 1, sizeof (nv[0]));
109 if (!nv)
110 return NULL;
111 for (i = 0; i < argc; i++)
112 if ((nv[i] = strdup (argv[i])) == NULL)
113 {
114 mu_argcv_free (i, nv);
115 free (nv);
116 return NULL;
117 }
118 return nv;
119 }
120
121 static int
122 mu_url_copy0 (mu_url_t old_url, mu_url_t new_url)
123 {
124 const char *str;
125 size_t argc;
126 char **argv;
127 int rc;
128 mu_secret_t sec;
129
130 #define URLCOPY(what) \
131 do \
132 { \
133 rc = AC2(mu_url_sget_,what) (old_url, &str); \
134 if (rc == 0) \
135 { \
136 if ((new_url->what = strdup (str)) == NULL) \
137 return ENOMEM; \
138 } \
139 else if (rc != MU_ERR_NOENT) \
140 return rc; \
141 } \
142 while (0);
143
144 URLCOPY (scheme);
145 URLCOPY (user);
146
147 rc = mu_url_get_secret (old_url, &sec);
148 if (rc == MU_ERR_NOENT)
149 new_url->secret = NULL;
150 else if (rc)
151 return rc;
152 else
153 {
154 rc = mu_secret_dup (sec, &new_url->secret);
155 if (rc)
156 return rc;
157 }
158
159 URLCOPY (auth);
160 URLCOPY (host);
161 new_url->port = old_url->port;
162 URLCOPY (path);
163
164 rc = mu_url_sget_fvpairs (old_url, &argc, &argv);
165 if (rc == 0 && argc)
166 {
167 if ((new_url->fvpairs = argcv_copy (argc, argv)) == NULL)
168 return ENOMEM;
169 new_url->fvcount = argc;
170 }
171
172 rc = mu_url_sget_query (old_url, &argc, &argv);
173 if (rc == 0 && argc)
174 {
175 if ((new_url->qargv = argcv_copy (argc, argv)) == NULL)
176 return ENOMEM;
177 new_url->qargc = argc;
178 }
179 new_url->flags = old_url->flags;
180 return 0;
181 #undef URLCOPY
182 }
183
184 int
185 mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
186 {
187 mu_url_t url;
188 int rc = mu_url_create (&url, mu_url_to_string (old_url));
189
190 if (rc)
191 return rc;
192
193 rc = mu_url_copy0 (old_url, url);
194 if (rc == 0)
195 *new_url = url;
196 else
197 mu_url_destroy (&url);
198 return rc;
199 }
200
201 int
202 mu_url_uplevel (mu_url_t url, mu_url_t *upurl)
203 {
204 int rc;
205 char *p;
206 mu_url_t new_url;
207
208 if (url->_uplevel)
209 return url->_uplevel (url, upurl);
210
211 if (!url->path)
212 return MU_ERR_NOENT;
213 p = strrchr (url->path, '/');
214
215 rc = mu_url_dup (url, &new_url);
216 if (rc == 0)
217 {
218 if (!p || p == url->path)
219 {
220 free (new_url->path);
221 new_url->path = NULL;
222 }
223 else
224 {
225 size_t size = p - url->path;
226 new_url->path = realloc (new_url->path, size + 1);
227 if (!new_url->path)
228 {
229 mu_url_destroy (&new_url);
230 return ENOMEM;
231 }
232 memcpy (new_url->path, url->path, size);
233 new_url->path[size] = 0;
234 }
235 *upurl = new_url;
236 }
237 return rc;
238 }
239
240 void
241 mu_url_destroy (mu_url_t * purl)
242 {
243 if (purl && *purl)
244 {
245 mu_url_t url = (*purl);
246
247 if (url->_destroy)
248 url->_destroy (url);
249
250 if (url->name)
251 free (url->name);
252
253 if (url->scheme)
254 free (url->scheme);
255
256 if (url->user)
257 free (url->user);
258
259 mu_secret_destroy (&url->secret);
260
261 if (url->auth)
262 free (url->auth);
263
264 if (url->host)
265 free (url->host);
266
267 if (url->path)
268 free (url->path);
269
270 if (url->fvcount)
271 mu_argcv_free (url->fvcount, url->fvpairs);
272
273 mu_argcv_free (url->qargc, url->qargv);
274
275 free (url);
276
277 *purl = NULL;
278 }
279 }
280
281 int
282 mu_url_parse (mu_url_t url)
283 {
284 int err = 0;
285 char *n = NULL;
286 struct _mu_url u;
287 size_t pstart;
288 mu_secret_t newsec;
289 int want_decode;
290
291 if (!url || !url->name)
292 return EINVAL;
293
294 memset (&u, 0, sizeof u);
295 /* can't have been parsed already */
296 if (url->flags)
297 return EINVAL;
298
299 n = strdup (url->name);
300
301 if (!n)
302 return ENOMEM;
303
304 err = url_parse0 (&u, n, &pstart, &want_decode);
305
306 if (!err)
307 {
308 if (u.secret)
309 {
310 /* Obfuscate the password */
311 #define PASS_REPL "***"
312 #define PASS_REPL_LEN (sizeof (PASS_REPL) - 1)
313 size_t plen = mu_secret_length (u.secret);
314 size_t nlen = strlen (url->name);
315 size_t len = nlen - plen + PASS_REPL_LEN + 1;
316 char *newname;
317
318 memset (url->name + pstart, 0, plen);
319 if (len > nlen + 1)
320 {
321 newname = realloc (url->name, len);
322 if (!newname)
323 goto CLEANUP;
324 url->name = newname;
325 }
326 else
327 newname = url->name;
328 memmove (newname + pstart + PASS_REPL_LEN, newname + pstart + plen,
329 nlen - (pstart + plen) + 1);
330 memcpy (newname + pstart, PASS_REPL, PASS_REPL_LEN);
331 }
332
333 /* Dup the strings we found. We wouldn't have to do this
334 if we did a single alloc of the source url name, and
335 kept it around. It's also a good time to do hex decoding,
336 though.
337 */
338
339 #define UALLOC(X,f) \
340 if (u.X && u.X[0]) \
341 { \
342 url->X = want_decode ? mu_url_decode (u.X) : strdup (u.X); \
343 if (!url->X) \
344 { \
345 err = ENOMEM; \
346 goto CLEANUP; \
347 } \
348 url->flags |= f; \
349 } \
350 else \
351 { \
352 /* Set zero-length strings to NULL. */ \
353 url->X = NULL; \
354 }
355
356 UALLOC (scheme, 0);
357 UALLOC (user, MU_URL_USER);
358
359 if (u.secret)
360 {
361 char *pass = mu_url_decode (mu_secret_password (u.secret));
362 err = mu_secret_create (&newsec, pass, strlen (pass));
363 memset (pass, 0, strlen (pass));
364 mu_secret_destroy (&u.secret);
365 if (err)
366 goto CLEANUP;
367
368 url->secret = newsec;
369 url->flags |= MU_URL_SECRET;
370 }
371
372 UALLOC (auth, MU_URL_AUTH);
373 UALLOC (host, MU_URL_HOST);
374 UALLOC (path, MU_URL_PATH);
375
376 #undef UALLOC
377 url->fvcount = u.fvcount;
378 url->fvpairs = u.fvpairs;
379 if (u.fvcount)
380 url->flags |= MU_URL_PARAM;
381
382 url->qargc = u.qargc;
383 url->qargv = u.qargv;
384 if (u.qargc)
385 url->flags |= MU_URL_QUERY;
386
387 url->port = u.port;
388 if (u.port)
389 url->flags |= MU_URL_PORT;
390 }
391
392 CLEANUP:
393 memset (n, 0, strlen (n));
394 free (n);
395
396 if (err)
397 {
398 #define UFREE(X) if (X) { free(X); X = 0; }
399
400 UFREE (url->scheme);
401 UFREE (url->user);
402 mu_secret_destroy (&u.secret);
403 UFREE (url->auth);
404 UFREE (url->host);
405 UFREE (url->path);
406 mu_argcv_free (url->fvcount, url->fvpairs);
407 mu_argcv_free (url->qargc, url->qargv);
408 #undef UFREE
409 }
410
411 return err;
412 }
413
414 /*
415
416 Syntax, condensed from RFC 1738, and extended with the ;auth=
417 of RFC 2384 (for POP) and RFC 2192 (for IMAP):
418
419 url =
420 scheme ":" [ "//"
421
422 [ user [ ( ":" password ) | ( ";auth=" auth ) ] "@" ]
423
424 host [ ":" port ]
425
426 [ ( "/" urlpath ) | ( "?" query ) ] ]
427
428 All hell will break loose in this parser if the user/pass/auth
429 portion is missing, and the urlpath has any @ or : characters
430 in it. A imap mailbox, say, named after the email address of
431 the person the mail is from:
432
433 imap://imap.uniserve.com/alain@qnx.com
434
435 Is this required to be % quoted, though? I hope so!
436
437 */
438
439 static int
440 url_parse0 (mu_url_t u, char *name, size_t *poff, int *decode)
441 {
442 char *start = name;
443 char *p; /* pointer into name */
444
445 /* reject the obvious */
446 if (name == NULL)
447 return EINVAL;
448
449 if (name[0] == '/')
450 {
451 u->scheme = "file";
452 *decode = 0;
453 }
454 else if (name[0] == '|')
455 {
456 int rc;
457 u->scheme = "prog";
458 *decode = 0;
459 rc = mu_argcv_get (name + 1, NULL, NULL, &u->qargc, &u->qargv);
460 if (rc == 0)
461 {
462 u->path = strdup (u->qargv[0]);
463 if (!u->path)
464 rc = ENOMEM;
465 }
466 return rc;
467 }
468 else
469 {
470 *decode = 1;
471 /* Parse out the SCHEME. */
472 p = strchr (name, ':');
473 if (p == NULL)
474 return MU_ERR_PARSE;
475
476 *p++ = 0;
477
478 u->scheme = name;
479
480 /* RFC 1738, section 2.1, lower the scheme case */
481 for (; name < p; name++)
482 *name = mu_tolower (*name);
483
484 name = p;
485 }
486
487 /* Check for nothing following the scheme. */
488 if (!*name)
489 return 0;
490
491 if (strncmp (name, "//", 2) == 0)
492 {
493 name += 2;
494
495 if (name[0] == '/')
496 {
497 u->path = name;
498 p = u->path + strcspn (u->path, ";?");
499 }
500 else
501 {
502 /* Split into LHS and RHS of the '@', and then parse each side. */
503 u->host = strchr (name, '@');
504 if (u->host == NULL)
505 u->host = name;
506 else
507 {
508 char *pass = NULL;
509
510 /* Parse the LHS into an identification/authentication pair. */
511 *u->host++ = 0;
512
513 u->user = name;
514
515 /* Try to split the user into a:
516 <user>:<password>
517 or
518 <user>:<password>;AUTH=<auth>
519 */
520
521 for (; *name; name++)
522 {
523 if (*name == ':')
524 {
525 *name++ = 0;
526 pass = name;
527 *poff = pass - start;
528 }
529 else if (*name == ';')
530 {
531 /* Make sure it's the auth token. */
532 if (mu_c_strncasecmp (name + 1, "auth=", 5) == 0)
533 {
534 *name++ = 0;
535 name += 5;
536 u->auth = name;
537 break;
538 }
539 }
540 }
541
542 if (pass)
543 {
544 if (mu_secret_create (&u->secret, pass, strlen (pass)))
545 return ENOMEM;
546 else
547 /* Obfuscate password */
548 memset (pass, 0, strlen (pass));
549 }
550 }
551
552 /* Parse the host and port from the RHS. */
553 p = strchr (u->host, ':');
554 if (p)
555 {
556 *p++ = 0;
557 u->port = strtol (p, &p, 10);
558
559 /* Check for garbage after the port: we should be on the start
560 of a path, a query, or at the end of the string. */
561 if (*p && strcspn (p, "/?") != 0)
562 return MU_ERR_PARSE;
563 }
564 else
565 p = u->host + strcspn (u->host, ";/?");
566 }
567 }
568 else
569 {
570 u->path = name;
571 p = u->path + strcspn (u->path, ";?");
572 }
573
574 /* Either way, if we're not at a nul, we're at a path or query. */
575 if (u->path == NULL && *p == '/')
576 {
577 /* found a path */
578 *p++ = 0;
579 u->path = p;
580 p = u->path + strcspn (u->path, ";?");
581 }
582
583 if (*p == ';')
584 {
585 *p++ = 0;
586 if (parse_query (p, ";?", &u->fvcount, &u->fvpairs, (const char **)&p))
587 return ENOMEM;
588 }
589
590 if (*p == '?')
591 {
592 /* found a query */
593 *p++ = 0;
594 if (parse_query (p, "&", &u->qargc, &u->qargv, NULL))
595 return ENOMEM;
596 }
597
598 return 0;
599 }
600
601
602 /* General accessors: */
603 #define ACCESSOR(action,field) AC4(mu_url_,action,_,field)
604
605 #define DECL_SGET(field) \
606 int \
607 ACCESSOR(sget,field) (mu_url_t url, char const **sptr) \
608 { \
609 if (url == NULL) \
610 return EINVAL; \
611 if (!url->field) \
612 { \
613 if (url->AC2(_get_,field)) \
614 { \
615 size_t n; \
616 char *buf; \
617 \
618 int status = url->AC2(_get_,field) (url, NULL, 0, &n); \
619 if (status) \
620 return status; \
621 \
622 buf = malloc (n + 1); \
623 if (!buf) \
624 return ENOMEM; \
625 \
626 status = url->AC2(_get_,field) (url, buf, n + 1, NULL); \
627 if (status) \
628 return status; \
629 \
630 if (buf[0]) \
631 { \
632 url->field = mu_url_decode (buf); \
633 free (buf); \
634 } \
635 else \
636 url->field = buf; \
637 if (!url->field) \
638 return ENOMEM; \
639 } \
640 else \
641 return MU_ERR_NOENT; \
642 } \
643 *sptr = url->field; \
644 return 0; \
645 }
646
647 #define DECL_GET(field) \
648 int \
649 ACCESSOR(get,field) (mu_url_t url, char *buf, size_t len, size_t *n) \
650 { \
651 size_t i; \
652 const char *str; \
653 int status = ACCESSOR(sget, field) (url, &str); \
654 \
655 if (status) \
656 return status; \
657 \
658 i = mu_cpystr (buf, str, len); \
659 if (n) \
660 *n = i; \
661 return 0; \
662 }
663
664 #define DECL_AGET(field) \
665 int \
666 ACCESSOR(aget, field) (mu_url_t url, char **buf) \
667 { \
668 const char *str; \
669 int status = ACCESSOR(sget, field) (url, &str); \
670 \
671 if (status) \
672 return status; \
673 \
674 if (str) \
675 { \
676 *buf = strdup (str); \
677 if (!*buf) \
678 status = ENOMEM; \
679 } \
680 else \
681 *buf = NULL; \
682 return status; \
683 }
684
685 #define DECL_CMP(field) \
686 int \
687 ACCESSOR(is_same,field) (mu_url_t url1, mu_url_t url2) \
688 { \
689 const char *s1, *s2; \
690 int status1, status2; \
691 \
692 status1 = ACCESSOR(sget, field) (url1, &s1); \
693 if (status1 && status1 != MU_ERR_NOENT) \
694 return 0; \
695 status2 = ACCESSOR(sget, field) (url2, &s2); \
696 if (status2 && status2 != MU_ERR_NOENT) \
697 return 0; \
698 \
699 if (status1 || status2) \
700 return status1 == status2; /* Both fields are missing */ \
701 return mu_c_strcasecmp (s1, s2) == 0; \
702 }
703
704 #define DECL_ACCESSORS(field) \
705 DECL_SGET(field) \
706 DECL_GET(field) \
707 DECL_AGET(field) \
708 DECL_CMP(field)
709
710
711 /* Declare particular accessors */
712 DECL_ACCESSORS (scheme)
713 DECL_ACCESSORS (user)
714 DECL_ACCESSORS (auth)
715 DECL_ACCESSORS (host)
716 DECL_ACCESSORS (path)
717
718 int
719 mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret)
720 {
721 if (url->_get_secret)
722 return url->_get_secret (url, psecret);
723 if (url->secret == NULL)
724 return MU_ERR_NOENT;
725 mu_secret_ref (url->secret);
726 *psecret = url->secret;
727 return 0;
728 }
729
730 int
731 mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
732 {
733 if (url == NULL)
734 return EINVAL;
735 /* See FIXME below */
736 *qc = url->qargc;
737 *qv = url->qargv;
738 return 0;
739 }
740
741 int
742 mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv)
743 {
744 size_t qargc, i;
745 char **qargv;
746 char **qcopy;
747
748 int rc = mu_url_sget_fvpairs (url, &qargc, &qargv);
749 if (rc)
750 return rc;
751
752 qcopy = calloc (qargc + 1, sizeof (qcopy[0]));
753 if (!qcopy)
754 return errno;
755 for (i = 0; i < qargc; i++)
756 {
757 if (!(qcopy[i] = strdup (qargv[i])))
758 {
759 mu_argcv_free (i, qcopy);
760 return errno;
761 }
762 }
763 qcopy[i] = NULL;
764 *qc = qargc;
765 *qv = qcopy;
766 return 0;
767 }
768
769 /* field-value pairs accessors */
770 int
771 mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp)
772 {
773 if (url == NULL)
774 return EINVAL;
775 /* FIXME: no _get_fvpairs method, but the method stuff needs to be rewritten
776 anyway */
777 *fvc = url->fvcount;
778 *fvp = url->fvpairs;
779 return 0;
780 }
781
782 int
783 mu_url_sget_param (const mu_url_t url, const char *param, const char **val)
784 {
785 size_t fvc;
786 char **fvp;
787 int status = mu_url_sget_fvpairs (url, &fvc, &fvp);
788
789 if (status)
790 return status;
791
792 if (fvc)
793 {
794 size_t i;
795
796 for (i = 0; i < fvc; i++)
797 {
798 const char *p;
799 char *q;
800
801 for (p = param, q = fvp[i]; *p && *q && *p == *q; p++, q++)
802 ;
803 if (*p == 0)
804 {
805 if (*q == 0)
806 {
807 if (val)
808 *val = q;
809 return 0;
810 }
811 else if (*q == '=')
812 {
813 if (val)
814 *val = q + 1;
815 return 0;
816 }
817 }
818 }
819 }
820
821 return MU_ERR_NOENT;
822 }
823
824 int
825 mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp)
826 {
827 size_t fvc, i;
828 char **fvp;
829 char **fvcopy;
830
831 int rc = mu_url_sget_fvpairs (url, &fvc, &fvp);
832 if (rc)
833 return rc;
834
835 fvcopy = calloc (fvc + 1, sizeof (fvcopy[0]));
836 if (!fvcopy)
837 return errno;
838 for (i = 0; i < fvc; i++)
839 {
840 if (!(fvcopy[i] = strdup (fvp[i])))
841 {
842 mu_argcv_free (i, fvcopy);
843 return errno;
844 }
845 }
846 fvcopy[i] = NULL;
847 *pfvc = fvc;
848 *pfvp = fvcopy;
849 return 0;
850 }
851
852 int
853 mu_url_aget_param (const mu_url_t url, const char *param, char **val)
854 {
855 const char *s;
856 int status = mu_url_sget_param (url, param, &s);
857
858 if (status == 0)
859 {
860 *val = strdup (s);
861 if (!*val)
862 status = ENOMEM;
863 }
864 return status;
865 }
866
867 int
868 mu_url_get_port (const mu_url_t url, long *pport)
869 {
870 if (url == NULL)
871 return EINVAL;
872 if (url->_get_port)
873 return url->_get_port (url, pport);
874 *pport = url->port;
875 return 0;
876 }
877
878 const char *
879 mu_url_to_string (const mu_url_t url)
880 {
881 if (url == NULL || url->name == NULL)
882 return "";
883 return url->name;
884 }
885
886 int
887 mu_url_set_scheme (mu_url_t url, const char *scheme)
888 {
889 char *p;
890 if (!url || !scheme)
891 return EINVAL;
892 p = realloc (url->scheme, strlen (scheme) + 1);
893 if (!p)
894 return ENOMEM;
895 strcpy (url->scheme, scheme);
896 return 0;
897 }
898
899 int
900 mu_url_is_scheme (mu_url_t url, const char *scheme)
901 {
902 if (url && scheme && url->scheme
903 && mu_c_strcasecmp (url->scheme, scheme) == 0)
904 return 1;
905
906 return 0;
907 }
908
909 int
910 mu_url_is_same_port (mu_url_t url1, mu_url_t url2)
911 {
912 long p1 = 0, p2 = 0;
913
914 mu_url_get_port (url1, &p1);
915 mu_url_get_port (url2, &p2);
916 return (p1 == p2);
917 }
918
919 /* From RFC 1738, section 2.2 */
920 char *
921 mu_url_decode_len (const char *s, size_t len)
922 {
923 char *d;
924 const char *eos = s + len;
925 int i;
926
927 d = malloc (len + 1);
928 if (!d)
929 return NULL;
930
931 for (i = 0; s < eos; i++)
932 {
933 if (*s != '%')
934 {
935 d[i] = *s;
936 s++;
937 }
938 else
939 {
940 unsigned long ul = 0;
941
942 s++;
943
944 /* don't check return value, it's correctly coded, or it's not,
945 in which case we just skip the garbage, this is a decoder,
946 not an AI project */
947
948 mu_hexstr2ul (&ul, s, 2);
949
950 s += 2;
951
952 d[i] = (char) ul;
953 }
954 }
955
956 d[i] = 0;
957
958 return d;
959 }
960
961 char *
962 mu_url_decode (const char *s)
963 {
964 return mu_url_decode_len (s, strlen (s));
965 }
966
967 #define is_wildcard(s) ((s)[0] == '*' && s[1] == 0)
968
969 #define WEIGHT_SCHEME 3
970 #define WEIGHT_USER 4
971 #define WEIGHT_HOST 2
972 #define WEIGHT_PORT 1
973
974 int
975 mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *pwc)
976 {
977 int wcnt = 0;
978
979 if (is_wildcard (ticket->scheme))
980 wcnt += WEIGHT_SCHEME;
981 else if (mu_c_strcasecmp (ticket->scheme, url->scheme))
982 return 0;
983
984 if (ticket->flags & MU_URL_HOST)
985 {
986 if (is_wildcard (ticket->host))
987 wcnt += WEIGHT_HOST;
988 else if (url->flags & MU_URL_HOST)
989 {
990 if (mu_c_strcasecmp (ticket->host, url->host))
991 /* FIXME: Compare IP addresses */
992 return 0;
993 }
994 else
995 return 0;
996 }
997 else
998 wcnt += WEIGHT_HOST;
999
1000 if (ticket->flags & MU_URL_PORT)
1001 {
1002 /* FIXME: No way to put a wildcard in the ticket file */
1003 if (url->port & MU_URL_PORT)
1004 {
1005 if (ticket->port != url->port)
1006 return 0;
1007 else
1008 wcnt += WEIGHT_PORT;
1009 }
1010 }
1011 else
1012 wcnt += WEIGHT_PORT;
1013
1014 if (ticket->flags & MU_URL_USER)
1015 {
1016 if (is_wildcard (ticket->user))
1017 wcnt += WEIGHT_USER;
1018
1019 /* If ticket has a user or pass, but url doesn't, that's OK, we were
1020 looking for this info. But if url does have a user/pass, it
1021 must match the ticket. */
1022 else if (url->flags & MU_URL_USER)
1023 {
1024 if (strcmp (ticket->user, url->user))
1025 return 0;
1026 }
1027 }
1028 else
1029 wcnt += WEIGHT_USER;
1030
1031 /* Guess it matches. */
1032 if (pwc)
1033 *pwc = wcnt;
1034 return 1;
1035 }
1036
1037 int
1038 mu_url_init (mu_url_t url, int port, const char *scheme)
1039 {
1040 int status = 0;
1041
1042 url->_destroy = NULL;
1043
1044 status = mu_url_parse (url);
1045 if (status)
1046 return status;
1047
1048 if (!mu_url_is_scheme (url, scheme))
1049 return EINVAL;
1050
1051 if (url->port == 0)
1052 url->port = port;
1053
1054 return status;
1055 }
1056
1057 /* Default mailbox path generator */
1058 static char *
1059 _url_path_default (const char *spooldir, const char *user, int unused)
1060 {
1061 return mu_make_file_name (spooldir, user);
1062 }
1063
1064 /* Hashed indexing */
1065 static char *
1066 _url_path_hashed (const char *spooldir, const char *user, int param)
1067 {
1068 int i;
1069 int ulen = strlen (user);
1070 char *mbox;
1071 unsigned hash;
1072
1073 if (param > ulen)
1074 param = ulen;
1075 for (i = 0, hash = 0; i < param; i++)
1076 hash += user[i];
1077
1078 mbox = malloc (ulen + strlen (spooldir) + 5);
1079 sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user);
1080 return mbox;
1081 }
1082
1083 static int transtab[] = {
1084 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
1085 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
1086 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
1087 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f',
1088 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
1089 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
1090 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd',
1091 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
1092 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1093 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1094 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1095 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
1096 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1097 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1098 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1099 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
1100 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
1101 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
1102 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
1103 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1104 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1105 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1106 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e',
1107 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
1108 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
1109 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
1110 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
1111 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g',
1112 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
1113 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
1114 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
1115 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g'
1116 };
1117
1118 /* Forward Indexing */
1119 static char *
1120 _url_path_index (const char *spooldir, const char *iuser, int index_depth)
1121 {
1122 const unsigned char* user = (const unsigned char*) iuser;
1123 int i, ulen = strlen (iuser);
1124 char *mbox, *p;
1125
1126 if (ulen == 0)
1127 return NULL;
1128
1129 mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2);
1130 strcpy (mbox, spooldir);
1131 p = mbox + strlen (mbox);
1132 for (i = 0; i < index_depth && i < ulen; i++)
1133 {
1134 *p++ = '/';
1135 *p++ = transtab[ user[i] ];
1136 }
1137 for (; i < index_depth; i++)
1138 {
1139 *p++ = '/';
1140 *p++ = transtab[ user[ulen-1] ];
1141 }
1142 *p++ = '/';
1143 strcpy (p, iuser);
1144 return mbox;
1145 }
1146
1147 /* Reverse Indexing */
1148 static char *
1149 _url_path_rev_index (const char *spooldir, const char *iuser, int index_depth)
1150 {
1151 const unsigned char* user = (const unsigned char*) iuser;
1152 int i, ulen = strlen (iuser);
1153 char *mbox, *p;
1154
1155 if (ulen == 0)
1156 return NULL;
1157
1158 mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1);
1159 strcpy (mbox, spooldir);
1160 p = mbox + strlen (mbox);
1161 for (i = 0; i < index_depth && i < ulen; i++)
1162 {
1163 *p++ = '/';
1164 *p++ = transtab[ user[ulen - i - 1] ];
1165 }
1166 for (; i < index_depth; i++)
1167 {
1168 *p++ = '/';
1169 *p++ = transtab[ user[0] ];
1170 }
1171 *p++ = '/';
1172 strcpy (p, iuser);
1173 return mbox;
1174 }
1175
1176 static int
1177 rmselector (const char *p, void *data MU_ARG_UNUSED)
1178 {
1179 return strncmp (p, "type=", 5) == 0
1180 || strncmp (p, "user=", 5) == 0
1181 || strncmp (p, "param=", 6) == 0;
1182 }
1183
1184 int
1185 mu_url_expand_path (mu_url_t url)
1186 {
1187 size_t i;
1188 char *user = NULL;
1189 int param = 0;
1190 char *p;
1191 char *(*fun) (const char *, const char *, int) = _url_path_default;
1192
1193 if (url->fvcount == 0)
1194 return 0;
1195
1196 for (i = 0; i < url->fvcount; i++)
1197 {
1198 p = url->fvpairs[i];
1199 if (strncmp (p, "type=", 5) == 0)
1200 {
1201 char *type = p + 5;
1202
1203 if (strcmp (type, "hash") == 0)
1204 fun = _url_path_hashed;
1205 else if (strcmp (type, "index") == 0)
1206 fun = _url_path_index;
1207 else if (strcmp (type, "rev-index") == 0)
1208 fun = _url_path_rev_index;
1209 else
1210 return MU_ERR_NOENT;
1211 }
1212 else if (strncmp (p, "user=", 5) == 0)
1213 {
1214 user = p + 5;
1215 }
1216 else if (strncmp (p, "param=", 6) == 0)
1217 {
1218 param = strtoul (p + 6, NULL, 0);
1219 }
1220 }
1221
1222 if (user)
1223 {
1224 char *p = fun (url->path, user, param);
1225 if (p)
1226 {
1227 free (url->path);
1228 url->path = p;
1229 }
1230 mu_argcv_remove (&url->fvcount, &url->fvpairs, rmselector, NULL);
1231 }
1232 else
1233 return MU_ERR_NOENT;
1234
1235 return 0;
1236 }
1237
1238 int
1239 mu_url_get_flags (mu_url_t url, int *pf)
1240 {
1241 if (!url || !pf)
1242 return EINVAL;
1243 *pf = url->flags;
1244 return 0;
1245 }
1246
1247 int
1248 mu_url_has_flag (mu_url_t url, int flags)
1249 {
1250 if (!url)
1251 return 0;
1252 return url->flags & flags;
1253 }
1254
...@@ -180,7 +180,9 @@ file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, ...@@ -180,7 +180,9 @@ file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge,
180 180
181 if (!ft->tickurl) 181 if (!ft->tickurl)
182 { 182 {
183 int rc = mu_wicket_file_match_url (ft->filename, url, &ft->tickurl); 183 int rc = mu_wicket_file_match_url (ft->filename, url,
184 MU_URL_PARSE_ALL,
185 &ft->tickurl);
184 if (rc) 186 if (rc)
185 return rc; 187 return rc;
186 } 188 }
...@@ -245,7 +247,8 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data, ...@@ -245,7 +247,8 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data,
245 247
246 int 248 int
247 mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc, 249 mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc,
248 mu_url_t url, mu_url_t *pticket_url) 250 mu_url_t url, int parse_flags,
251 mu_url_t *pticket_url)
249 { 252 {
250 int rc; 253 int rc;
251 mu_url_t u = NULL; 254 mu_url_t u = NULL;
...@@ -270,20 +273,13 @@ mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc, ...@@ -270,20 +273,13 @@ mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc,
270 if (*p == 0 || *p == '#') 273 if (*p == 0 || *p == '#')
271 continue; 274 continue;
272 275
273 if ((err = mu_url_create (&u, p)) != 0) 276 if ((err = mu_url_create_hint (&u, p, parse_flags, NULL)) != 0)
274 { 277 {
275 /* Skip erroneous entry */ 278 /* Skip erroneous entry */
276 mu_error (_("%s:%u: cannot create URL: %s"), 279 mu_error (_("%s:%u: cannot create URL: %s"),
277 loc->file, loc->line, mu_strerror (err)); 280 loc->file, loc->line, mu_strerror (err));
278 continue; 281 continue;
279 } 282 }
280 if ((err = mu_url_parse (u)) != 0)
281 {
282 mu_error (_("%s:%u: cannot parse URL: %s"),
283 loc->file, loc->line, mu_strerror (err));
284 mu_url_destroy (&u);
285 continue;
286 }
287 283
288 if (!mu_url_has_flag (u, MU_URL_USER|MU_URL_SECRET)) 284 if (!mu_url_has_flag (u, MU_URL_USER|MU_URL_SECRET))
289 { 285 {
...@@ -326,6 +322,7 @@ mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc, ...@@ -326,6 +322,7 @@ mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc,
326 322
327 int 323 int
328 mu_wicket_file_match_url (const char *name, mu_url_t url, 324 mu_wicket_file_match_url (const char *name, mu_url_t url,
325 int parse_flags,
329 mu_url_t *pticket_url) 326 mu_url_t *pticket_url)
330 { 327 {
331 mu_stream_t stream; 328 mu_stream_t stream;
...@@ -337,7 +334,8 @@ mu_wicket_file_match_url (const char *name, mu_url_t url, ...@@ -337,7 +334,8 @@ mu_wicket_file_match_url (const char *name, mu_url_t url,
337 return rc; 334 return rc;
338 loc.file = name; 335 loc.file = name;
339 loc.line = 0; 336 loc.line = 0;
340 rc = mu_wicket_stream_match_url (stream, &loc, url, pticket_url); 337 rc = mu_wicket_stream_match_url (stream, &loc, url, parse_flags,
338 pticket_url);
341 mu_stream_close (stream); 339 mu_stream_close (stream);
342 mu_stream_destroy (&stream); 340 mu_stream_destroy (&stream);
343 return rc; 341 return rc;
......
...@@ -157,8 +157,6 @@ mu_folder_create (mu_folder_t *pfolder, const char *name) ...@@ -157,8 +157,6 @@ mu_folder_create (mu_folder_t *pfolder, const char *name)
157 rc = mu_url_create (&url, name); 157 rc = mu_url_create (&url, name);
158 if (rc) 158 if (rc)
159 return rc; 159 return rc;
160 rc = mu_url_parse (url);
161 if (rc == 0)
162 rc = mu_folder_create_from_record (pfolder, url, NULL); 160 rc = mu_folder_create_from_record (pfolder, url, NULL);
163 if (rc) 161 if (rc)
164 mu_url_destroy (&url); 162 mu_url_destroy (&url);
......
...@@ -185,8 +185,6 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name) ...@@ -185,8 +185,6 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name)
185 status = mu_url_create (&url, name); 185 status = mu_url_create (&url, name);
186 if (status) 186 if (status)
187 return status; 187 return status;
188 status = mu_url_parse (url);
189 if (status == 0)
190 status = _create_mailbox0 (pmbox, url, name); 188 status = _create_mailbox0 (pmbox, url, name);
191 if (status) 189 if (status)
192 mu_url_destroy (&url); 190 mu_url_destroy (&url);
...@@ -224,8 +222,6 @@ mu_mailbox_create_from_record (mu_mailbox_t *pmbox, mu_record_t record, ...@@ -224,8 +222,6 @@ mu_mailbox_create_from_record (mu_mailbox_t *pmbox, mu_record_t record,
224 rc = mu_url_create (&url, name); 222 rc = mu_url_create (&url, name);
225 if (rc) 223 if (rc)
226 return rc; 224 return rc;
227 rc = mu_url_parse (url);
228 if (rc == 0)
229 rc = _mailbox_create_from_record (pmbox, record, url, name); 225 rc = _mailbox_create_from_record (pmbox, record, url, name);
230 if (rc) 226 if (rc)
231 mu_url_destroy (&url); 227 mu_url_destroy (&url);
......
...@@ -168,8 +168,6 @@ mu_mailer_create (mu_mailer_t * pmailer, const char *name) ...@@ -168,8 +168,6 @@ mu_mailer_create (mu_mailer_t * pmailer, const char *name)
168 status = mu_url_create (&url, name); 168 status = mu_url_create (&url, name);
169 if (status) 169 if (status)
170 return status; 170 return status;
171 status = mu_url_parse (url);
172 if (status == 0)
173 status = mu_mailer_create_from_url (pmailer, url); 171 status = mu_mailer_create_from_url (pmailer, url);
174 if (status) 172 if (status)
175 mu_url_destroy (&url); 173 mu_url_destroy (&url);
......
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
29 #include <mailutils/message.h> 29 #include <mailutils/message.h>
30 #include <mailutils/header.h> 30 #include <mailutils/header.h>
31 #include <mailutils/stream.h> 31 #include <mailutils/stream.h>
32 #include <mailutils/url.h> /* FIXME: for mu_url_decode, which should
33 be renamed! */
34 #include <mailutils/mime.h> 32 #include <mailutils/mime.h>
35 #include <mailutils/filter.h> 33 #include <mailutils/filter.h>
36 #include <mailutils/util.h> 34 #include <mailutils/util.h>
...@@ -480,9 +478,9 @@ mu_mimehdr_decode_param (const char *value, int flags, ...@@ -480,9 +478,9 @@ mu_mimehdr_decode_param (const char *value, int flags,
480 } 478 }
481 else 479 else
482 { 480 {
483 decoded = mu_url_decode (value); 481 rc = mu_str_url_decode (&decoded, value);
484 if (!decoded) 482 if (rc)
485 return ENOMEM; 483 return rc;
486 484
487 if ((flags & MU_MIMEHDR_CSINFO) 485 if ((flags & MU_MIMEHDR_CSINFO)
488 && (lang = strchr (decoded, '\'')) 486 && (lang = strchr (decoded, '\''))
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
27 #include <stdlib.h> 27 #include <stdlib.h>
28 #include <string.h> 28 #include <string.h>
29 #include <unistd.h> 29 #include <unistd.h>
30 #include <limits.h>
30 31
31 #include <sys/socket.h> 32 #include <sys/socket.h>
32 #include <sys/types.h> 33 #include <sys/types.h>
...@@ -52,7 +53,7 @@ struct _tcp_instance ...@@ -52,7 +53,7 @@ struct _tcp_instance
52 struct _mu_stream stream; 53 struct _mu_stream stream;
53 int fd; 54 int fd;
54 char *host; 55 char *host;
55 int port; 56 unsigned short port;
56 int state; 57 int state;
57 unsigned long address; 58 unsigned long address;
58 unsigned long source_addr; 59 unsigned long source_addr;
...@@ -304,7 +305,7 @@ _create_tcp_stream (int flags) ...@@ -304,7 +305,7 @@ _create_tcp_stream (int flags)
304 305
305 int 306 int
306 mu_tcp_stream_create_with_source_ip (mu_stream_t *pstream, 307 mu_tcp_stream_create_with_source_ip (mu_stream_t *pstream,
307 const char *host, int port, 308 const char *host, unsigned port,
308 unsigned long source_ip, 309 unsigned long source_ip,
309 int flags) 310 int flags)
310 { 311 {
...@@ -315,7 +316,7 @@ mu_tcp_stream_create_with_source_ip (mu_stream_t *pstream, ...@@ -315,7 +316,7 @@ mu_tcp_stream_create_with_source_ip (mu_stream_t *pstream,
315 if (host == NULL) 316 if (host == NULL)
316 return MU_ERR_TCP_NO_HOST; 317 return MU_ERR_TCP_NO_HOST;
317 318
318 if (port < 1) 319 if (port > USHRT_MAX)
319 return MU_ERR_TCP_NO_PORT; 320 return MU_ERR_TCP_NO_PORT;
320 321
321 tcp = _create_tcp_stream (flags | MU_STREAM_RDWR); 322 tcp = _create_tcp_stream (flags | MU_STREAM_RDWR);
...@@ -341,7 +342,7 @@ mu_tcp_stream_create_with_source_ip (mu_stream_t *pstream, ...@@ -341,7 +342,7 @@ mu_tcp_stream_create_with_source_ip (mu_stream_t *pstream,
341 342
342 int 343 int
343 mu_tcp_stream_create_with_source_host (mu_stream_t *stream, 344 mu_tcp_stream_create_with_source_host (mu_stream_t *stream,
344 const char *host, int port, 345 const char *host, unsigned port,
345 const char *source_host, 346 const char *source_host,
346 int flags) 347 int flags)
347 { 348 {
...@@ -354,7 +355,7 @@ mu_tcp_stream_create_with_source_host (mu_stream_t *stream, ...@@ -354,7 +355,7 @@ mu_tcp_stream_create_with_source_host (mu_stream_t *stream,
354 } 355 }
355 356
356 int 357 int
357 mu_tcp_stream_create (mu_stream_t *stream, const char *host, int port, 358 mu_tcp_stream_create (mu_stream_t *stream, const char *host, unsigned port,
358 int flags) 359 int flags)
359 { 360 {
360 return mu_tcp_stream_create_with_source_ip (stream, host, port, 361 return mu_tcp_stream_create_with_source_ip (stream, host, port,
......
...@@ -34,6 +34,7 @@ libstring_la_SOURCES = \ ...@@ -34,6 +34,7 @@ libstring_la_SOURCES = \
34 asprintf.c\ 34 asprintf.c\
35 muctype.c\ 35 muctype.c\
36 vasnprintf.c\ 36 vasnprintf.c\
37 mkfilename.c 37 mkfilename.c\
38 xdecode.c
38 39
39 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils 40 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009,
3 2010 Free Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #if HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <string.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/util.h>
26
27 /* From RFC 1738, section 2.2 */
28 void
29 mu_str_url_decode_inline (char *s)
30 {
31 char *d;
32
33 d = strchr (s, '%');
34 if (!d)
35 return;
36
37 for (s = d; *s; )
38 {
39 if (*s != '%')
40 {
41 *d++ = *s++;
42 }
43 else
44 {
45 unsigned long ul = 0;
46
47 s++;
48
49 /* don't check return value, it's correctly coded, or it's not,
50 in which case we just skip the garbage, this is a decoder,
51 not an AI project */
52
53 mu_hexstr2ul (&ul, s, 2);
54
55 s += 2;
56
57 *d++ = (char) ul;
58 }
59 }
60
61 *d = 0;
62 }
63
64 int
65 mu_str_url_decode (char **ptr, const char *s)
66 {
67 char *d = strdup (s);
68 if (!d)
69 return ENOMEM;
70 mu_str_url_decode_inline (d);
71 *ptr = d;
72 return 0;
73 }
...@@ -77,7 +77,7 @@ int ...@@ -77,7 +77,7 @@ int
77 main () 77 main ()
78 { 78 {
79 char str[1024]; 79 char str[1024];
80 long port = 0; 80 unsigned port = 0;
81 mu_url_t u = NULL; 81 mu_url_t u = NULL;
82 82
83 while (fgets (str, sizeof (str), stdin) != NULL) 83 while (fgets (str, sizeof (str), stdin) != NULL)
...@@ -95,11 +95,6 @@ main () ...@@ -95,11 +95,6 @@ main ()
95 str, rc, mu_strerror (rc)); 95 str, rc, mu_strerror (rc));
96 exit (1); 96 exit (1);
97 } 97 }
98 if ((rc = mu_url_parse (u)) != 0)
99 {
100 fprintf (stderr, "%s\n", mu_errname (rc));
101 continue;
102 }
103 98
104 GET_AND_PRINT (scheme, u, buf, rc); 99 GET_AND_PRINT (scheme, u, buf, rc);
105 GET_AND_PRINT (user, u, buf, rc); 100 GET_AND_PRINT (user, u, buf, rc);
...@@ -127,7 +122,7 @@ main () ...@@ -127,7 +122,7 @@ main ()
127 mu_error ("cannot get %s: %s", "port", mu_strerror (rc)); 122 mu_error ("cannot get %s: %s", "port", mu_strerror (rc));
128 exit (1); 123 exit (1);
129 } 124 }
130 printf ("port %ld\n", port); 125 printf ("port %hu\n", port);
131 126
132 GET_AND_PRINT (path, u, buf, rc); 127 GET_AND_PRINT (path, u, buf, rc);
133 print_fvpairs (u); 128 print_fvpairs (u);
......
...@@ -38,15 +38,10 @@ match_string (const char *str) ...@@ -38,15 +38,10 @@ match_string (const char *str)
38 str, rc, mu_strerror (rc)); 38 str, rc, mu_strerror (rc));
39 return; 39 return;
40 } 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)); 41 MU_ASSERT (mu_stream_seek (stream, 0, MU_SEEK_SET, NULL));
47 loc.file = name; 42 loc.file = name;
48 loc.line = 0; 43 loc.line = 0;
49 rc = mu_wicket_stream_match_url (stream, &loc, u, &url); 44 rc = mu_wicket_stream_match_url (stream, &loc, u, MU_URL_PARSE_ALL, &url);
50 switch (rc) 45 switch (rc)
51 { 46 {
52 case 0: 47 case 0:
......
1 # GNU Mailutils -- a suite of utilities for electronic mail
2 # Copyright (C) 2010 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, see
16 # <http://www.gnu.org/licenses/>.
17
18 noinst_LTLIBRARIES = liburl.la
19
20 liburl_la_SOURCES = \
21 accessor.h\
22 copy.c\
23 create.c\
24 decode.c\
25 destroy.c\
26 dup.c\
27 expand.c\
28 flag.c\
29 get-auth.c\
30 get-host.c\
31 get-param.c\
32 get-path.c\
33 get-portstr.c\
34 get-query.c\
35 get-scheme.c\
36 get-secret.c\
37 get-user.c\
38 match.c\
39 port.c\
40 scheme.c\
41 uplevel.c\
42 urlstr.c
43
44 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
45
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/errno.h>
31 #include <mailutils/util.h>
32 #include <mailutils/cstr.h>
33 #include <mailutils/sys/url.h>
34
35 /* General accessors: */
36 #define AC2(a,b) a ## b
37 #define METHOD(pfx,part) AC2(pfx,part)
38 #define AC4(a,b,c,d) a ## b ## c ## d
39 #define ACCESSOR(action,field) AC4(mu_url_,action,_,field)
40
41 /* Define a `static get' accessor */
42 int
43 ACCESSOR(sget,URL_PART) (mu_url_t url, char const **sptr)
44 {
45 if (url == NULL)
46 return EINVAL;
47 if (!url->URL_PART)
48 {
49 if (url->METHOD(_get_,URL_PART))
50 {
51 size_t n;
52 char *buf;
53
54 int status = url->METHOD(_get_,URL_PART) (url, NULL, 0, &n);
55 if (status)
56 return status;
57
58 buf = malloc (n + 1);
59 if (!buf)
60 return ENOMEM;
61
62 status = url->METHOD(_get_,URL_PART) (url, buf, n + 1, NULL);
63 if (status)
64 return status;
65
66 if (buf[0])
67 {
68 /* FIXME */
69 status = mu_str_url_decode (&url->URL_PART, buf);
70 if (status)
71 {
72 free (buf);
73 return status;
74 }
75 }
76 else
77 url->URL_PART = buf;
78 if (!url->URL_PART)
79 return ENOMEM;
80 }
81 else
82 return MU_ERR_NOENT;
83 }
84 *sptr = url->URL_PART;
85 return 0;
86 }
87
88 /* Define a `get' accessor */
89 int
90 ACCESSOR(get,URL_PART) (mu_url_t url, char *buf, size_t len, size_t *n)
91 {
92 size_t i;
93 const char *str;
94 int status = ACCESSOR(sget, URL_PART) (url, &str);
95
96 if (status)
97 return status;
98
99 i = mu_cpystr (buf, str, len);
100 if (n)
101 *n = i;
102 return 0;
103 }
104
105 /* Define an `allocated get' accessor */
106 int
107 ACCESSOR(aget, URL_PART) (mu_url_t url, char **buf)
108 {
109 const char *str;
110 int status = ACCESSOR(sget, URL_PART) (url, &str);
111
112 if (status)
113 return status;
114
115 if (str)
116 {
117 *buf = strdup (str);
118 if (!*buf)
119 status = ENOMEM;
120 }
121 else
122 *buf = NULL;
123 return status;
124 }
125
126 /* Define a comparator */
127 int
128 ACCESSOR(is_same,URL_PART) (mu_url_t url1, mu_url_t url2)
129 {
130 const char *s1, *s2;
131 int status1, status2;
132
133 status1 = ACCESSOR(sget, URL_PART) (url1, &s1);
134 if (status1 && status1 != MU_ERR_NOENT)
135 return 0;
136 status2 = ACCESSOR(sget, URL_PART) (url2, &s2);
137 if (status2 && status2 != MU_ERR_NOENT)
138 return 0;
139
140 if (status1 || status2)
141 return status1 == status2; /* Both fields are missing */
142 return mu_c_strcasecmp (s1, s2) == 0;
143 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <string.h>
24 #ifdef HAVE_STRINGS_H
25 # include <strings.h>
26 #endif
27
28 #include <mailutils/types.h>
29 #include <mailutils/argcv.h>
30 #include <mailutils/secret.h>
31 #include <mailutils/util.h>
32 #include <mailutils/sys/url.h>
33
34 struct copy_tab
35 {
36 int mask;
37 int (*fun) (mu_url_t, mu_url_t, size_t);
38 size_t off;
39 };
40
41 static int
42 _url_copy_str (mu_url_t dest_url, mu_url_t src_url, size_t off)
43 {
44 char **dest = (char**) ((char*) dest_url + off);
45 char *src = *(char**) ((char*) src_url + off);
46 char *p = strdup (src);
47 if (!p)
48 return ENOMEM;
49 *dest = p;
50 return 0;
51 }
52
53 static int
54 _url_copy_secret (mu_url_t dest, mu_url_t src, size_t off)
55 {
56 return mu_secret_dup (src->secret, &dest->secret);
57 }
58
59 static int
60 _url_copy_port (mu_url_t dest, mu_url_t src, size_t off)
61 {
62 if (src->portstr)
63 {
64 dest->portstr = strdup (src->portstr);
65 if (!dest->portstr)
66 return ENOMEM;
67 }
68 dest->port = src->port;
69 return 0;
70 }
71
72 static char **
73 argcv_copy (size_t argc, char **argv)
74 {
75 size_t i;
76 char **nv = calloc (argc + 1, sizeof (nv[0]));
77 if (!nv)
78 return NULL;
79 for (i = 0; i < argc; i++)
80 if ((nv[i] = strdup (argv[i])) == NULL)
81 {
82 mu_argcv_free (i, nv);
83 free (nv);
84 return NULL;
85 }
86 return nv;
87 }
88
89 static int
90 _url_copy_param (mu_url_t dest, mu_url_t src, size_t off)
91 {
92 if ((dest->fvpairs = argcv_copy (src->fvcount, src->fvpairs)) == NULL)
93 return ENOMEM;
94 dest->fvcount = src->fvcount;
95 return 0;
96 }
97
98 static int
99 _url_copy_query (mu_url_t dest, mu_url_t src, size_t off)
100 {
101 if ((dest->qargv = argcv_copy (src->qargc, src->qargv)) == NULL)
102 return ENOMEM;
103 dest->qargc = src->qargc;
104 return 0;
105 }
106
107 static struct copy_tab copy_tab[] = {
108 { MU_URL_SCHEME, _url_copy_str, mu_offsetof (struct _mu_url, scheme) },
109 { MU_URL_USER, _url_copy_str, mu_offsetof (struct _mu_url, user) },
110 { MU_URL_SECRET, _url_copy_secret, 0 },
111 { MU_URL_AUTH, _url_copy_str, mu_offsetof (struct _mu_url, auth) },
112 { MU_URL_HOST, _url_copy_str, mu_offsetof (struct _mu_url, host) },
113 { MU_URL_PORT, _url_copy_port, 0 },
114 { MU_URL_PATH, _url_copy_str, mu_offsetof (struct _mu_url, path) },
115 { MU_URL_PARAM, _url_copy_param, 0 },
116 { MU_URL_QUERY, _url_copy_query, 0 }
117 };
118
119 int
120 mu_url_copy_hints (mu_url_t url, mu_url_t hint)
121 {
122 int i;
123
124 if (!url)
125 return EINVAL;
126 if (!hint)
127 return 0;
128 for (i = 0; i < MU_ARRAY_SIZE (copy_tab); i++)
129 {
130 if (!(url->flags & copy_tab[i].mask) &&
131 (hint->flags & copy_tab[i].mask))
132 {
133 int rc = copy_tab[i].fun (url, hint, copy_tab[i].off);
134 if (rc)
135 return rc;
136 url->flags |= copy_tab[i].mask;
137 }
138 }
139 return 0;
140 }
141
142
143
144
145
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <ctype.h>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #ifdef HAVE_STRINGS_H
27 # include <strings.h>
28 #endif
29 #include <netdb.h>
30 #include <arpa/inet.h>
31 #include <limits.h>
32
33 #include <mailutils/util.h>
34 #include <mailutils/errno.h>
35 #include <mailutils/argcv.h>
36 #include <mailutils/secret.h>
37 #include <mailutils/cstr.h>
38 #include <mailutils/sys/url.h>
39
40 struct mu_url_ctx
41 {
42 int flags;
43 const char *input;
44 const char *cur;
45 mu_url_t url;
46
47 size_t passoff;
48
49 char *tokbuf;
50 size_t toksize;
51 size_t toklen;
52 };
53
54 static int
55 getkn (struct mu_url_ctx *ctx, char *delim)
56 {
57 size_t n;
58
59 if (*ctx->cur == 0)
60 return -1;
61 n = strcspn (ctx->cur, delim);
62 if (n > ctx->toksize)
63 {
64 char *p = realloc (ctx->tokbuf, n + 1);
65 if (!p)
66 return ENOENT;
67 ctx->toksize = n + 1;
68 ctx->tokbuf = p;
69 }
70 memcpy (ctx->tokbuf, ctx->cur, n);
71 ctx->tokbuf[n] = 0;
72 ctx->toklen = n;
73 ctx->cur += n;
74 return 0;
75 }
76
77 #define INIT_ARRAY_SIZE 16
78
79 static int
80 expand_array (size_t *pwc, char ***pwv, int incr)
81 {
82 size_t wc = *pwc;
83 char **wv = *pwv;
84
85 if (!wv)
86 {
87 wv = calloc (INIT_ARRAY_SIZE, sizeof (wv[0]));
88 wc = INIT_ARRAY_SIZE;
89 }
90 else
91 {
92 if (incr)
93 wc += incr;
94 else
95 {
96 size_t newsize = wc * 2;
97 if (newsize < wc)
98 return ENOMEM;
99 wc = newsize;
100 }
101 wv = realloc (wv, sizeof (wv[0]) * wc);
102 }
103 if (!wv)
104 return ENOMEM;
105 *pwv = wv;
106 *pwc = wc;
107 return 0;
108 }
109
110 static int
111 parse_param (struct mu_url_ctx *ctx, char *delim, int *pargc, char ***pargv)
112 {
113 int rc;
114 size_t wc = 0, wn = 0;
115 char **wv = NULL;
116
117 while ((rc = getkn (ctx, delim)) == 0)
118 {
119 if (wn == wc)
120 {
121 rc = expand_array (&wc, &wv, 0);
122 if (rc)
123 break;
124 }
125 wv[wn] = strdup (ctx->tokbuf);
126 if (!wv[wn])
127 {
128 rc = ENOMEM;
129 break;
130 }
131 wn++;
132 if (*ctx->cur != delim[0])
133 break;
134 ctx->cur++;
135 }
136
137 if (rc == 0)
138 {
139 if (wn == wc)
140 {
141 rc = expand_array (&wc, &wv, 1);
142 if (rc)
143 {
144 mu_argcv_free (wc, wv);
145 return ENOMEM;
146 }
147 wv[wn] = NULL;
148 }
149
150 *pargv = realloc (wv, sizeof (wv[0]) * (wn + 1));
151 *pargc = wn;
152 }
153 else
154 mu_argcv_free (wc, wv);
155
156 return rc;
157 }
158
159 static int
160 _mu_url_ctx_parse_query (struct mu_url_ctx *ctx)
161 {
162 int rc;
163
164 ctx->cur++;
165 rc = parse_param (ctx, "&", &ctx->url->qargc, &ctx->url->qargv);
166 if (rc == 0 && ctx->url->qargc)
167 ctx->url->flags |= MU_URL_QUERY;
168 return rc;
169 }
170
171 static int
172 _mu_url_ctx_parse_param (struct mu_url_ctx *ctx)
173 {
174 int rc;
175
176 ctx->cur++;
177 rc = parse_param (ctx, ";?", &ctx->url->fvcount, &ctx->url->fvpairs);
178 if (rc)
179 return rc;
180 if (ctx->url->fvcount)
181 ctx->url->flags |= MU_URL_PARAM;
182 if (*ctx->cur == '?')
183 return _mu_url_ctx_parse_query (ctx);
184 return 0;
185 }
186
187 static int
188 str_assign (char **ptr, const char *str)
189 {
190 *ptr = strdup (str);
191 if (!*ptr)
192 return ENOMEM;
193 return 0;
194 }
195
196 static int
197 _mu_url_ctx_parse_path (struct mu_url_ctx *ctx)
198 {
199 int rc;
200 mu_url_t url = ctx->url;
201
202 rc = getkn (ctx, ";?");
203 if (rc)
204 return rc;
205 rc = str_assign (&url->path, ctx->tokbuf);
206 if (rc == 0)
207 url->flags |= MU_URL_PATH;
208 if (*ctx->cur == ';')
209 return _mu_url_ctx_parse_param (ctx);
210 if (*ctx->cur == '?')
211 return _mu_url_ctx_parse_query (ctx);
212 return 0;
213 }
214
215 static int
216 _mu_url_ctx_parse_host (struct mu_url_ctx *ctx, int has_host)
217 {
218 int rc;
219 mu_url_t url = ctx->url;
220
221 rc = getkn (ctx, ":/;?");
222 if (rc)
223 return rc;
224
225 if (ctx->toklen)
226 {
227 rc = str_assign (&url->host, ctx->tokbuf);
228 if (rc)
229 return rc;
230 url->flags |= MU_URL_HOST;
231 has_host = 1;
232 }
233
234 if (*ctx->cur == ':')
235 {
236 ctx->cur++;
237 has_host = 1;
238
239 rc = getkn (ctx, "/;?");
240 if (rc)
241 return rc;
242
243 rc = str_assign (&url->portstr, ctx->tokbuf);
244 if (rc)
245 return rc;
246 url->flags |= MU_URL_PORT;
247 }
248
249 if (*ctx->cur == '/')
250 {
251 if (has_host)
252 ctx->cur++;
253 return _mu_url_ctx_parse_path (ctx);
254 }
255
256 if (*ctx->cur == ';')
257 return _mu_url_ctx_parse_param (ctx);
258
259 if (*ctx->cur == '?')
260 return _mu_url_ctx_parse_query (ctx);
261 return 0;
262 }
263
264 static int
265 _mu_url_ctx_parse_cred (struct mu_url_ctx *ctx)
266 {
267 int rc, has_cred;
268 mu_url_t url = ctx->url;
269 const char *save = ctx->cur;
270
271 rc = getkn (ctx, "@");
272 if (rc)
273 return rc;
274 has_cred = *ctx->cur == '@';
275 /* restore the pointer */
276 ctx->cur = save;
277 if (has_cred)
278 {
279 /* Try to split the user into a:
280 <user>:<password>
281 or
282 <user>:<password>;AUTH=<auth>
283 */
284 rc = getkn (ctx, ":;@");
285 if (rc)
286 return rc;
287
288 if (ctx->toklen)
289 {
290 rc = str_assign (&url->user, ctx->tokbuf);
291 if (rc)
292 return rc;
293 url->flags |= MU_URL_USER;
294 }
295
296 if (*ctx->cur == ':')
297 {
298 ctx->cur++;
299 ctx->passoff = ctx->cur - ctx->input;
300
301 rc = getkn (ctx, ";@");
302 if (rc)
303 return rc;
304
305 if (ctx->toklen)
306 {
307 if (mu_secret_create (&url->secret, ctx->tokbuf, ctx->toklen))
308 return ENOMEM;
309 else
310 /* Clear password */
311 memset (ctx->tokbuf, 0, ctx->toklen);
312 url->flags |= MU_URL_SECRET;
313 }
314 }
315 if (*ctx->cur == ';')
316 {
317 ctx->cur++;
318
319 rc = getkn (ctx, "@");
320 if (rc)
321 return rc;
322
323 /* Make sure it's the auth token. */
324 if (mu_c_strncasecmp (ctx->tokbuf, "auth=", 5) == 0)
325 {
326 rc = str_assign (&url->auth, ctx->tokbuf + 5);
327 if (rc)
328 return rc;
329 url->flags |= MU_URL_AUTH;
330 }
331 }
332
333 /* Skip @ sign */
334 ctx->cur++;
335 }
336 return _mu_url_ctx_parse_host (ctx, has_cred);
337 }
338
339 int
340 _mu_url_ctx_parse (struct mu_url_ctx *ctx)
341 {
342 int rc;
343 mu_url_t url = ctx->url;
344
345 /* Parse the scheme part */
346 rc = getkn (ctx, ":/");
347 if (rc)
348 return rc;
349 if (*ctx->cur == ':')
350 {
351 rc = str_assign (&url->scheme, ctx->tokbuf);
352 if (rc)
353 return rc;
354 url->flags |= MU_URL_SCHEME;
355 ctx->cur++;
356 }
357
358 if (*ctx->cur == 0)
359 return 0;
360
361 if (ctx->cur[0] == '/' && ctx->cur[1] == '/')
362 {
363 ctx->cur += 2;
364 return _mu_url_ctx_parse_cred (ctx);
365 }
366
367 return _mu_url_ctx_parse_path (ctx);
368 }
369
370 static int
371 _mu_url_create_internal (struct mu_url_ctx *ctx, mu_url_t hint)
372 {
373 int rc;
374 mu_url_t url = ctx->url;
375
376 if ((ctx->flags & MU_URL_PARSE_PIPE) && ctx->input[0] == '|')
377 {
378 rc = str_assign (&url->scheme, "prog");
379 if (rc)
380 return rc;
381 url->flags |= MU_URL_SCHEME;
382 ctx->flags &= ~MU_URL_PARSE_HEXCODE;
383 rc = mu_argcv_get (ctx->input + 1, NULL, NULL, &url->qargc, &url->qargv);
384 if (rc == 0)
385 {
386 url->flags |= MU_URL_QUERY;
387 rc = str_assign (&url->path, url->qargv[0]);
388 if (rc == 0)
389 url->flags |= MU_URL_PATH;
390 }
391 }
392 else if ((ctx->flags & MU_URL_PARSE_SLASH) && ctx->input[0] == '/')
393 {
394 rc = str_assign (&url->scheme, "file");
395 if (rc)
396 return rc;
397 url->flags |= MU_URL_SCHEME;
398 ctx->flags &= ~MU_URL_PARSE_HEXCODE;
399 rc = str_assign (&url->path, ctx->input);
400 if (rc == 0)
401 url->flags |= MU_URL_PATH;
402 }
403 else
404 rc = _mu_url_ctx_parse (ctx);
405
406 if (rc)
407 return rc;
408
409 if (hint)
410 {
411 /* Fill in missing values */
412 rc = mu_url_copy_hints (url, hint);
413 if (rc)
414 return rc;
415 }
416
417 if (!(url->flags & MU_URL_SCHEME))
418 return MU_ERR_URL_MISS_PARTS;
419
420 /* RFC 1738, section 2.1, lower the scheme case */
421 mu_strlower (url->scheme);
422
423 if ((url->flags & MU_URL_PORT) && url->port == 0)
424 {
425 /* Convert port string to number */
426 unsigned long n;
427 char *p;
428
429 n = strtoul (url->portstr, &p, 10);
430 if (*p)
431 {
432 if (ctx->flags & MU_URL_PARSE_PORTSRV)
433 {
434 /* FIXME: Another proto? */
435 struct servent *sp = getservbyname (url->portstr, "tcp");
436 if (!sp)
437 return MU_ERR_TCP_NO_PORT; //FIXME: Error code?
438 url->port = ntohs (sp->s_port);
439 }
440 else
441 return MU_ERR_TCP_NO_PORT;
442 }
443 else if (n > USHRT_MAX)
444 return ERANGE;
445 else
446 url->port = n;
447 }
448
449 if (ctx->flags & MU_URL_PARSE_HEXCODE)
450 {
451 /* Decode the %XX notations */
452 rc = mu_url_decode (url);
453 if (rc)
454 return rc;
455 }
456
457 if ((url->flags & MU_URL_SECRET) &&
458 (ctx->flags & MU_URL_PARSE_HIDEPASS))
459 {
460 /* Obfuscate the password */
461 #define PASS_REPL "***"
462 #define PASS_REPL_LEN (sizeof (PASS_REPL) - 1)
463 size_t plen = mu_secret_length (url->secret);
464 size_t nlen = strlen (url->name);
465 size_t len = nlen - plen + PASS_REPL_LEN + 1;
466 char *newname;
467
468 memset (url->name + ctx->passoff, 0, plen);
469 if (len > nlen + 1)
470 {
471 newname = realloc (url->name, len);
472 if (!newname)
473 return rc;
474 url->name = newname;
475 }
476 else
477 newname = url->name;
478 memmove (newname + ctx->passoff + PASS_REPL_LEN,
479 newname + ctx->passoff + plen,
480 nlen - (ctx->passoff + plen) + 1);
481 memcpy (newname + ctx->passoff, PASS_REPL, PASS_REPL_LEN);
482 }
483
484 return 0;
485 }
486
487 int
488 mu_url_create_hint (mu_url_t *purl, const char *str, int flags,
489 mu_url_t hint)
490 {
491 int rc;
492 struct mu_url_ctx ctx;
493 mu_url_t url = calloc (1, sizeof (*url));
494 if (url == NULL)
495 return ENOMEM;
496 url->name = strdup (str);
497 if (!url->name)
498 {
499 free (url);
500 return ENOMEM;
501 }
502 memset (&ctx, 0, sizeof (ctx));
503 ctx.flags = flags;
504 ctx.input = str;
505 ctx.cur = ctx.input;
506 ctx.url = url;
507 rc = _mu_url_create_internal (&ctx, hint);
508 free (ctx.tokbuf);
509 if (rc)
510 mu_url_destroy (&url);
511 else
512 *purl = url;
513 return rc;
514 }
515
516 int
517 mu_url_create (mu_url_t *purl, const char *str)
518 {
519 return mu_url_create_hint (purl, str,
520 MU_URL_PARSE_HEXCODE |
521 MU_URL_PARSE_HIDEPASS |
522 MU_URL_PARSE_PORTSRV |
523 MU_URL_PARSE_PIPE |
524 MU_URL_PARSE_SLASH, NULL);
525 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/util.h>
31 #include <mailutils/secret.h>
32 #include <mailutils/sys/url.h>
33
34 struct decode_tab
35 {
36 int mask;
37 int (*fun) (mu_url_t, size_t);
38 size_t off;
39 };
40
41 static int
42 _url_dec_str (mu_url_t url, size_t off)
43 {
44 char **pptr = (char**) ((char*) url + off);
45 mu_str_url_decode_inline (*pptr);
46 return 0;
47 }
48
49 static int
50 _url_dec_param (mu_url_t url, size_t off)
51 {
52 int i;
53
54 for (i = 0; i < url->fvcount; i++)
55 mu_str_url_decode_inline (url->fvpairs[i]);
56 return 0;
57 }
58
59 static int
60 _url_dec_query (mu_url_t url, size_t off)
61 {
62 int i;
63
64 for (i = 0; i < url->qargc; i++)
65 mu_str_url_decode_inline (url->qargv[i]);
66 return 0;
67 }
68
69 static int
70 _url_dec_secret (mu_url_t url, size_t off)
71 {
72 char *pass;
73 mu_secret_t newsec;
74 int rc;
75
76 rc = mu_str_url_decode (&pass, mu_secret_password (url->secret));
77 if (rc)
78 return rc;
79 rc = mu_secret_create (&newsec, pass, strlen (pass));
80 memset (pass, 0, strlen (pass));
81 free (pass);
82 if (rc)
83 return rc;
84 mu_secret_destroy (&url->secret);
85 url->secret = newsec;
86 return 0;
87 }
88
89 static struct decode_tab decode_tab[] = {
90 { MU_URL_SCHEME, _url_dec_str, mu_offsetof (struct _mu_url, scheme) },
91 { MU_URL_USER, _url_dec_str, mu_offsetof (struct _mu_url, user) },
92 { MU_URL_SECRET, _url_dec_secret },
93 { MU_URL_AUTH, _url_dec_str, mu_offsetof (struct _mu_url, auth) },
94 { MU_URL_HOST, _url_dec_str, mu_offsetof (struct _mu_url, host) },
95 { MU_URL_PATH, _url_dec_str, mu_offsetof (struct _mu_url, path) },
96 { MU_URL_PARAM, _url_dec_param, 0 },
97 { MU_URL_QUERY, _url_dec_query, 0 }
98 };
99
100 int
101 mu_url_decode (mu_url_t url)
102 {
103 int i;
104
105 if (!url)
106 return EINVAL;
107 for (i = 0; i < MU_ARRAY_SIZE (decode_tab); i++)
108 {
109 if (url->flags & decode_tab[i].mask)
110 {
111 int rc = decode_tab[i].fun (url, decode_tab[i].off);
112 if (rc)
113 return rc;
114 }
115 }
116 return 0;
117 }
118
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/argcv.h>
31 #include <mailutils/secret.h>
32 #include <mailutils/errno.h>
33 #include <mailutils/sys/url.h>
34
35 void
36 mu_url_destroy (mu_url_t * purl)
37 {
38 if (purl && *purl)
39 {
40 mu_url_t url = (*purl);
41
42 if (url->_destroy)
43 url->_destroy (url);
44
45 if (url->name)
46 free (url->name);
47
48 if (url->scheme)
49 free (url->scheme);
50
51 if (url->user)
52 free (url->user);
53
54 mu_secret_destroy (&url->secret);
55
56 if (url->auth)
57 free (url->auth);
58
59 if (url->host)
60 free (url->host);
61
62 if (url->path)
63 free (url->path);
64
65 if (url->fvcount)
66 mu_argcv_free (url->fvcount, url->fvpairs);
67
68 mu_argcv_free (url->qargc, url->qargv);
69
70 free (url);
71
72 *purl = NULL;
73 }
74 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/util.h>
31 #include <mailutils/sys/url.h>
32
33 int
34 mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
35 {
36 int rc;
37 mu_url_t url = calloc (1, sizeof (*url));
38
39 if (!url)
40 return ENOMEM;
41 url->name = strdup (old_url->name);
42 if (!url->name)
43 {
44 free (url);
45 return ENOMEM;
46 }
47
48 rc = mu_url_copy_hints (url, old_url);
49 if (rc)
50 {
51 mu_url_destroy (&url);
52 return rc;
53 }
54 *new_url = url;
55 return 0;
56 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #ifdef HAVE_STRINGS_H
27 # include <strings.h>
28 #endif
29
30 #include <mailutils/types.h>
31 #include <mailutils/util.h>
32 #include <mailutils/errno.h>
33 #include <mailutils/argcv.h>
34 #include <mailutils/sys/url.h>
35
36 /* Default mailbox path generator */
37 static char *
38 _url_path_default (const char *spooldir, const char *user, int unused)
39 {
40 return mu_make_file_name (spooldir, user);
41 }
42
43 /* Hashed indexing */
44 static char *
45 _url_path_hashed (const char *spooldir, const char *user, int param)
46 {
47 int i;
48 int ulen = strlen (user);
49 char *mbox;
50 unsigned hash;
51
52 if (param > ulen)
53 param = ulen;
54 for (i = 0, hash = 0; i < param; i++)
55 hash += user[i];
56
57 mbox = malloc (ulen + strlen (spooldir) + 5);
58 sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user);
59 return mbox;
60 }
61
62 static int transtab[] = {
63 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
64 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
65 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
66 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f',
67 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
68 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
69 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd',
70 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
71 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
72 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
73 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
74 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
75 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
76 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
77 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
78 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
79 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
80 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
81 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
82 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
83 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
84 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
85 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e',
86 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
87 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
88 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
89 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
90 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g',
91 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
92 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
93 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
94 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g'
95 };
96
97 /* Forward Indexing */
98 static char *
99 _url_path_index (const char *spooldir, const char *iuser, int index_depth)
100 {
101 const unsigned char* user = (const unsigned char*) iuser;
102 int i, ulen = strlen (iuser);
103 char *mbox, *p;
104
105 if (ulen == 0)
106 return NULL;
107
108 mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2);
109 strcpy (mbox, spooldir);
110 p = mbox + strlen (mbox);
111 for (i = 0; i < index_depth && i < ulen; i++)
112 {
113 *p++ = '/';
114 *p++ = transtab[ user[i] ];
115 }
116 for (; i < index_depth; i++)
117 {
118 *p++ = '/';
119 *p++ = transtab[ user[ulen-1] ];
120 }
121 *p++ = '/';
122 strcpy (p, iuser);
123 return mbox;
124 }
125
126 /* Reverse Indexing */
127 static char *
128 _url_path_rev_index (const char *spooldir, const char *iuser, int index_depth)
129 {
130 const unsigned char* user = (const unsigned char*) iuser;
131 int i, ulen = strlen (iuser);
132 char *mbox, *p;
133
134 if (ulen == 0)
135 return NULL;
136
137 mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1);
138 strcpy (mbox, spooldir);
139 p = mbox + strlen (mbox);
140 for (i = 0; i < index_depth && i < ulen; i++)
141 {
142 *p++ = '/';
143 *p++ = transtab[ user[ulen - i - 1] ];
144 }
145 for (; i < index_depth; i++)
146 {
147 *p++ = '/';
148 *p++ = transtab[ user[0] ];
149 }
150 *p++ = '/';
151 strcpy (p, iuser);
152 return mbox;
153 }
154
155 static int
156 rmselector (const char *p, void *data MU_ARG_UNUSED)
157 {
158 return strncmp (p, "type=", 5) == 0
159 || strncmp (p, "user=", 5) == 0
160 || strncmp (p, "param=", 6) == 0;
161 }
162
163 int
164 mu_url_expand_path (mu_url_t url)
165 {
166 size_t i;
167 char *user = NULL;
168 int param = 0;
169 char *p;
170 char *(*fun) (const char *, const char *, int) = _url_path_default;
171
172 if (url->fvcount == 0)
173 return 0;
174
175 for (i = 0; i < url->fvcount; i++)
176 {
177 p = url->fvpairs[i];
178 if (strncmp (p, "type=", 5) == 0)
179 {
180 char *type = p + 5;
181
182 if (strcmp (type, "hash") == 0)
183 fun = _url_path_hashed;
184 else if (strcmp (type, "index") == 0)
185 fun = _url_path_index;
186 else if (strcmp (type, "rev-index") == 0)
187 fun = _url_path_rev_index;
188 else
189 return MU_ERR_NOENT;
190 }
191 else if (strncmp (p, "user=", 5) == 0)
192 {
193 user = p + 5;
194 }
195 else if (strncmp (p, "param=", 6) == 0)
196 {
197 param = strtoul (p + 6, NULL, 0);
198 }
199 }
200
201 if (user)
202 {
203 char *p = fun (url->path, user, param);
204 if (p)
205 {
206 free (url->path);
207 url->path = p;
208 }
209 mu_argcv_remove (&url->fvcount, &url->fvpairs, rmselector, NULL);
210 }
211 else
212 return MU_ERR_NOENT;
213
214 return 0;
215 }
216
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <mailutils/sys/url.h>
24
25 int
26 mu_url_get_flags (mu_url_t url, int *pf)
27 {
28 if (!url || !pf)
29 return EINVAL;
30 *pf = url->flags;
31 return 0;
32 }
33
34 int
35 mu_url_has_flag (mu_url_t url, int flags)
36 {
37 if (!url)
38 return 0;
39 return url->flags & flags;
40 }
1 #define URL_PART auth
2 #include "accessor.h"
3
1 #define URL_PART host
2 #include "accessor.h"
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/errno.h>
31 #include <mailutils/argcv.h>
32 #include <mailutils/sys/url.h>
33
34 /* field-value pairs accessors */
35 int
36 mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp)
37 {
38 if (url == NULL)
39 return EINVAL;
40 /* FIXME: no _get_fvpairs method, but the method stuff needs to be rewritten
41 anyway */
42 *fvc = url->fvcount;
43 *fvp = url->fvpairs;
44 return 0;
45 }
46
47 int
48 mu_url_sget_param (const mu_url_t url, const char *param, const char **val)
49 {
50 size_t fvc;
51 char **fvp;
52 int status = mu_url_sget_fvpairs (url, &fvc, &fvp);
53
54 if (status)
55 return status;
56
57 if (fvc)
58 {
59 size_t i;
60
61 for (i = 0; i < fvc; i++)
62 {
63 const char *p;
64 char *q;
65
66 for (p = param, q = fvp[i]; *p && *q && *p == *q; p++, q++)
67 ;
68 if (*p == 0)
69 {
70 if (*q == 0)
71 {
72 if (val)
73 *val = q;
74 return 0;
75 }
76 else if (*q == '=')
77 {
78 if (val)
79 *val = q + 1;
80 return 0;
81 }
82 }
83 }
84 }
85
86 return MU_ERR_NOENT;
87 }
88
89 int
90 mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp)
91 {
92 size_t fvc, i;
93 char **fvp;
94 char **fvcopy;
95
96 int rc = mu_url_sget_fvpairs (url, &fvc, &fvp);
97 if (rc)
98 return rc;
99
100 fvcopy = calloc (fvc + 1, sizeof (fvcopy[0]));
101 if (!fvcopy)
102 return errno;
103 for (i = 0; i < fvc; i++)
104 {
105 if (!(fvcopy[i] = strdup (fvp[i])))
106 {
107 mu_argcv_free (i, fvcopy);
108 return errno;
109 }
110 }
111 fvcopy[i] = NULL;
112 *pfvc = fvc;
113 *pfvp = fvcopy;
114 return 0;
115 }
116
117 int
118 mu_url_aget_param (const mu_url_t url, const char *param, char **val)
119 {
120 const char *s;
121 int status = mu_url_sget_param (url, param, &s);
122
123 if (status == 0)
124 {
125 *val = strdup (s);
126 if (!*val)
127 status = ENOMEM;
128 }
129 return status;
130 }
131
1 #define URL_PART path
2 #include "accessor.h"
1 #define URL_PART portstr
2 #include "accessor.h"
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/errno.h>
31 #include <mailutils/argcv.h>
32 #include <mailutils/sys/url.h>
33
34 int
35 mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
36 {
37 if (url == NULL)
38 return EINVAL;
39 /* See FIXME below */
40 *qc = url->qargc;
41 *qv = url->qargv;
42 return 0;
43 }
44
45 int
46 mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv)
47 {
48 size_t qargc, i;
49 char **qargv;
50 char **qcopy;
51
52 int rc = mu_url_sget_fvpairs (url, &qargc, &qargv);
53 if (rc)
54 return rc;
55
56 qcopy = calloc (qargc + 1, sizeof (qcopy[0]));
57 if (!qcopy)
58 return errno;
59 for (i = 0; i < qargc; i++)
60 {
61 if (!(qcopy[i] = strdup (qargv[i])))
62 {
63 mu_argcv_free (i, qcopy);
64 return errno;
65 }
66 }
67 qcopy[i] = NULL;
68 *qc = qargc;
69 *qv = qcopy;
70 return 0;
71 }
72
1 #define URL_PART scheme
2 #include "accessor.h"
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/errno.h>
31 #include <mailutils/secret.h>
32 #include <mailutils/sys/url.h>
33
34 int
35 mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret)
36 {
37 if (url->_get_secret)
38 return url->_get_secret (url, psecret);
39 if (url->secret == NULL)
40 return MU_ERR_NOENT;
41 mu_secret_ref (url->secret);
42 *psecret = url->secret;
43 return 0;
44 }
1 #define URL_PART user
2 #include "accessor.h"
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/cstr.h>
31 #include <mailutils/sys/url.h>
32
33 #define is_wildcard(s) ((s)[0] == '*' && s[1] == 0)
34
35 #define WEIGHT_SCHEME 3
36 #define WEIGHT_USER 4
37 #define WEIGHT_HOST 2
38 #define WEIGHT_PORT 1
39
40 int
41 mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *pwc)
42 {
43 int wcnt = 0;
44
45 if (is_wildcard (ticket->scheme))
46 wcnt += WEIGHT_SCHEME;
47 else if (mu_c_strcasecmp (ticket->scheme, url->scheme))
48 return 0;
49
50 if (ticket->flags & MU_URL_HOST)
51 {
52 if (is_wildcard (ticket->host))
53 wcnt += WEIGHT_HOST;
54 else if (url->flags & MU_URL_HOST)
55 {
56 if (mu_c_strcasecmp (ticket->host, url->host))
57 /* FIXME: Compare IP addresses */
58 return 0;
59 }
60 else
61 return 0;
62 }
63 else
64 wcnt += WEIGHT_HOST;
65
66 if (ticket->flags & MU_URL_PORT)
67 {
68 if (is_wildcard (ticket->portstr))
69 wcnt += WEIGHT_PORT;
70 else if (url->port & MU_URL_PORT)
71 {
72 if (ticket->port != url->port)
73 return 0;
74 else
75 wcnt += WEIGHT_PORT;
76 }
77 }
78 else
79 wcnt += WEIGHT_PORT;
80
81 if (ticket->flags & MU_URL_USER)
82 {
83 if (is_wildcard (ticket->user))
84 wcnt += WEIGHT_USER;
85
86 /* If ticket has a user or pass, but url doesn't, that's OK, we were
87 looking for this info. But if url does have a user/pass, it
88 must match the ticket. */
89 else if (url->flags & MU_URL_USER)
90 {
91 if (strcmp (ticket->user, url->user))
92 return 0;
93 }
94 }
95 else
96 wcnt += WEIGHT_USER;
97
98 /* Guess it matches. */
99 if (pwc)
100 *pwc = wcnt;
101 return 1;
102 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/cstr.h>
31 #include <mailutils/sys/url.h>
32
33 int
34 mu_url_get_port (const mu_url_t url, unsigned *pport)
35 {
36 if (url == NULL)
37 return EINVAL;
38 if (url->_get_port)
39 return url->_get_port (url, pport);
40 *pport = url->port;
41 return 0;
42 }
43
44 int
45 mu_url_is_same_port (mu_url_t url1, mu_url_t url2)
46 {
47 unsigned p1 = 0, p2 = 0;
48
49 mu_url_get_port (url1, &p1);
50 mu_url_get_port (url2, &p2);
51 return (p1 == p2);
52 }
53
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/cstr.h>
31 #include <mailutils/sys/url.h>
32
33 int
34 mu_url_set_scheme (mu_url_t url, const char *scheme)
35 {
36 char *p;
37 if (!url || !scheme)
38 return EINVAL;
39 p = realloc (url->scheme, strlen (scheme) + 1);
40 if (!p)
41 return ENOMEM;
42 strcpy (url->scheme, scheme);
43 return 0;
44 }
45
46 int
47 mu_url_is_scheme (mu_url_t url, const char *scheme)
48 {
49 if (url && scheme && url->scheme
50 && mu_c_strcasecmp (url->scheme, scheme) == 0)
51 return 1;
52
53 return 0;
54 }
55
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif
28
29 #include <mailutils/types.h>
30 #include <mailutils/errno.h>
31 #include <mailutils/sys/url.h>
32
33 int
34 mu_url_uplevel (mu_url_t url, mu_url_t *upurl)
35 {
36 int rc;
37 char *p;
38 mu_url_t new_url;
39
40 if (url->_uplevel)
41 return url->_uplevel (url, upurl);
42
43 if (!url->path)
44 return MU_ERR_NOENT;
45 p = strrchr (url->path, '/');
46
47 rc = mu_url_dup (url, &new_url);
48 if (rc == 0)
49 {
50 if (!p || p == url->path)
51 {
52 free (new_url->path);
53 new_url->path = NULL;
54 }
55 else
56 {
57 size_t size = p - url->path;
58 new_url->path = realloc (new_url->path, size + 1);
59 if (!new_url->path)
60 {
61 mu_url_destroy (&new_url);
62 return ENOMEM;
63 }
64 memcpy (new_url->path, url->path, size);
65 new_url->path[size] = 0;
66 }
67 *upurl = new_url;
68 }
69 return rc;
70 }
71
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010 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, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <stdlib.h>
22 #include <mailutils/types.h>
23 #include <mailutils/sys/url.h>
24
25 const char *
26 mu_url_to_string (const mu_url_t url)
27 {
28 if (url == NULL || url->name == NULL)
29 return "";
30 return url->name;
31 }
...@@ -54,19 +54,17 @@ Url :: ~Url () ...@@ -54,19 +54,17 @@ Url :: ~Url ()
54 void 54 void
55 Url :: parse () 55 Url :: parse ()
56 { 56 {
57 int status = mu_url_parse (url); 57 /* FIXME: Remove */
58 if (status)
59 throw Exception ("Url::parse", status);
60 } 58 }
61 59
62 long 60 unsigned
63 Url :: get_port () 61 Url :: get_port ()
64 { 62 {
65 long port; 63 unsigned port;
66 int status = mu_url_get_port (url, &port); 64 int status = mu_url_get_port (url, &port);
67 if (status) 65 if (status)
68 throw Exception ("Url::get_port", status); 66 throw Exception ("Url::get_port", status);
69 return port; 67 return (unsigned short) port;
70 } 68 }
71 69
72 std::string 70 std::string
......
...@@ -67,7 +67,7 @@ static struct _mu_record _imap_record = ...@@ -67,7 +67,7 @@ static struct _mu_record _imap_record =
67 MU_IMAP_PRIO, 67 MU_IMAP_PRIO,
68 MU_IMAP_SCHEME, 68 MU_IMAP_SCHEME,
69 MU_RECORD_DEFAULT, 69 MU_RECORD_DEFAULT,
70 MU_URL_CRED | MU_URL_INET | MU_URL_PATH, 70 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET | MU_URL_PATH,
71 MU_URL_HOST, 71 MU_URL_HOST,
72 _url_imap_init, /* url entry. */ 72 _url_imap_init, /* url entry. */
73 _mailbox_imap_init, /* Mailbox entry. */ 73 _mailbox_imap_init, /* Mailbox entry. */
...@@ -91,7 +91,7 @@ static struct _mu_record _imaps_record = ...@@ -91,7 +91,7 @@ static struct _mu_record _imaps_record =
91 MU_IMAP_PRIO, 91 MU_IMAP_PRIO,
92 MU_IMAPS_SCHEME, 92 MU_IMAPS_SCHEME,
93 MU_RECORD_DEFAULT, 93 MU_RECORD_DEFAULT,
94 MU_URL_CRED | MU_URL_INET | MU_URL_PATH | MU_URL_PARAM, 94 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET | MU_URL_PATH | MU_URL_PARAM,
95 MU_URL_HOST, 95 MU_URL_HOST,
96 _url_imaps_init, /* url entry. */ 96 _url_imaps_init, /* url entry. */
97 _mailbox_imaps_init, /* Mailbox entry. */ 97 _mailbox_imaps_init, /* Mailbox entry. */
...@@ -629,7 +629,7 @@ folder_imap_open (mu_folder_t folder, int flags) ...@@ -629,7 +629,7 @@ folder_imap_open (mu_folder_t folder, int flags)
629 { 629 {
630 f_imap_t f_imap = folder->data; 630 f_imap_t f_imap = folder->data;
631 const char *host; 631 const char *host;
632 long port = f_imap->imaps ? MU_IMAPS_PORT : MU_IMAP_PORT; 632 unsigned port = f_imap->imaps ? MU_IMAPS_PORT : MU_IMAP_PORT;
633 int status = 0; 633 int status = 0;
634 634
635 /* If we are already open for business, noop. */ 635 /* If we are already open for business, noop. */
......
...@@ -99,7 +99,7 @@ static struct _mu_record _maildir_record = ...@@ -99,7 +99,7 @@ static struct _mu_record _maildir_record =
99 MU_MAILDIR_PRIO, 99 MU_MAILDIR_PRIO,
100 MU_MAILDIR_SCHEME, 100 MU_MAILDIR_SCHEME,
101 MU_RECORD_LOCAL, 101 MU_RECORD_LOCAL,
102 MU_URL_PATH, 102 MU_URL_SCHEME | MU_URL_PATH,
103 MU_URL_PATH, 103 MU_URL_PATH,
104 mu_url_expand_path, /* Url init. */ 104 mu_url_expand_path, /* Url init. */
105 _mailbox_maildir_init, /* Mailbox init. */ 105 _mailbox_maildir_init, /* Mailbox init. */
......
...@@ -47,7 +47,7 @@ static struct _mu_record _prog_record = ...@@ -47,7 +47,7 @@ static struct _mu_record _prog_record =
47 MU_RECORD_DEFAULT, 47 MU_RECORD_DEFAULT,
48 /* FIXME: MU_URL_USER could be used to request running with this 48 /* FIXME: MU_URL_USER could be used to request running with this
49 user privileges. */ 49 user privileges. */
50 MU_URL_PATH | MU_URL_QUERY, 50 MU_URL_SCHEME | MU_URL_PATH | MU_URL_QUERY,
51 MU_URL_PATH, 51 MU_URL_PATH,
52 _url_prog_init, /* url init. */ 52 _url_prog_init, /* url init. */
53 _mu_mailer_mailbox_init, /* Mailbox entry. */ 53 _mu_mailer_mailbox_init, /* Mailbox entry. */
......
...@@ -76,7 +76,7 @@ static struct _mu_record _mu_remote_smtp_record = { ...@@ -76,7 +76,7 @@ static struct _mu_record _mu_remote_smtp_record = {
76 MU_SMTP_PRIO, 76 MU_SMTP_PRIO,
77 "remote+smtp", 77 "remote+smtp",
78 MU_RECORD_DEFAULT, 78 MU_RECORD_DEFAULT,
79 MU_URL_CRED | MU_URL_INET | MU_URL_PATH | MU_URL_PARAM, 79 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET | MU_URL_PATH | MU_URL_PARAM,
80 MU_URL_HOST, 80 MU_URL_HOST,
81 _url_remote_smtp_init, /* url init. */ 81 _url_remote_smtp_init, /* url init. */
82 _mu_mailer_mailbox_init, /* Mailbox init. */ 82 _mu_mailer_mailbox_init, /* Mailbox init. */
...@@ -108,7 +108,7 @@ static struct _mu_record _mu_remote_sendmail_record = ...@@ -108,7 +108,7 @@ static struct _mu_record _mu_remote_sendmail_record =
108 MU_SENDMAIL_PRIO, 108 MU_SENDMAIL_PRIO,
109 "remote+sendmail", 109 "remote+sendmail",
110 MU_RECORD_DEFAULT, 110 MU_RECORD_DEFAULT,
111 MU_URL_PATH, 111 MU_URL_SCHEME | MU_URL_PATH,
112 MU_URL_PATH, 112 MU_URL_PATH,
113 _url_remote_sendmail_init, /* url init. */ 113 _url_remote_sendmail_init, /* url init. */
114 _mu_mailer_mailbox_init, /* Mailbox entry. */ 114 _mu_mailer_mailbox_init, /* Mailbox entry. */
...@@ -137,7 +137,7 @@ static struct _mu_record _mu_remote_prog_record = ...@@ -137,7 +137,7 @@ static struct _mu_record _mu_remote_prog_record =
137 MU_PROG_PRIO, 137 MU_PROG_PRIO,
138 "remote+prog", 138 "remote+prog",
139 MU_RECORD_DEFAULT, 139 MU_RECORD_DEFAULT,
140 MU_URL_CRED | MU_URL_PATH | MU_URL_QUERY, 140 MU_URL_SCHEME | MU_URL_CRED | MU_URL_PATH | MU_URL_QUERY,
141 MU_URL_PATH, 141 MU_URL_PATH,
142 _url_remote_prog_init, /* url init. */ 142 _url_remote_prog_init, /* url init. */
143 _mu_mailer_mailbox_init, /* Mailbox entry. */ 143 _mu_mailer_mailbox_init, /* Mailbox entry. */
......
...@@ -271,9 +271,9 @@ static struct _mu_record _sendmail_record = ...@@ -271,9 +271,9 @@ static struct _mu_record _sendmail_record =
271 MU_SENDMAIL_PRIO, 271 MU_SENDMAIL_PRIO,
272 MU_SENDMAIL_SCHEME, 272 MU_SENDMAIL_SCHEME,
273 MU_RECORD_DEFAULT, 273 MU_RECORD_DEFAULT,
274 MU_URL_PATH, 274 MU_URL_SCHEME | MU_URL_PATH,
275 0, /* Nothing is required in the URL, except scheme. Missing path means 275 MU_URL_SCHEME, /* Nothing is required in the URL, except scheme.
276 using PATH_SENDMAIL. */ 276 Missing path means using PATH_SENDMAIL. */
277 _url_sendmail_init, /* url init. */ 277 _url_sendmail_init, /* url init. */
278 _mu_mailer_mailbox_init, /* Mailbox entry. */ 278 _mu_mailer_mailbox_init, /* Mailbox entry. */
279 _mu_mailer_sendmail_init, /* Mailer entry. */ 279 _mu_mailer_sendmail_init, /* Mailer entry. */
......
...@@ -65,7 +65,7 @@ static struct _mu_record _smtp_record = { ...@@ -65,7 +65,7 @@ static struct _mu_record _smtp_record = {
65 MU_SMTP_PRIO, 65 MU_SMTP_PRIO,
66 MU_SMTP_SCHEME, 66 MU_SMTP_SCHEME,
67 MU_RECORD_DEFAULT, 67 MU_RECORD_DEFAULT,
68 MU_URL_CRED | MU_URL_INET | MU_URL_PARAM, 68 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET | MU_URL_PARAM,
69 MU_URL_HOST, 69 MU_URL_HOST,
70 _url_smtp_init, /* url init. */ 70 _url_smtp_init, /* url init. */
71 _mu_mailer_mailbox_init, /* Mailbox init. */ 71 _mu_mailer_mailbox_init, /* Mailbox init. */
...@@ -113,7 +113,7 @@ static int ...@@ -113,7 +113,7 @@ static int
113 smtp_open (mu_mailer_t mailer, int flags) 113 smtp_open (mu_mailer_t mailer, int flags)
114 { 114 {
115 const char *host, *auth; 115 const char *host, *auth;
116 long port; 116 unsigned port;
117 struct _smtp_mailer *smtp_mailer = mailer->data; 117 struct _smtp_mailer *smtp_mailer = mailer->data;
118 int rc; 118 int rc;
119 size_t parmc = 0; 119 size_t parmc = 0;
......
...@@ -77,15 +77,6 @@ _mu_smtp_fixup_params (mu_smtp_t smtp) ...@@ -77,15 +77,6 @@ _mu_smtp_fixup_params (mu_smtp_t smtp)
77 return rc; 77 return rc;
78 } 78 }
79 79
80 rc = mu_url_parse (url);
81 if (rc)
82 {
83 mu_diag_output (MU_DIAG_ERROR, "cannot parse URL: %s",
84 mu_strerror (rc));
85 mu_url_destroy (&url);
86 return rc;
87 }
88
89 if (!(flags & _HAS_USERNAME)) 80 if (!(flags & _HAS_USERNAME))
90 { 81 {
91 rc = mu_url_sget_user (url, &str); 82 rc = mu_url_sget_user (url, &str);
......
...@@ -101,7 +101,7 @@ static struct _mu_record _mbox_record = ...@@ -101,7 +101,7 @@ static struct _mu_record _mbox_record =
101 MU_MBOX_PRIO, 101 MU_MBOX_PRIO,
102 MU_MBOX_SCHEME, 102 MU_MBOX_SCHEME,
103 MU_RECORD_LOCAL, 103 MU_RECORD_LOCAL,
104 MU_URL_PATH, 104 MU_URL_SCHEME | MU_URL_PATH,
105 MU_URL_PATH, 105 MU_URL_PATH,
106 mu_url_expand_path, /* URL init. */ 106 mu_url_expand_path, /* URL init. */
107 _mailbox_mbox_init, /* Mailbox init. */ 107 _mailbox_mbox_init, /* Mailbox init. */
......
...@@ -139,7 +139,7 @@ static struct _mu_record _mh_record = ...@@ -139,7 +139,7 @@ static struct _mu_record _mh_record =
139 MU_MH_PRIO, 139 MU_MH_PRIO,
140 MU_MH_SCHEME, 140 MU_MH_SCHEME,
141 MU_RECORD_LOCAL, 141 MU_RECORD_LOCAL,
142 MU_URL_PATH, 142 MU_URL_SCHEME | MU_URL_PATH,
143 MU_URL_PATH, 143 MU_URL_PATH,
144 mu_url_expand_path, /* Url init. */ 144 mu_url_expand_path, /* Url init. */
145 _mailbox_mh_init, /* Mailbox init. */ 145 _mailbox_mh_init, /* Mailbox init. */
......
...@@ -46,7 +46,7 @@ static struct _mu_record _nntp_record = ...@@ -46,7 +46,7 @@ static struct _mu_record _nntp_record =
46 MU_NNTP_PRIO, 46 MU_NNTP_PRIO,
47 MU_NNTP_URL_SCHEME, 47 MU_NNTP_URL_SCHEME,
48 MU_RECORD_DEFAULT, 48 MU_RECORD_DEFAULT,
49 MU_URL_CRED | MU_URL_INET | MU_URL_PATH, 49 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET | MU_URL_PATH,
50 MU_URL_HOST, 50 MU_URL_HOST,
51 _nntp_url_init, /* Url init. */ 51 _nntp_url_init, /* Url init. */
52 _nntp_mailbox_init, /* Mailbox init. */ 52 _nntp_mailbox_init, /* Mailbox init. */
...@@ -104,7 +104,7 @@ nntp_folder_open (mu_folder_t folder, int flags) ...@@ -104,7 +104,7 @@ nntp_folder_open (mu_folder_t folder, int flags)
104 f_nntp_t f_nntp = folder->data; 104 f_nntp_t f_nntp = folder->data;
105 mu_stream_t carrier = NULL; 105 mu_stream_t carrier = NULL;
106 const char *host; 106 const char *host;
107 long port = MU_NNTP_DEFAULT_PORT; /* default nntp port. */ 107 unsigned port = MU_NNTP_DEFAULT_PORT; /* default nntp port. */
108 int status = 0; 108 int status = 0;
109 109
110 /* If we are already open for business, noop. */ 110 /* If we are already open for business, noop. */
......
...@@ -48,7 +48,7 @@ static struct _mu_record _pop_record = ...@@ -48,7 +48,7 @@ static struct _mu_record _pop_record =
48 MU_POP_PRIO, 48 MU_POP_PRIO,
49 MU_POP_SCHEME, 49 MU_POP_SCHEME,
50 MU_RECORD_DEFAULT, 50 MU_RECORD_DEFAULT,
51 MU_URL_CRED | MU_URL_INET | MU_URL_PARAM, 51 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET | MU_URL_PARAM,
52 MU_URL_HOST, 52 MU_URL_HOST,
53 _url_pop_init, /* Url init. */ 53 _url_pop_init, /* Url init. */
54 _mailbox_pop_init, /* Mailbox init. */ 54 _mailbox_pop_init, /* Mailbox init. */
...@@ -69,7 +69,7 @@ static struct _mu_record _pops_record = ...@@ -69,7 +69,7 @@ static struct _mu_record _pops_record =
69 MU_POP_PRIO, 69 MU_POP_PRIO,
70 MU_POPS_SCHEME, 70 MU_POPS_SCHEME,
71 MU_RECORD_DEFAULT, 71 MU_RECORD_DEFAULT,
72 MU_URL_CRED | MU_URL_INET, 72 MU_URL_SCHEME | MU_URL_CRED | MU_URL_INET,
73 MU_URL_HOST, 73 MU_URL_HOST,
74 _url_pops_init, /* Url init. */ 74 _url_pops_init, /* Url init. */
75 _mailbox_pops_init, /* Mailbox init. */ 75 _mailbox_pops_init, /* Mailbox init. */
......
...@@ -105,7 +105,7 @@ pop_open (mu_mailbox_t mbox, int flags) ...@@ -105,7 +105,7 @@ pop_open (mu_mailbox_t mbox, int flags)
105 struct _pop3_mailbox *mpd = mbox->data; 105 struct _pop3_mailbox *mpd = mbox->data;
106 int status; 106 int status;
107 const char *host; 107 const char *host;
108 long port = mpd->pops ? MU_POPS_PORT : MU_POP_PORT; 108 unsigned port = mpd->pops ? MU_POPS_PORT : MU_POP_PORT;
109 mu_stream_t stream; 109 mu_stream_t stream;
110 110
111 /* Sanity checks. */ 111 /* Sanity checks. */
......
...@@ -385,13 +385,6 @@ do_delivery (mu_url_t url, mu_message_t msg, const char *name, char **errp) ...@@ -385,13 +385,6 @@ do_delivery (mu_url_t url, mu_message_t msg, const char *name, char **errp)
385 auth->mailbox, mu_strerror (status)); 385 auth->mailbox, mu_strerror (status));
386 return exit_code = EX_UNAVAILABLE; 386 return exit_code = EX_UNAVAILABLE;
387 } 387 }
388 status = mu_url_parse (url);
389 if (status)
390 {
391 maidag_error (_("error parsing URL %s: %s"),
392 auth->mailbox, mu_strerror (status));
393 return exit_code = EX_UNAVAILABLE;
394 }
395 } 388 }
396 389
397 status = mu_mailbox_create_from_url (&mbox, url); 390 status = mu_mailbox_create_from_url (&mbox, url);
...@@ -437,14 +430,6 @@ deliver_to_url (mu_message_t msg, char *dest_id, char **errp) ...@@ -437,14 +430,6 @@ deliver_to_url (mu_message_t msg, char *dest_id, char **errp)
437 mu_strerror (status)); 430 mu_strerror (status));
438 return EX_NOUSER; 431 return EX_NOUSER;
439 } 432 }
440 status = mu_url_parse (url);
441 if (status)
442 {
443 maidag_error (_("%s: cannot parse url: %s"), dest_id,
444 mu_strerror (status));
445 mu_url_destroy (&url);
446 return EX_NOUSER;
447 }
448 status = mu_url_sget_user (url, &name); 433 status = mu_url_sget_user (url, &name);
449 if (status == MU_ERR_NOENT) 434 if (status == MU_ERR_NOENT)
450 name = NULL; 435 name = NULL;
......
...@@ -75,6 +75,10 @@ wicket_match (mu_stream_t stream, const char *str) ...@@ -75,6 +75,10 @@ wicket_match (mu_stream_t stream, const char *str)
75 int rc, ret; 75 int rc, ret;
76 mu_url_t u, url; 76 mu_url_t u, url;
77 struct mu_debug_locus loc; 77 struct mu_debug_locus loc;
78 int flags = MU_URL_PARSE_ALL;
79
80 if (wicket_verbose > 2)
81 flags &= ~MU_URL_PARSE_HIDEPASS;
78 82
79 rc = mu_url_create (&u, str); 83 rc = mu_url_create (&u, str);
80 if (rc) 84 if (rc)
...@@ -82,12 +86,6 @@ wicket_match (mu_stream_t stream, const char *str) ...@@ -82,12 +86,6 @@ wicket_match (mu_stream_t stream, const char *str)
82 mu_diag_funcall (MU_DIAG_ERROR, "mu_url_create", str, rc); 86 mu_diag_funcall (MU_DIAG_ERROR, "mu_url_create", str, rc);
83 return 2; 87 return 2;
84 } 88 }
85 rc = mu_url_parse (u);
86 if (rc)
87 {
88 mu_diag_funcall (MU_DIAG_ERROR, "mu_url_parse", str, rc);
89 return 2;
90 }
91 89
92 rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); 90 rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
93 if (rc) 91 if (rc)
...@@ -97,7 +95,7 @@ wicket_match (mu_stream_t stream, const char *str) ...@@ -97,7 +95,7 @@ wicket_match (mu_stream_t stream, const char *str)
97 } 95 }
98 loc.file = wicket_file; 96 loc.file = wicket_file;
99 loc.line = 0; 97 loc.line = 0;
100 rc = mu_wicket_stream_match_url (stream, &loc, u, &url); 98 rc = mu_wicket_stream_match_url (stream, &loc, u, flags, &url);
101 switch (rc) 99 switch (rc)
102 { 100 {
103 case 0: 101 case 0:
...@@ -106,27 +104,7 @@ wicket_match (mu_stream_t stream, const char *str) ...@@ -106,27 +104,7 @@ wicket_match (mu_stream_t stream, const char *str)
106 { 104 {
107 printf ("%s: %s:%d", str, loc.file, loc.line); 105 printf ("%s: %s:%d", str, loc.file, loc.line);
108 if (wicket_verbose > 1) 106 if (wicket_verbose > 1)
109 {
110 printf (": %s", mu_url_to_string (url)); 107 printf (": %s", mu_url_to_string (url));
111 if (wicket_verbose > 2)
112 {
113 mu_secret_t s;
114 rc = mu_url_get_secret (url, &s);
115 if (rc == 0)
116 {
117 printf (": %s", mu_secret_password (s));
118 mu_secret_password_unref (s);
119 mu_secret_unref (s);
120 }
121 else if (rc == MU_ERR_NOENT)
122 printf (": [%s]", _("no password"));
123 else
124 {
125 printf (": [error: %s]", mu_strerror (rc));
126 ret = 2;
127 }
128 }
129 }
130 putchar ('\n'); 108 putchar ('\n');
131 } 109 }
132 break; 110 break;
......
...@@ -102,6 +102,7 @@ api_url_destroy (PyObject *self, PyObject *args) ...@@ -102,6 +102,7 @@ api_url_destroy (PyObject *self, PyObject *args)
102 return _ro (Py_None); 102 return _ro (Py_None);
103 } 103 }
104 104
105 /* FIXME: Remove */
105 static PyObject * 106 static PyObject *
106 api_url_parse (PyObject *self, PyObject *args) 107 api_url_parse (PyObject *self, PyObject *args)
107 { 108 {
...@@ -111,22 +112,21 @@ api_url_parse (PyObject *self, PyObject *args) ...@@ -111,22 +112,21 @@ api_url_parse (PyObject *self, PyObject *args)
111 if (!PyArg_ParseTuple (args, "O!", &PyUrlType, &py_url)) 112 if (!PyArg_ParseTuple (args, "O!", &PyUrlType, &py_url))
112 return NULL; 113 return NULL;
113 114
114 status = mu_url_parse (py_url->url); 115 return _ro (0);
115 return _ro (PyInt_FromLong (status));
116 } 116 }
117 117
118 static PyObject * 118 static PyObject *
119 api_url_get_port (PyObject *self, PyObject *args) 119 api_url_get_port (PyObject *self, PyObject *args)
120 { 120 {
121 int status; 121 int status;
122 long port; 122 unsigned port;
123 PyUrl *py_url; 123 PyUrl *py_url;
124 124
125 if (!PyArg_ParseTuple (args, "O!", &PyUrlType, &py_url)) 125 if (!PyArg_ParseTuple (args, "O!", &PyUrlType, &py_url))
126 return NULL; 126 return NULL;
127 127
128 status = mu_url_get_port (py_url->url, &port); 128 status = mu_url_get_port (py_url->url, &port);
129 return status_object (status, PyInt_FromLong (port)); 129 return status_object (status, PyInt_FromLong ((long)port));
130 } 130 }
131 131
132 static PyObject * 132 static PyObject *
......