summaryrefslogtreecommitdiff
path: root/libmailutils/url
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-10-26 13:00:52 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-10-26 13:36:28 +0300
commit3327a23a49e532c068972a0b2d64021361540f7b (patch)
treeb2d6508005ac8343a54638142c4f8234f7202441 /libmailutils/url
parent6203ae65f53758a4b893e6e176be7c153a31bef0 (diff)
downloadmailutils-3327a23a49e532c068972a0b2d64021361540f7b.tar.gz
mailutils-3327a23a49e532c068972a0b2d64021361540f7b.tar.bz2
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.
Diffstat (limited to 'libmailutils/url')
-rw-r--r--libmailutils/url/Makefile.am45
-rw-r--r--libmailutils/url/accessor.h143
-rw-r--r--libmailutils/url/copy.c145
-rw-r--r--libmailutils/url/create.c525
-rw-r--r--libmailutils/url/decode.c118
-rw-r--r--libmailutils/url/destroy.c74
-rw-r--r--libmailutils/url/dup.c56
-rw-r--r--libmailutils/url/expand.c216
-rw-r--r--libmailutils/url/flag.c40
-rw-r--r--libmailutils/url/get-auth.c3
-rw-r--r--libmailutils/url/get-host.c2
-rw-r--r--libmailutils/url/get-param.c131
-rw-r--r--libmailutils/url/get-path.c2
-rw-r--r--libmailutils/url/get-portstr.c2
-rw-r--r--libmailutils/url/get-query.c72
-rw-r--r--libmailutils/url/get-scheme.c2
-rw-r--r--libmailutils/url/get-secret.c44
-rw-r--r--libmailutils/url/get-user.c2
-rw-r--r--libmailutils/url/match.c102
-rw-r--r--libmailutils/url/port.c53
-rw-r--r--libmailutils/url/scheme.c55
-rw-r--r--libmailutils/url/uplevel.c71
-rw-r--r--libmailutils/url/urlstr.c31
23 files changed, 1934 insertions, 0 deletions
diff --git a/libmailutils/url/Makefile.am b/libmailutils/url/Makefile.am
new file mode 100644
index 000000000..51e3e6483
--- /dev/null
+++ b/libmailutils/url/Makefile.am
@@ -0,0 +1,45 @@
+# GNU Mailutils -- a suite of utilities for electronic mail
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General
+# Public License along with this library. If not, see
+# <http://www.gnu.org/licenses/>.
+
+noinst_LTLIBRARIES = liburl.la
+
+liburl_la_SOURCES = \
+ accessor.h\
+ copy.c\
+ create.c\
+ decode.c\
+ destroy.c\
+ dup.c\
+ expand.c\
+ flag.c\
+ get-auth.c\
+ get-host.c\
+ get-param.c\
+ get-path.c\
+ get-portstr.c\
+ get-query.c\
+ get-scheme.c\
+ get-secret.c\
+ get-user.c\
+ match.c\
+ port.c\
+ scheme.c\
+ uplevel.c\
+ urlstr.c
+
+INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
+
diff --git a/libmailutils/url/accessor.h b/libmailutils/url/accessor.h
new file mode 100644
index 000000000..de3871152
--- /dev/null
+++ b/libmailutils/url/accessor.h
@@ -0,0 +1,143 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/util.h>
+#include <mailutils/cstr.h>
+#include <mailutils/sys/url.h>
+
+/* General accessors: */
+#define AC2(a,b) a ## b
+#define METHOD(pfx,part) AC2(pfx,part)
+#define AC4(a,b,c,d) a ## b ## c ## d
+#define ACCESSOR(action,field) AC4(mu_url_,action,_,field)
+
+/* Define a `static get' accessor */
+int
+ACCESSOR(sget,URL_PART) (mu_url_t url, char const **sptr)
+{
+ if (url == NULL)
+ return EINVAL;
+ if (!url->URL_PART)
+ {
+ if (url->METHOD(_get_,URL_PART))
+ {
+ size_t n;
+ char *buf;
+
+ int status = url->METHOD(_get_,URL_PART) (url, NULL, 0, &n);
+ if (status)
+ return status;
+
+ buf = malloc (n + 1);
+ if (!buf)
+ return ENOMEM;
+
+ status = url->METHOD(_get_,URL_PART) (url, buf, n + 1, NULL);
+ if (status)
+ return status;
+
+ if (buf[0])
+ {
+ /* FIXME */
+ status = mu_str_url_decode (&url->URL_PART, buf);
+ if (status)
+ {
+ free (buf);
+ return status;
+ }
+ }
+ else
+ url->URL_PART = buf;
+ if (!url->URL_PART)
+ return ENOMEM;
+ }
+ else
+ return MU_ERR_NOENT;
+ }
+ *sptr = url->URL_PART;
+ return 0;
+}
+
+/* Define a `get' accessor */
+int
+ACCESSOR(get,URL_PART) (mu_url_t url, char *buf, size_t len, size_t *n)
+{
+ size_t i;
+ const char *str;
+ int status = ACCESSOR(sget, URL_PART) (url, &str);
+
+ if (status)
+ return status;
+
+ i = mu_cpystr (buf, str, len);
+ if (n)
+ *n = i;
+ return 0;
+}
+
+/* Define an `allocated get' accessor */
+int
+ACCESSOR(aget, URL_PART) (mu_url_t url, char **buf)
+{
+ const char *str;
+ int status = ACCESSOR(sget, URL_PART) (url, &str);
+
+ if (status)
+ return status;
+
+ if (str)
+ {
+ *buf = strdup (str);
+ if (!*buf)
+ status = ENOMEM;
+ }
+ else
+ *buf = NULL;
+ return status;
+}
+
+/* Define a comparator */
+int
+ACCESSOR(is_same,URL_PART) (mu_url_t url1, mu_url_t url2)
+{
+ const char *s1, *s2;
+ int status1, status2;
+
+ status1 = ACCESSOR(sget, URL_PART) (url1, &s1);
+ if (status1 && status1 != MU_ERR_NOENT)
+ return 0;
+ status2 = ACCESSOR(sget, URL_PART) (url2, &s2);
+ if (status2 && status2 != MU_ERR_NOENT)
+ return 0;
+
+ if (status1 || status2)
+ return status1 == status2; /* Both fields are missing */
+ return mu_c_strcasecmp (s1, s2) == 0;
+}
diff --git a/libmailutils/url/copy.c b/libmailutils/url/copy.c
new file mode 100644
index 000000000..7190b4212
--- /dev/null
+++ b/libmailutils/url/copy.c
@@ -0,0 +1,145 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/argcv.h>
+#include <mailutils/secret.h>
+#include <mailutils/util.h>
+#include <mailutils/sys/url.h>
+
+struct copy_tab
+{
+ int mask;
+ int (*fun) (mu_url_t, mu_url_t, size_t);
+ size_t off;
+};
+
+static int
+_url_copy_str (mu_url_t dest_url, mu_url_t src_url, size_t off)
+{
+ char **dest = (char**) ((char*) dest_url + off);
+ char *src = *(char**) ((char*) src_url + off);
+ char *p = strdup (src);
+ if (!p)
+ return ENOMEM;
+ *dest = p;
+ return 0;
+}
+
+static int
+_url_copy_secret (mu_url_t dest, mu_url_t src, size_t off)
+{
+ return mu_secret_dup (src->secret, &dest->secret);
+}
+
+static int
+_url_copy_port (mu_url_t dest, mu_url_t src, size_t off)
+{
+ if (src->portstr)
+ {
+ dest->portstr = strdup (src->portstr);
+ if (!dest->portstr)
+ return ENOMEM;
+ }
+ dest->port = src->port;
+ return 0;
+}
+
+static char **
+argcv_copy (size_t argc, char **argv)
+{
+ size_t i;
+ char **nv = calloc (argc + 1, sizeof (nv[0]));
+ if (!nv)
+ return NULL;
+ for (i = 0; i < argc; i++)
+ if ((nv[i] = strdup (argv[i])) == NULL)
+ {
+ mu_argcv_free (i, nv);
+ free (nv);
+ return NULL;
+ }
+ return nv;
+}
+
+static int
+_url_copy_param (mu_url_t dest, mu_url_t src, size_t off)
+{
+ if ((dest->fvpairs = argcv_copy (src->fvcount, src->fvpairs)) == NULL)
+ return ENOMEM;
+ dest->fvcount = src->fvcount;
+ return 0;
+}
+
+static int
+_url_copy_query (mu_url_t dest, mu_url_t src, size_t off)
+{
+ if ((dest->qargv = argcv_copy (src->qargc, src->qargv)) == NULL)
+ return ENOMEM;
+ dest->qargc = src->qargc;
+ return 0;
+}
+
+static struct copy_tab copy_tab[] = {
+ { MU_URL_SCHEME, _url_copy_str, mu_offsetof (struct _mu_url, scheme) },
+ { MU_URL_USER, _url_copy_str, mu_offsetof (struct _mu_url, user) },
+ { MU_URL_SECRET, _url_copy_secret, 0 },
+ { MU_URL_AUTH, _url_copy_str, mu_offsetof (struct _mu_url, auth) },
+ { MU_URL_HOST, _url_copy_str, mu_offsetof (struct _mu_url, host) },
+ { MU_URL_PORT, _url_copy_port, 0 },
+ { MU_URL_PATH, _url_copy_str, mu_offsetof (struct _mu_url, path) },
+ { MU_URL_PARAM, _url_copy_param, 0 },
+ { MU_URL_QUERY, _url_copy_query, 0 }
+};
+
+int
+mu_url_copy_hints (mu_url_t url, mu_url_t hint)
+{
+ int i;
+
+ if (!url)
+ return EINVAL;
+ if (!hint)
+ return 0;
+ for (i = 0; i < MU_ARRAY_SIZE (copy_tab); i++)
+ {
+ if (!(url->flags & copy_tab[i].mask) &&
+ (hint->flags & copy_tab[i].mask))
+ {
+ int rc = copy_tab[i].fun (url, hint, copy_tab[i].off);
+ if (rc)
+ return rc;
+ url->flags |= copy_tab[i].mask;
+ }
+ }
+ return 0;
+}
+
+
+
+
+
diff --git a/libmailutils/url/create.c b/libmailutils/url/create.c
new file mode 100644
index 000000000..674a52469
--- /dev/null
+++ b/libmailutils/url/create.c
@@ -0,0 +1,525 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <limits.h>
+
+#include <mailutils/util.h>
+#include <mailutils/errno.h>
+#include <mailutils/argcv.h>
+#include <mailutils/secret.h>
+#include <mailutils/cstr.h>
+#include <mailutils/sys/url.h>
+
+struct mu_url_ctx
+{
+ int flags;
+ const char *input;
+ const char *cur;
+ mu_url_t url;
+
+ size_t passoff;
+
+ char *tokbuf;
+ size_t toksize;
+ size_t toklen;
+};
+
+static int
+getkn (struct mu_url_ctx *ctx, char *delim)
+{
+ size_t n;
+
+ if (*ctx->cur == 0)
+ return -1;
+ n = strcspn (ctx->cur, delim);
+ if (n > ctx->toksize)
+ {
+ char *p = realloc (ctx->tokbuf, n + 1);
+ if (!p)
+ return ENOENT;
+ ctx->toksize = n + 1;
+ ctx->tokbuf = p;
+ }
+ memcpy (ctx->tokbuf, ctx->cur, n);
+ ctx->tokbuf[n] = 0;
+ ctx->toklen = n;
+ ctx->cur += n;
+ return 0;
+}
+
+#define INIT_ARRAY_SIZE 16
+
+static int
+expand_array (size_t *pwc, char ***pwv, int incr)
+{
+ size_t wc = *pwc;
+ char **wv = *pwv;
+
+ if (!wv)
+ {
+ wv = calloc (INIT_ARRAY_SIZE, sizeof (wv[0]));
+ wc = INIT_ARRAY_SIZE;
+ }
+ else
+ {
+ if (incr)
+ wc += incr;
+ else
+ {
+ size_t newsize = wc * 2;
+ if (newsize < wc)
+ return ENOMEM;
+ wc = newsize;
+ }
+ wv = realloc (wv, sizeof (wv[0]) * wc);
+ }
+ if (!wv)
+ return ENOMEM;
+ *pwv = wv;
+ *pwc = wc;
+ return 0;
+}
+
+static int
+parse_param (struct mu_url_ctx *ctx, char *delim, int *pargc, char ***pargv)
+{
+ int rc;
+ size_t wc = 0, wn = 0;
+ char **wv = NULL;
+
+ while ((rc = getkn (ctx, delim)) == 0)
+ {
+ if (wn == wc)
+ {
+ rc = expand_array (&wc, &wv, 0);
+ if (rc)
+ break;
+ }
+ wv[wn] = strdup (ctx->tokbuf);
+ if (!wv[wn])
+ {
+ rc = ENOMEM;
+ break;
+ }
+ wn++;
+ if (*ctx->cur != delim[0])
+ break;
+ ctx->cur++;
+ }
+
+ if (rc == 0)
+ {
+ if (wn == wc)
+ {
+ rc = expand_array (&wc, &wv, 1);
+ if (rc)
+ {
+ mu_argcv_free (wc, wv);
+ return ENOMEM;
+ }
+ wv[wn] = NULL;
+ }
+
+ *pargv = realloc (wv, sizeof (wv[0]) * (wn + 1));
+ *pargc = wn;
+ }
+ else
+ mu_argcv_free (wc, wv);
+
+ return rc;
+}
+
+static int
+_mu_url_ctx_parse_query (struct mu_url_ctx *ctx)
+{
+ int rc;
+
+ ctx->cur++;
+ rc = parse_param (ctx, "&", &ctx->url->qargc, &ctx->url->qargv);
+ if (rc == 0 && ctx->url->qargc)
+ ctx->url->flags |= MU_URL_QUERY;
+ return rc;
+}
+
+static int
+_mu_url_ctx_parse_param (struct mu_url_ctx *ctx)
+{
+ int rc;
+
+ ctx->cur++;
+ rc = parse_param (ctx, ";?", &ctx->url->fvcount, &ctx->url->fvpairs);
+ if (rc)
+ return rc;
+ if (ctx->url->fvcount)
+ ctx->url->flags |= MU_URL_PARAM;
+ if (*ctx->cur == '?')
+ return _mu_url_ctx_parse_query (ctx);
+ return 0;
+}
+
+static int
+str_assign (char **ptr, const char *str)
+{
+ *ptr = strdup (str);
+ if (!*ptr)
+ return ENOMEM;
+ return 0;
+}
+
+static int
+_mu_url_ctx_parse_path (struct mu_url_ctx *ctx)
+{
+ int rc;
+ mu_url_t url = ctx->url;
+
+ rc = getkn (ctx, ";?");
+ if (rc)
+ return rc;
+ rc = str_assign (&url->path, ctx->tokbuf);
+ if (rc == 0)
+ url->flags |= MU_URL_PATH;
+ if (*ctx->cur == ';')
+ return _mu_url_ctx_parse_param (ctx);
+ if (*ctx->cur == '?')
+ return _mu_url_ctx_parse_query (ctx);
+ return 0;
+}
+
+static int
+_mu_url_ctx_parse_host (struct mu_url_ctx *ctx, int has_host)
+{
+ int rc;
+ mu_url_t url = ctx->url;
+
+ rc = getkn (ctx, ":/;?");
+ if (rc)
+ return rc;
+
+ if (ctx->toklen)
+ {
+ rc = str_assign (&url->host, ctx->tokbuf);
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_HOST;
+ has_host = 1;
+ }
+
+ if (*ctx->cur == ':')
+ {
+ ctx->cur++;
+ has_host = 1;
+
+ rc = getkn (ctx, "/;?");
+ if (rc)
+ return rc;
+
+ rc = str_assign (&url->portstr, ctx->tokbuf);
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_PORT;
+ }
+
+ if (*ctx->cur == '/')
+ {
+ if (has_host)
+ ctx->cur++;
+ return _mu_url_ctx_parse_path (ctx);
+ }
+
+ if (*ctx->cur == ';')
+ return _mu_url_ctx_parse_param (ctx);
+
+ if (*ctx->cur == '?')
+ return _mu_url_ctx_parse_query (ctx);
+ return 0;
+}
+
+static int
+_mu_url_ctx_parse_cred (struct mu_url_ctx *ctx)
+{
+ int rc, has_cred;
+ mu_url_t url = ctx->url;
+ const char *save = ctx->cur;
+
+ rc = getkn (ctx, "@");
+ if (rc)
+ return rc;
+ has_cred = *ctx->cur == '@';
+ /* restore the pointer */
+ ctx->cur = save;
+ if (has_cred)
+ {
+ /* Try to split the user into a:
+ <user>:<password>
+ or
+ <user>:<password>;AUTH=<auth>
+ */
+ rc = getkn (ctx, ":;@");
+ if (rc)
+ return rc;
+
+ if (ctx->toklen)
+ {
+ rc = str_assign (&url->user, ctx->tokbuf);
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_USER;
+ }
+
+ if (*ctx->cur == ':')
+ {
+ ctx->cur++;
+ ctx->passoff = ctx->cur - ctx->input;
+
+ rc = getkn (ctx, ";@");
+ if (rc)
+ return rc;
+
+ if (ctx->toklen)
+ {
+ if (mu_secret_create (&url->secret, ctx->tokbuf, ctx->toklen))
+ return ENOMEM;
+ else
+ /* Clear password */
+ memset (ctx->tokbuf, 0, ctx->toklen);
+ url->flags |= MU_URL_SECRET;
+ }
+ }
+ if (*ctx->cur == ';')
+ {
+ ctx->cur++;
+
+ rc = getkn (ctx, "@");
+ if (rc)
+ return rc;
+
+ /* Make sure it's the auth token. */
+ if (mu_c_strncasecmp (ctx->tokbuf, "auth=", 5) == 0)
+ {
+ rc = str_assign (&url->auth, ctx->tokbuf + 5);
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_AUTH;
+ }
+ }
+
+ /* Skip @ sign */
+ ctx->cur++;
+ }
+ return _mu_url_ctx_parse_host (ctx, has_cred);
+}
+
+int
+_mu_url_ctx_parse (struct mu_url_ctx *ctx)
+{
+ int rc;
+ mu_url_t url = ctx->url;
+
+ /* Parse the scheme part */
+ rc = getkn (ctx, ":/");
+ if (rc)
+ return rc;
+ if (*ctx->cur == ':')
+ {
+ rc = str_assign (&url->scheme, ctx->tokbuf);
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_SCHEME;
+ ctx->cur++;
+ }
+
+ if (*ctx->cur == 0)
+ return 0;
+
+ if (ctx->cur[0] == '/' && ctx->cur[1] == '/')
+ {
+ ctx->cur += 2;
+ return _mu_url_ctx_parse_cred (ctx);
+ }
+
+ return _mu_url_ctx_parse_path (ctx);
+}
+
+static int
+_mu_url_create_internal (struct mu_url_ctx *ctx, mu_url_t hint)
+{
+ int rc;
+ mu_url_t url = ctx->url;
+
+ if ((ctx->flags & MU_URL_PARSE_PIPE) && ctx->input[0] == '|')
+ {
+ rc = str_assign (&url->scheme, "prog");
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_SCHEME;
+ ctx->flags &= ~MU_URL_PARSE_HEXCODE;
+ rc = mu_argcv_get (ctx->input + 1, NULL, NULL, &url->qargc, &url->qargv);
+ if (rc == 0)
+ {
+ url->flags |= MU_URL_QUERY;
+ rc = str_assign (&url->path, url->qargv[0]);
+ if (rc == 0)
+ url->flags |= MU_URL_PATH;
+ }
+ }
+ else if ((ctx->flags & MU_URL_PARSE_SLASH) && ctx->input[0] == '/')
+ {
+ rc = str_assign (&url->scheme, "file");
+ if (rc)
+ return rc;
+ url->flags |= MU_URL_SCHEME;
+ ctx->flags &= ~MU_URL_PARSE_HEXCODE;
+ rc = str_assign (&url->path, ctx->input);
+ if (rc == 0)
+ url->flags |= MU_URL_PATH;
+ }
+ else
+ rc = _mu_url_ctx_parse (ctx);
+
+ if (rc)
+ return rc;
+
+ if (hint)
+ {
+ /* Fill in missing values */
+ rc = mu_url_copy_hints (url, hint);
+ if (rc)
+ return rc;
+ }
+
+ if (!(url->flags & MU_URL_SCHEME))
+ return MU_ERR_URL_MISS_PARTS;
+
+ /* RFC 1738, section 2.1, lower the scheme case */
+ mu_strlower (url->scheme);
+
+ if ((url->flags & MU_URL_PORT) && url->port == 0)
+ {
+ /* Convert port string to number */
+ unsigned long n;
+ char *p;
+
+ n = strtoul (url->portstr, &p, 10);
+ if (*p)
+ {
+ if (ctx->flags & MU_URL_PARSE_PORTSRV)
+ {
+ /* FIXME: Another proto? */
+ struct servent *sp = getservbyname (url->portstr, "tcp");
+ if (!sp)
+ return MU_ERR_TCP_NO_PORT; //FIXME: Error code?
+ url->port = ntohs (sp->s_port);
+ }
+ else
+ return MU_ERR_TCP_NO_PORT;
+ }
+ else if (n > USHRT_MAX)
+ return ERANGE;
+ else
+ url->port = n;
+ }
+
+ if (ctx->flags & MU_URL_PARSE_HEXCODE)
+ {
+ /* Decode the %XX notations */
+ rc = mu_url_decode (url);
+ if (rc)
+ return rc;
+ }
+
+ if ((url->flags & MU_URL_SECRET) &&
+ (ctx->flags & MU_URL_PARSE_HIDEPASS))
+ {
+ /* Obfuscate the password */
+#define PASS_REPL "***"
+#define PASS_REPL_LEN (sizeof (PASS_REPL) - 1)
+ size_t plen = mu_secret_length (url->secret);
+ size_t nlen = strlen (url->name);
+ size_t len = nlen - plen + PASS_REPL_LEN + 1;
+ char *newname;
+
+ memset (url->name + ctx->passoff, 0, plen);
+ if (len > nlen + 1)
+ {
+ newname = realloc (url->name, len);
+ if (!newname)
+ return rc;
+ url->name = newname;
+ }
+ else
+ newname = url->name;
+ memmove (newname + ctx->passoff + PASS_REPL_LEN,
+ newname + ctx->passoff + plen,
+ nlen - (ctx->passoff + plen) + 1);
+ memcpy (newname + ctx->passoff, PASS_REPL, PASS_REPL_LEN);
+ }
+
+ return 0;
+}
+
+int
+mu_url_create_hint (mu_url_t *purl, const char *str, int flags,
+ mu_url_t hint)
+{
+ int rc;
+ struct mu_url_ctx ctx;
+ mu_url_t url = calloc (1, sizeof (*url));
+ if (url == NULL)
+ return ENOMEM;
+ url->name = strdup (str);
+ if (!url->name)
+ {
+ free (url);
+ return ENOMEM;
+ }
+ memset (&ctx, 0, sizeof (ctx));
+ ctx.flags = flags;
+ ctx.input = str;
+ ctx.cur = ctx.input;
+ ctx.url = url;
+ rc = _mu_url_create_internal (&ctx, hint);
+ free (ctx.tokbuf);
+ if (rc)
+ mu_url_destroy (&url);
+ else
+ *purl = url;
+ return rc;
+}
+
+int
+mu_url_create (mu_url_t *purl, const char *str)
+{
+ return mu_url_create_hint (purl, str,
+ MU_URL_PARSE_HEXCODE |
+ MU_URL_PARSE_HIDEPASS |
+ MU_URL_PARSE_PORTSRV |
+ MU_URL_PARSE_PIPE |
+ MU_URL_PARSE_SLASH, NULL);
+}
diff --git a/libmailutils/url/decode.c b/libmailutils/url/decode.c
new file mode 100644
index 000000000..9aca0e217
--- /dev/null
+++ b/libmailutils/url/decode.c
@@ -0,0 +1,118 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/util.h>
+#include <mailutils/secret.h>
+#include <mailutils/sys/url.h>
+
+struct decode_tab
+{
+ int mask;
+ int (*fun) (mu_url_t, size_t);
+ size_t off;
+};
+
+static int
+_url_dec_str (mu_url_t url, size_t off)
+{
+ char **pptr = (char**) ((char*) url + off);
+ mu_str_url_decode_inline (*pptr);
+ return 0;
+}
+
+static int
+_url_dec_param (mu_url_t url, size_t off)
+{
+ int i;
+
+ for (i = 0; i < url->fvcount; i++)
+ mu_str_url_decode_inline (url->fvpairs[i]);
+ return 0;
+}
+
+static int
+_url_dec_query (mu_url_t url, size_t off)
+{
+ int i;
+
+ for (i = 0; i < url->qargc; i++)
+ mu_str_url_decode_inline (url->qargv[i]);
+ return 0;
+}
+
+static int
+_url_dec_secret (mu_url_t url, size_t off)
+{
+ char *pass;
+ mu_secret_t newsec;
+ int rc;
+
+ rc = mu_str_url_decode (&pass, mu_secret_password (url->secret));
+ if (rc)
+ return rc;
+ rc = mu_secret_create (&newsec, pass, strlen (pass));
+ memset (pass, 0, strlen (pass));
+ free (pass);
+ if (rc)
+ return rc;
+ mu_secret_destroy (&url->secret);
+ url->secret = newsec;
+ return 0;
+}
+
+static struct decode_tab decode_tab[] = {
+ { MU_URL_SCHEME, _url_dec_str, mu_offsetof (struct _mu_url, scheme) },
+ { MU_URL_USER, _url_dec_str, mu_offsetof (struct _mu_url, user) },
+ { MU_URL_SECRET, _url_dec_secret },
+ { MU_URL_AUTH, _url_dec_str, mu_offsetof (struct _mu_url, auth) },
+ { MU_URL_HOST, _url_dec_str, mu_offsetof (struct _mu_url, host) },
+ { MU_URL_PATH, _url_dec_str, mu_offsetof (struct _mu_url, path) },
+ { MU_URL_PARAM, _url_dec_param, 0 },
+ { MU_URL_QUERY, _url_dec_query, 0 }
+};
+
+int
+mu_url_decode (mu_url_t url)
+{
+ int i;
+
+ if (!url)
+ return EINVAL;
+ for (i = 0; i < MU_ARRAY_SIZE (decode_tab); i++)
+ {
+ if (url->flags & decode_tab[i].mask)
+ {
+ int rc = decode_tab[i].fun (url, decode_tab[i].off);
+ if (rc)
+ return rc;
+ }
+ }
+ return 0;
+}
+
diff --git a/libmailutils/url/destroy.c b/libmailutils/url/destroy.c
new file mode 100644
index 000000000..a46dc3150
--- /dev/null
+++ b/libmailutils/url/destroy.c
@@ -0,0 +1,74 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/argcv.h>
+#include <mailutils/secret.h>
+#include <mailutils/errno.h>
+#include <mailutils/sys/url.h>
+
+void
+mu_url_destroy (mu_url_t * purl)
+{
+ if (purl && *purl)
+ {
+ mu_url_t url = (*purl);
+
+ if (url->_destroy)
+ url->_destroy (url);
+
+ if (url->name)
+ free (url->name);
+
+ if (url->scheme)
+ free (url->scheme);
+
+ if (url->user)
+ free (url->user);
+
+ mu_secret_destroy (&url->secret);
+
+ if (url->auth)
+ free (url->auth);
+
+ if (url->host)
+ free (url->host);
+
+ if (url->path)
+ free (url->path);
+
+ if (url->fvcount)
+ mu_argcv_free (url->fvcount, url->fvpairs);
+
+ mu_argcv_free (url->qargc, url->qargv);
+
+ free (url);
+
+ *purl = NULL;
+ }
+}
diff --git a/libmailutils/url/dup.c b/libmailutils/url/dup.c
new file mode 100644
index 000000000..d9a738341
--- /dev/null
+++ b/libmailutils/url/dup.c
@@ -0,0 +1,56 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/util.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
+{
+ int rc;
+ mu_url_t url = calloc (1, sizeof (*url));
+
+ if (!url)
+ return ENOMEM;
+ url->name = strdup (old_url->name);
+ if (!url->name)
+ {
+ free (url);
+ return ENOMEM;
+ }
+
+ rc = mu_url_copy_hints (url, old_url);
+ if (rc)
+ {
+ mu_url_destroy (&url);
+ return rc;
+ }
+ *new_url = url;
+ return 0;
+}
diff --git a/libmailutils/url/expand.c b/libmailutils/url/expand.c
new file mode 100644
index 000000000..bb2ef9584
--- /dev/null
+++ b/libmailutils/url/expand.c
@@ -0,0 +1,216 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/util.h>
+#include <mailutils/errno.h>
+#include <mailutils/argcv.h>
+#include <mailutils/sys/url.h>
+
+/* Default mailbox path generator */
+static char *
+_url_path_default (const char *spooldir, const char *user, int unused)
+{
+ return mu_make_file_name (spooldir, user);
+}
+
+/* Hashed indexing */
+static char *
+_url_path_hashed (const char *spooldir, const char *user, int param)
+{
+ int i;
+ int ulen = strlen (user);
+ char *mbox;
+ unsigned hash;
+
+ if (param > ulen)
+ param = ulen;
+ for (i = 0, hash = 0; i < param; i++)
+ hash += user[i];
+
+ mbox = malloc (ulen + strlen (spooldir) + 5);
+ sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user);
+ return mbox;
+}
+
+static int transtab[] = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'b', 'c', 'd', 'e', 'f',
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
+ 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
+ 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e',
+ 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', 'b', 'c', 'd', 'e', 'f', 'g'
+};
+
+/* Forward Indexing */
+static char *
+_url_path_index (const char *spooldir, const char *iuser, int index_depth)
+{
+ const unsigned char* user = (const unsigned char*) iuser;
+ int i, ulen = strlen (iuser);
+ char *mbox, *p;
+
+ if (ulen == 0)
+ return NULL;
+
+ mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 2);
+ strcpy (mbox, spooldir);
+ p = mbox + strlen (mbox);
+ for (i = 0; i < index_depth && i < ulen; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[i] ];
+ }
+ for (; i < index_depth; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[ulen-1] ];
+ }
+ *p++ = '/';
+ strcpy (p, iuser);
+ return mbox;
+}
+
+/* Reverse Indexing */
+static char *
+_url_path_rev_index (const char *spooldir, const char *iuser, int index_depth)
+{
+ const unsigned char* user = (const unsigned char*) iuser;
+ int i, ulen = strlen (iuser);
+ char *mbox, *p;
+
+ if (ulen == 0)
+ return NULL;
+
+ mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1);
+ strcpy (mbox, spooldir);
+ p = mbox + strlen (mbox);
+ for (i = 0; i < index_depth && i < ulen; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[ulen - i - 1] ];
+ }
+ for (; i < index_depth; i++)
+ {
+ *p++ = '/';
+ *p++ = transtab[ user[0] ];
+ }
+ *p++ = '/';
+ strcpy (p, iuser);
+ return mbox;
+}
+
+static int
+rmselector (const char *p, void *data MU_ARG_UNUSED)
+{
+ return strncmp (p, "type=", 5) == 0
+ || strncmp (p, "user=", 5) == 0
+ || strncmp (p, "param=", 6) == 0;
+}
+
+int
+mu_url_expand_path (mu_url_t url)
+{
+ size_t i;
+ char *user = NULL;
+ int param = 0;
+ char *p;
+ char *(*fun) (const char *, const char *, int) = _url_path_default;
+
+ if (url->fvcount == 0)
+ return 0;
+
+ for (i = 0; i < url->fvcount; i++)
+ {
+ p = url->fvpairs[i];
+ if (strncmp (p, "type=", 5) == 0)
+ {
+ char *type = p + 5;
+
+ if (strcmp (type, "hash") == 0)
+ fun = _url_path_hashed;
+ else if (strcmp (type, "index") == 0)
+ fun = _url_path_index;
+ else if (strcmp (type, "rev-index") == 0)
+ fun = _url_path_rev_index;
+ else
+ return MU_ERR_NOENT;
+ }
+ else if (strncmp (p, "user=", 5) == 0)
+ {
+ user = p + 5;
+ }
+ else if (strncmp (p, "param=", 6) == 0)
+ {
+ param = strtoul (p + 6, NULL, 0);
+ }
+ }
+
+ if (user)
+ {
+ char *p = fun (url->path, user, param);
+ if (p)
+ {
+ free (url->path);
+ url->path = p;
+ }
+ mu_argcv_remove (&url->fvcount, &url->fvpairs, rmselector, NULL);
+ }
+ else
+ return MU_ERR_NOENT;
+
+ return 0;
+}
+
diff --git a/libmailutils/url/flag.c b/libmailutils/url/flag.c
new file mode 100644
index 000000000..bf06f6884
--- /dev/null
+++ b/libmailutils/url/flag.c
@@ -0,0 +1,40 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_get_flags (mu_url_t url, int *pf)
+{
+ if (!url || !pf)
+ return EINVAL;
+ *pf = url->flags;
+ return 0;
+}
+
+int
+mu_url_has_flag (mu_url_t url, int flags)
+{
+ if (!url)
+ return 0;
+ return url->flags & flags;
+}
diff --git a/libmailutils/url/get-auth.c b/libmailutils/url/get-auth.c
new file mode 100644
index 000000000..b9650a53c
--- /dev/null
+++ b/libmailutils/url/get-auth.c
@@ -0,0 +1,3 @@
+#define URL_PART auth
+#include "accessor.h"
+
diff --git a/libmailutils/url/get-host.c b/libmailutils/url/get-host.c
new file mode 100644
index 000000000..6de6b564e
--- /dev/null
+++ b/libmailutils/url/get-host.c
@@ -0,0 +1,2 @@
+#define URL_PART host
+#include "accessor.h"
diff --git a/libmailutils/url/get-param.c b/libmailutils/url/get-param.c
new file mode 100644
index 000000000..c2be8234b
--- /dev/null
+++ b/libmailutils/url/get-param.c
@@ -0,0 +1,131 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/argcv.h>
+#include <mailutils/sys/url.h>
+
+/* field-value pairs accessors */
+int
+mu_url_sget_fvpairs (const mu_url_t url, size_t *fvc, char ***fvp)
+{
+ if (url == NULL)
+ return EINVAL;
+ /* FIXME: no _get_fvpairs method, but the method stuff needs to be rewritten
+ anyway */
+ *fvc = url->fvcount;
+ *fvp = url->fvpairs;
+ return 0;
+}
+
+int
+mu_url_sget_param (const mu_url_t url, const char *param, const char **val)
+{
+ size_t fvc;
+ char **fvp;
+ int status = mu_url_sget_fvpairs (url, &fvc, &fvp);
+
+ if (status)
+ return status;
+
+ if (fvc)
+ {
+ size_t i;
+
+ for (i = 0; i < fvc; i++)
+ {
+ const char *p;
+ char *q;
+
+ for (p = param, q = fvp[i]; *p && *q && *p == *q; p++, q++)
+ ;
+ if (*p == 0)
+ {
+ if (*q == 0)
+ {
+ if (val)
+ *val = q;
+ return 0;
+ }
+ else if (*q == '=')
+ {
+ if (val)
+ *val = q + 1;
+ return 0;
+ }
+ }
+ }
+ }
+
+ return MU_ERR_NOENT;
+}
+
+int
+mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp)
+{
+ size_t fvc, i;
+ char **fvp;
+ char **fvcopy;
+
+ int rc = mu_url_sget_fvpairs (url, &fvc, &fvp);
+ if (rc)
+ return rc;
+
+ fvcopy = calloc (fvc + 1, sizeof (fvcopy[0]));
+ if (!fvcopy)
+ return errno;
+ for (i = 0; i < fvc; i++)
+ {
+ if (!(fvcopy[i] = strdup (fvp[i])))
+ {
+ mu_argcv_free (i, fvcopy);
+ return errno;
+ }
+ }
+ fvcopy[i] = NULL;
+ *pfvc = fvc;
+ *pfvp = fvcopy;
+ return 0;
+}
+
+int
+mu_url_aget_param (const mu_url_t url, const char *param, char **val)
+{
+ const char *s;
+ int status = mu_url_sget_param (url, param, &s);
+
+ if (status == 0)
+ {
+ *val = strdup (s);
+ if (!*val)
+ status = ENOMEM;
+ }
+ return status;
+}
+
diff --git a/libmailutils/url/get-path.c b/libmailutils/url/get-path.c
new file mode 100644
index 000000000..3f906b9b1
--- /dev/null
+++ b/libmailutils/url/get-path.c
@@ -0,0 +1,2 @@
+#define URL_PART path
+#include "accessor.h"
diff --git a/libmailutils/url/get-portstr.c b/libmailutils/url/get-portstr.c
new file mode 100644
index 000000000..9b211bf8f
--- /dev/null
+++ b/libmailutils/url/get-portstr.c
@@ -0,0 +1,2 @@
+#define URL_PART portstr
+#include "accessor.h"
diff --git a/libmailutils/url/get-query.c b/libmailutils/url/get-query.c
new file mode 100644
index 000000000..cf74922da
--- /dev/null
+++ b/libmailutils/url/get-query.c
@@ -0,0 +1,72 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/argcv.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
+{
+ if (url == NULL)
+ return EINVAL;
+ /* See FIXME below */
+ *qc = url->qargc;
+ *qv = url->qargv;
+ return 0;
+}
+
+int
+mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv)
+{
+ size_t qargc, i;
+ char **qargv;
+ char **qcopy;
+
+ int rc = mu_url_sget_fvpairs (url, &qargc, &qargv);
+ if (rc)
+ return rc;
+
+ qcopy = calloc (qargc + 1, sizeof (qcopy[0]));
+ if (!qcopy)
+ return errno;
+ for (i = 0; i < qargc; i++)
+ {
+ if (!(qcopy[i] = strdup (qargv[i])))
+ {
+ mu_argcv_free (i, qcopy);
+ return errno;
+ }
+ }
+ qcopy[i] = NULL;
+ *qc = qargc;
+ *qv = qcopy;
+ return 0;
+}
+
diff --git a/libmailutils/url/get-scheme.c b/libmailutils/url/get-scheme.c
new file mode 100644
index 000000000..983902ea4
--- /dev/null
+++ b/libmailutils/url/get-scheme.c
@@ -0,0 +1,2 @@
+#define URL_PART scheme
+#include "accessor.h"
diff --git a/libmailutils/url/get-secret.c b/libmailutils/url/get-secret.c
new file mode 100644
index 000000000..34fb2291b
--- /dev/null
+++ b/libmailutils/url/get-secret.c
@@ -0,0 +1,44 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/secret.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret)
+{
+ if (url->_get_secret)
+ return url->_get_secret (url, psecret);
+ if (url->secret == NULL)
+ return MU_ERR_NOENT;
+ mu_secret_ref (url->secret);
+ *psecret = url->secret;
+ return 0;
+}
diff --git a/libmailutils/url/get-user.c b/libmailutils/url/get-user.c
new file mode 100644
index 000000000..5a3ab791f
--- /dev/null
+++ b/libmailutils/url/get-user.c
@@ -0,0 +1,2 @@
+#define URL_PART user
+#include "accessor.h"
diff --git a/libmailutils/url/match.c b/libmailutils/url/match.c
new file mode 100644
index 000000000..4932f4577
--- /dev/null
+++ b/libmailutils/url/match.c
@@ -0,0 +1,102 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/cstr.h>
+#include <mailutils/sys/url.h>
+
+#define is_wildcard(s) ((s)[0] == '*' && s[1] == 0)
+
+#define WEIGHT_SCHEME 3
+#define WEIGHT_USER 4
+#define WEIGHT_HOST 2
+#define WEIGHT_PORT 1
+
+int
+mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *pwc)
+{
+ int wcnt = 0;
+
+ if (is_wildcard (ticket->scheme))
+ wcnt += WEIGHT_SCHEME;
+ else if (mu_c_strcasecmp (ticket->scheme, url->scheme))
+ return 0;
+
+ if (ticket->flags & MU_URL_HOST)
+ {
+ if (is_wildcard (ticket->host))
+ wcnt += WEIGHT_HOST;
+ else if (url->flags & MU_URL_HOST)
+ {
+ if (mu_c_strcasecmp (ticket->host, url->host))
+ /* FIXME: Compare IP addresses */
+ return 0;
+ }
+ else
+ return 0;
+ }
+ else
+ wcnt += WEIGHT_HOST;
+
+ if (ticket->flags & MU_URL_PORT)
+ {
+ if (is_wildcard (ticket->portstr))
+ wcnt += WEIGHT_PORT;
+ else if (url->port & MU_URL_PORT)
+ {
+ if (ticket->port != url->port)
+ return 0;
+ else
+ wcnt += WEIGHT_PORT;
+ }
+ }
+ else
+ wcnt += WEIGHT_PORT;
+
+ if (ticket->flags & MU_URL_USER)
+ {
+ if (is_wildcard (ticket->user))
+ wcnt += WEIGHT_USER;
+
+ /* If ticket has a user or pass, but url doesn't, that's OK, we were
+ looking for this info. But if url does have a user/pass, it
+ must match the ticket. */
+ else if (url->flags & MU_URL_USER)
+ {
+ if (strcmp (ticket->user, url->user))
+ return 0;
+ }
+ }
+ else
+ wcnt += WEIGHT_USER;
+
+ /* Guess it matches. */
+ if (pwc)
+ *pwc = wcnt;
+ return 1;
+}
diff --git a/libmailutils/url/port.c b/libmailutils/url/port.c
new file mode 100644
index 000000000..88b7dd136
--- /dev/null
+++ b/libmailutils/url/port.c
@@ -0,0 +1,53 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/cstr.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_get_port (const mu_url_t url, unsigned *pport)
+{
+ if (url == NULL)
+ return EINVAL;
+ if (url->_get_port)
+ return url->_get_port (url, pport);
+ *pport = url->port;
+ return 0;
+}
+
+int
+mu_url_is_same_port (mu_url_t url1, mu_url_t url2)
+{
+ unsigned p1 = 0, p2 = 0;
+
+ mu_url_get_port (url1, &p1);
+ mu_url_get_port (url2, &p2);
+ return (p1 == p2);
+}
+
diff --git a/libmailutils/url/scheme.c b/libmailutils/url/scheme.c
new file mode 100644
index 000000000..e68fa9192
--- /dev/null
+++ b/libmailutils/url/scheme.c
@@ -0,0 +1,55 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/cstr.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_set_scheme (mu_url_t url, const char *scheme)
+{
+ char *p;
+ if (!url || !scheme)
+ return EINVAL;
+ p = realloc (url->scheme, strlen (scheme) + 1);
+ if (!p)
+ return ENOMEM;
+ strcpy (url->scheme, scheme);
+ return 0;
+}
+
+int
+mu_url_is_scheme (mu_url_t url, const char *scheme)
+{
+ if (url && scheme && url->scheme
+ && mu_c_strcasecmp (url->scheme, scheme) == 0)
+ return 1;
+
+ return 0;
+}
+
diff --git a/libmailutils/url/uplevel.c b/libmailutils/url/uplevel.c
new file mode 100644
index 000000000..749fe1fae
--- /dev/null
+++ b/libmailutils/url/uplevel.c
@@ -0,0 +1,71 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#include <mailutils/types.h>
+#include <mailutils/errno.h>
+#include <mailutils/sys/url.h>
+
+int
+mu_url_uplevel (mu_url_t url, mu_url_t *upurl)
+{
+ int rc;
+ char *p;
+ mu_url_t new_url;
+
+ if (url->_uplevel)
+ return url->_uplevel (url, upurl);
+
+ if (!url->path)
+ return MU_ERR_NOENT;
+ p = strrchr (url->path, '/');
+
+ rc = mu_url_dup (url, &new_url);
+ if (rc == 0)
+ {
+ if (!p || p == url->path)
+ {
+ free (new_url->path);
+ new_url->path = NULL;
+ }
+ else
+ {
+ size_t size = p - url->path;
+ new_url->path = realloc (new_url->path, size + 1);
+ if (!new_url->path)
+ {
+ mu_url_destroy (&new_url);
+ return ENOMEM;
+ }
+ memcpy (new_url->path, url->path, size);
+ new_url->path[size] = 0;
+ }
+ *upurl = new_url;
+ }
+ return rc;
+}
+
diff --git a/libmailutils/url/urlstr.c b/libmailutils/url/urlstr.c
new file mode 100644
index 000000000..31e5197f8
--- /dev/null
+++ b/libmailutils/url/urlstr.c
@@ -0,0 +1,31 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <mailutils/types.h>
+#include <mailutils/sys/url.h>
+
+const char *
+mu_url_to_string (const mu_url_t url)
+{
+ if (url == NULL || url->name == NULL)
+ return "";
+ return url->name;
+}

Return to:

Send suggestions and report system problems to the System administrator.