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.
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 | ... | ... |
... | @@ -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; | ... | ... |
libmailutils/base/url.c
deleted
100644 → 0
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 | ... | ... |
libmailutils/string/xdecode.c
0 → 100644
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: | ... | ... |
libmailutils/url/Makefile.am
0 → 100644
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 |
libmailutils/url/accessor.h
0 → 100644
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 | } |
libmailutils/url/copy.c
0 → 100644
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 |
libmailutils/url/create.c
0 → 100644
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 | } |
libmailutils/url/decode.c
0 → 100644
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 |
libmailutils/url/destroy.c
0 → 100644
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 | } |
libmailutils/url/dup.c
0 → 100644
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 | } |
libmailutils/url/expand.c
0 → 100644
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 |
libmailutils/url/flag.c
0 → 100644
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 | } |
libmailutils/url/get-auth.c
0 → 100644
libmailutils/url/get-host.c
0 → 100644
libmailutils/url/get-param.c
0 → 100644
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 |
libmailutils/url/get-path.c
0 → 100644
libmailutils/url/get-portstr.c
0 → 100644
libmailutils/url/get-query.c
0 → 100644
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 |
libmailutils/url/get-scheme.c
0 → 100644
libmailutils/url/get-secret.c
0 → 100644
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 | } |
libmailutils/url/get-user.c
0 → 100644
libmailutils/url/match.c
0 → 100644
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 | } |
libmailutils/url/port.c
0 → 100644
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 |
libmailutils/url/scheme.c
0 → 100644
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 |
libmailutils/url/uplevel.c
0 → 100644
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 |
libmailutils/url/urlstr.c
0 → 100644
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 * | ... | ... |
-
Please register or sign in to post a comment