commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-412-gfb994e0


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-412-gfb994e0
Date: Fri, 28 Oct 2011 12:14:00 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=fb994e0a85011d050eb6e3e166018a5625118c20

The branch, master has been updated
       via  fb994e0a85011d050eb6e3e166018a5625118c20 (commit)
       via  02334735e86f1cfda6a2e07cfea9283e4fc88011 (commit)
       via  e9a329bfe70d903fb0a78007adaff6b565ddfc6b (commit)
      from  442711bcda49eeca667d15c509d200995379c832 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fb994e0a85011d050eb6e3e166018a5625118c20
Author: Sergey Poznyakoff <address@hidden>
Date:   Fri Oct 28 14:06:38 2011 +0300

    pop3d: configurable APOP file and safety criteria.
    
    * include/mailutils/dbm.h (mu_dbm_init)
    (mu_dbm_get_hint): New prototypes.
    * include/mailutils/util.h (mu_stpcpy)
    (mu_file_safety_compose): New prototypes.
    * libmailutils/string/Makefile.am (libstring_la_SOURCES): Add stpcpy.c
    * libmailutils/string/stpcpy.c: New file.
    * libmu_cfg/tls.c (cb2_safety_checks): Use mu_file_safety_compose.
    * libmu_dbm/create.c (mu_dbm_create): Use mu_dbm_init.
    * libmu_dbm/dbm.c (_mu_dbm_init): Rename mu_dbm_init. All uses changed.
    Use URL composing interface to create hints.
    * maidag/maidag.c (mu_dbm_get_hint): New function.
    * pop3d/pop3d.c (cb2_forward_file_checks): Use mu_file_safety_compose.
    (apop_database_name, apop_database_safety)
    (apop_database_safety_set): New variables.
    (pop3d_cfg_param) <apop-database-file>
    <apop-database-safety>: New configuration statements.
    (main) [ENABLE_DBM]: Initialize dbm safety criteria.
    * pop3d/apop.c (pop3d_apopuser): Use configured database name and
    safety flags, if set.
    * pop3d/pop3d.h [ENABLE_DBM] (APOP_PASSFILE): Add ".db" suffix.
    (apop_database_name, apop_database_safety)
    (apop_database_safety_set): New variables.

commit 02334735e86f1cfda6a2e07cfea9283e4fc88011
Author: Sergey Poznyakoff <address@hidden>
Date:   Fri Oct 28 13:21:25 2011 +0300

    New interface for composing URLs from parts.
    
    * include/mailutils/url.h (mu_url_sget_name)
    (mu_url_aget_name,mu_url_get_name)
    (mu_url_invalidate,mu_url_create_null)
    (mu_url_set_user,mu_url_set_path,mu_url_set_scheme)
    (mu_url_set_host,mu_url_set_port,mu_url_set_service)
    (mu_url_set_auth,mu_url_set_secret,mu_url_add_param)
    (mu_url_clear_param,mu_url_add_query,mu_url_clear_query): New
    prototypes.
    
    * libmailutils/tests/url-comp.at: New test case.
    * libmailutils/tests/url-comp.c: New test program.
    * libmailutils/tests/.gitignore: Update.
    * libmailutils/tests/Makefile.am: Add new files.
    * libmailutils/tests/testsuite.at: Add new tests.
    
    * libmailutils/url/Makefile.am: Add new files.
    * libmailutils/url/add-param.c: New file.
    * libmailutils/url/add-query.c: New file.
    * libmailutils/url/clr-param.c: New file.
    * libmailutils/url/clr-query.c: New file.
    * libmailutils/url/null.c: New file.
    * libmailutils/url/set-auth.c: New file.
    * libmailutils/url/set-host.c: New file.
    * libmailutils/url/set-path.c: New file.
    * libmailutils/url/set-port.c: New file.
    * libmailutils/url/set-scheme.c: New file.
    * libmailutils/url/set-secret.c: New file.
    * libmailutils/url/set-service.c: New file.
    * libmailutils/url/set-user.c: New file.
    * libmailutils/url/urlinv.c: New file.
    
    * libmailutils/url/create.c (mu_url_create_hint): Return EINVAL if
    purl is NULL.
    * libmailutils/url/scheme.c (mu_url_set_scheme): Remove. See set-scheme.c
    * libmailutils/url/urlstr.c (mu_url_sget_name)
    (mu_url_aget_name,mu_url_get_name): New functions.
    (mu_url_to_string): Rewrite using the above.
    
    * libmailutils/base/Makefile.am: Add fscompose.c
    * libmailutils/base/fscompose.c: New file.

commit e9a329bfe70d903fb0a78007adaff6b565ddfc6b
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Oct 27 13:30:12 2011 +0300

    Add testcases for file safety checking functions.
    
    * libmailutils/tests/fsaf.at: New testcase.
    * libmailutils/tests/fsaf.c: New file.
    * libmailutils/tests/.gitignore: Add fsaf
    * libmailutils/tests/Makefile.am: Likewise.
    * libmailutils/tests/testsuite.at: Include fsaf.at.

-----------------------------------------------------------------------

Summary of changes:
 include/mailutils/dbm.h                            |    6 +-
 include/mailutils/url.h                            |   22 +++-
 include/mailutils/util.h                           |    2 +
 libmailutils/base/Makefile.am                      |    1 +
 .../datumfree.c => libmailutils/base/fscompose.c   |   45 +++++--
 libmailutils/string/Makefile.am                    |    1 +
 libmailutils/{base/freeitem.c => string/stpcpy.c}  |   18 ++-
 libmailutils/tests/.gitignore                      |    2 +
 libmailutils/tests/Makefile.am                     |    4 +
 libmailutils/tests/fsaf.at                         |   82 +++++++++++
 .../tests/argcv.c => libmailutils/tests/fsaf.c     |   64 +++++----
 libmailutils/tests/testsuite.at                    |    2 +
 libmailutils/tests/url-comp.at                     |   72 +++++++++
 libmailutils/tests/url-comp.c                      |  147 +++++++++++++++++++
 libmailutils/url/Makefile.am                       |   14 ++
 libmailutils/url/{get-query.c => add-param.c}      |   64 +++++----
 libmailutils/url/{get-query.c => add-query.c}      |   64 +++++----
 libmailutils/url/{get-secret.c => clr-param.c}     |   24 ++--
 libmailutils/url/{get-secret.c => clr-query.c}     |   24 ++--
 libmailutils/url/create.c                          |    6 +-
 libmailutils/url/flag.c                            |    2 +-
 libmailutils/url/{flag.c => null.c}                |   24 ++--
 libmailutils/url/scheme.c                          |   13 --
 libmailutils/url/{dup.c => set-auth.c}             |   36 +++---
 libmailutils/url/{get-query.c => set-host.c}       |   65 +++++----
 libmailutils/url/{dup.c => set-path.c}             |   36 +++---
 libmailutils/url/{dup.c => set-port.c}             |   43 ++++---
 libmailutils/url/{scheme.c => set-scheme.c}        |   41 +++---
 libmailutils/url/{get-secret.c => set-secret.c}    |   27 +++--
 libmailutils/url/{get-query.c => set-service.c}    |   70 +++++----
 libmailutils/url/{dup.c => set-user.c}             |   36 +++---
 libmailutils/url/{urlstr.c => urlinv.c}            |   16 ++-
 libmailutils/url/urlstr.c                          |  151 +++++++++++++++++++-
 libmu_cfg/tls.c                                    |   59 ++------
 libmu_dbm/create.c                                 |    2 +-
 libmu_dbm/dbm.c                                    |   40 ++----
 maidag/maidag.c                                    |   39 +-----
 pop3d/apop.c                                       |   30 +++--
 pop3d/pop3d.c                                      |   51 +++++++
 pop3d/pop3d.h                                      |    5 +-
 40 files changed, 1007 insertions(+), 443 deletions(-)
 copy libmu_dbm/datumfree.c => libmailutils/base/fscompose.c (54%)
 copy libmailutils/{base/freeitem.c => string/stpcpy.c} (78%)
 create mode 100644 libmailutils/tests/fsaf.at
 copy libmu_compat/tests/argcv.c => libmailutils/tests/fsaf.c (50%)
 create mode 100644 libmailutils/tests/url-comp.at
 create mode 100644 libmailutils/tests/url-comp.c
 copy libmailutils/url/{get-query.c => add-param.c} (57%)
 copy libmailutils/url/{get-query.c => add-query.c} (57%)
 copy libmailutils/url/{get-secret.c => clr-param.c} (74%)
 copy libmailutils/url/{get-secret.c => clr-query.c} (74%)
 copy libmailutils/url/{flag.c => null.c} (80%)
 copy libmailutils/url/{dup.c => set-auth.c} (69%)
 copy libmailutils/url/{get-query.c => set-host.c} (59%)
 copy libmailutils/url/{dup.c => set-path.c} (69%)
 copy libmailutils/url/{dup.c => set-port.c} (63%)
 copy libmailutils/url/{scheme.c => set-scheme.c} (70%)
 copy libmailutils/url/{get-secret.c => set-secret.c} (72%)
 copy libmailutils/url/{get-query.c => set-service.c} (55%)
 copy libmailutils/url/{dup.c => set-user.c} (69%)
 copy libmailutils/url/{urlstr.c => urlinv.c} (79%)

diff --git a/include/mailutils/dbm.h b/include/mailutils/dbm.h
index 0d194f6..ab0d5c1 100644
--- a/include/mailutils/dbm.h
+++ b/include/mailutils/dbm.h
@@ -1,6 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2011 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
@@ -50,6 +49,9 @@ struct mu_dbm_impl
 
 extern mu_url_t mu_dbm_hint;
 
+void mu_dbm_init (void);
+mu_url_t mu_dbm_get_hint (void);
+
 int mu_dbm_register (struct mu_dbm_impl *impl);
 int mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db);
 int mu_dbm_create (char *name, mu_dbm_file_t *db);
diff --git a/include/mailutils/url.h b/include/mailutils/url.h
index c33dadc..513b767 100644
--- a/include/mailutils/url.h
+++ b/include/mailutils/url.h
@@ -80,6 +80,10 @@ int mu_url_has_flag (mu_url_t, int);
   
 void mu_url_destroy   (mu_url_t *);
 
+int mu_url_sget_name (const mu_url_t, const char **);
+int mu_url_aget_name (const mu_url_t, char **);
+int mu_url_get_name (const mu_url_t, char *, size_t, size_t *);
+  
 int mu_url_sget_scheme  (const mu_url_t, const char **);
 int mu_url_aget_scheme  (const mu_url_t, char **);  
 int mu_url_get_scheme  (const mu_url_t, char *, size_t, size_t *);
@@ -120,8 +124,6 @@ int mu_url_aget_param (const mu_url_t url, const char 
*param, char **val);
 int mu_url_expand_path (mu_url_t url);
 const char *mu_url_to_string   (const mu_url_t);
 
-int mu_url_set_scheme (mu_url_t url, const char *scheme);
-
 int mu_url_is_scheme   (mu_url_t, const char *scheme);
 
 int mu_url_is_same_scheme (mu_url_t, mu_url_t);
@@ -133,6 +135,22 @@ int mu_url_is_same_port   (mu_url_t, mu_url_t);
 int mu_url_matches_ticket   (mu_url_t ticket, mu_url_t url, int *wcn);  
 
 int mu_url_decode (mu_url_t url);
+
+int mu_url_invalidate (mu_url_t url);
+  
+int mu_url_create_null (mu_url_t *purl);
+int mu_url_set_user (mu_url_t url, const char *user);
+int mu_url_set_path (mu_url_t url, const char *path);
+int mu_url_set_scheme (mu_url_t url, const char *scheme);
+int mu_url_set_host (mu_url_t url, const char *host);
+int mu_url_set_port (mu_url_t url, unsigned port);
+int mu_url_set_service (mu_url_t url, const char *str);
+int mu_url_set_auth (mu_url_t url, const char *auth);
+int mu_url_set_secret (mu_url_t url, mu_secret_t secret);
+int mu_url_add_param (mu_url_t url, size_t pc, const char **pv);
+int mu_url_clear_param (mu_url_t url);
+int mu_url_add_query (mu_url_t url, size_t pc, const char **pv);
+int mu_url_clear_query (mu_url_t url);  
   
 #ifdef __cplusplus
 }
diff --git a/include/mailutils/util.h b/include/mailutils/util.h
index fcc11ac..d0ffd63 100644
--- a/include/mailutils/util.h
+++ b/include/mailutils/util.h
@@ -36,6 +36,7 @@ extern "C" {
 unsigned long mu_hex2ul (char hex);
 size_t mu_hexstr2ul (unsigned long* ul, const char* hex, size_t len);
 size_t mu_cpystr (char *dst, const char *src, size_t size);
+char *mu_stpcpy (char *p, char *q);
 int mu_string_unfold (char *text, size_t *plen);
 int mu_true_answer_p (const char *p);
 int mu_unre_set_regex (const char *str, int caseflag, char **errp);
@@ -225,6 +226,7 @@ int mu_file_safety_check (const char *filename, int mode,
                          mu_list_t idlist);
 int mu_file_safety_name_to_code (const char *name, int *pcode);
 int mu_file_safety_name_to_error (const char *name, int *pcode);  
+int mu_file_safety_compose (int *res, const char *name, int defval);
   
 #ifdef __cplusplus
 }
diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am
index 96ea2f8..5f41b0c 100644
--- a/libmailutils/base/Makefile.am
+++ b/libmailutils/base/Makefile.am
@@ -31,6 +31,7 @@ libbase_la_SOURCES = \
  fgetpwent.c\
  filename.c\
  freeitem.c\
+ fscompose.c\
  getcwd.c\
  getmaxfd.c\
  getpass.c\
diff --git a/libmu_dbm/datumfree.c b/libmailutils/base/fscompose.c
similarity index 54%
copy from libmu_dbm/datumfree.c
copy to libmailutils/base/fscompose.c
index c11db26..7af13ac 100644
--- a/libmu_dbm/datumfree.c
+++ b/libmailutils/base/fscompose.c
@@ -18,19 +18,46 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-#include <stdlib.h>
+#include <string.h>
 #include <mailutils/types.h>
-#include <mailutils/dbm.h>
+#include <mailutils/util.h>
+#include <mailutils/nls.h>
+#include <mailutils/error.h>
 #include <mailutils/errno.h>
-#include "mudbm.h"
 
-void
-mu_dbm_datum_free (struct mu_dbm_datum *datum)
+int
+mu_file_safety_compose (int *res, const char *name, int defval)
 {
-  if (datum && datum->mu_data &&
-      datum->mu_sys && datum->mu_sys->_dbm_datum_free)
+  int negate = 0;
+  int val;
+  
+  if (*name == '-')
     {
-      datum->mu_sys->_dbm_datum_free (datum);
-      datum->mu_data = NULL;
+      negate = 1;
+      name++;
     }
+  else if (*name == '+')
+    name++;
+
+  if (strcmp (name, "none") == 0)
+    {
+      *res = negate ? MU_FILE_SAFETY_ALL : MU_FILE_SAFETY_NONE;
+      return 0;
+    }
+  else if (strcmp (name, "all") == 0)
+    {
+      *res = negate ? MU_FILE_SAFETY_NONE : MU_FILE_SAFETY_ALL;
+      return 0;
+    }
+  else if (strcmp (name, "default") == 0)
+    val = defval;
+  else if (mu_file_safety_name_to_code (name, &val))
+    return MU_ERR_NOENT;
+
+  if (negate)
+    *res &= ~val;
+  else
+    *res |= val;
+  
+  return 0;
 }
diff --git a/libmailutils/string/Makefile.am b/libmailutils/string/Makefile.am
index 628787c..94db386 100644
--- a/libmailutils/string/Makefile.am
+++ b/libmailutils/string/Makefile.am
@@ -24,6 +24,7 @@ libstring_la_SOURCES = \
  cstrlower.c\
  cstrupper.c\
  hexstr.c\
+ stpcpy.c\
  strltrim.c\
  strskip.c\
  stripws.c\
diff --git a/libmailutils/base/freeitem.c b/libmailutils/string/stpcpy.c
similarity index 78%
copy from libmailutils/base/freeitem.c
copy to libmailutils/string/stpcpy.c
index 458fbef..dea4aad 100644
--- a/libmailutils/base/freeitem.c
+++ b/libmailutils/string/stpcpy.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2011 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
@@ -15,14 +15,18 @@
    Public License along with this library.  If not, see 
    <http://www.gnu.org/licenses/>. */
 
-#ifdef HAVE_CONFIG_H
+#if HAVE_CONFIG_H
 # include <config.h>
 #endif
-#include <stdlib.h>
 
-/* Default destroy_item function. */
-void
-mu_list_free_item (void *item)
+#include <string.h>
+#include <mailutils/util.h>
+
+char *
+mu_stpcpy (char *p, char *q)
 {
-  free (item);
+  if (q)
+    while ((*p = *q++))
+      p++;
+  return p;
 }
diff --git a/libmailutils/tests/.gitignore b/libmailutils/tests/.gitignore
index d01d4ad..0860f07 100644
--- a/libmailutils/tests/.gitignore
+++ b/libmailutils/tests/.gitignore
@@ -11,9 +11,11 @@ debugspec
 decode2047
 encode2047
 fltst
+fsaf
 listop
 mailcap
 prop
+url-comp
 url-parse
 wicket
 wsp
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 5c00873..66d83ca 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -46,10 +46,12 @@ noinst_PROGRAMS = \
  decode2047\
  encode2047\
  fltst\
+ fsaf\
  listop\
  mailcap\
  prop\
  tempfile\
+ url-comp\
  url-parse\
  wicket\
  wsp
@@ -70,6 +72,7 @@ TESTSUITE_AT = \
  decode2047.at\
  encode2047.at\
  fromflt.at\
+ fsaf.at\
  hdrflt.at\
  inline-comment.at\
  linecon.at\
@@ -78,6 +81,7 @@ TESTSUITE_AT = \
  prop.at\
  testsuite.at\
  url.at\
+ url-comp.at\
  wicket.at\
  wordsplit.at
 
diff --git a/libmailutils/tests/fsaf.at b/libmailutils/tests/fsaf.at
new file mode 100644
index 0000000..3d6b530
--- /dev/null
+++ b/libmailutils/tests/fsaf.at
@@ -0,0 +1,82 @@
+# This file is part of GNU Mailutils. -*- Autotest -*-
+# Copyright (C) 2011 Free Software Foundation, Inc.
+#
+# GNU Mailutils is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or (at
+# your option) any later version.
+#
+# GNU Mailutils 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>.
+
+AT_BANNER(File Safety)
+
+dnl ------------------------------------------------------------
+dnl FSAF(CRITERIA, CODE, [STDOUT = `'], [RUN-IF-FAIL],
+dnl      [RUN-IF-PASS], [NAME])
+dnl
+
+m4_pushdef([FSAFCODE],[
+AT_SETUP([m4_if([$6],,$1,$6)])
+AT_KEYWORDS([fsaf])
+AT_CHECK([
+$2
+fsaf $1 file
+],
+[0],
+[file: $3
+],
+[],
+[$4],
+[$5])
+AT_CLEANUP
+])
+
+m4_pushdef([FSAF],[
+FSAFCODE([$1],
+[> file
+m4_if([$2],,,[chmod $2 file])],[$3],[$4],[$5],[$6])
+])
+
+dnl ------------------------------------------------------------
+
+FSAF([], [], [Success], [], [], [default])
+
+FSAF([+awrfil], [o+w], [World writable file])
+FSAF([+gwrfil], [g+w], [Group writable file])
+
+FSAFCODE([+linkwrdir],
+[mkdir dir
+chmod g+w dir
+> data
+cd dir
+ln ../data file
+],
+[Linked file in a writable directory])
+
+FSAFCODE([+awrdir],
+[mkdir dir
+chmod o+w dir
+cd dir
+> file
+],
+[File in world writable directory])
+
+FSAFCODE([+gwrdir],
+[mkdir dir
+chmod g+w dir
+cd dir
+> file
+],
+[File in group writable directory])
+
+FSAF([+ardfil], [o+r], [World readable file])
+FSAF([+grdfil], [g+r], [Group readable file])
+
+m4_popdef([FSAFCODE])
+m4_popdef([FSAF])
diff --git a/libmu_compat/tests/argcv.c b/libmailutils/tests/fsaf.c
similarity index 50%
copy from libmu_compat/tests/argcv.c
copy to libmailutils/tests/fsaf.c
index 8817f94..d548744 100644
--- a/libmu_compat/tests/argcv.c
+++ b/libmailutils/tests/fsaf.c
@@ -1,6 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2005, 2007, 2009, 2010, 2011 Free Software Foundation,
-   Inc.
+   Copyright (C) 2011 Free Software Foundation, Inc.
 
    GNU Mailutils is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -17,44 +16,57 @@
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
-#endif 
+#endif
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <errno.h>
 #include <unistd.h>
-#define MU_ARCGV_DEPRECATED
-#include <mailutils/argcv.h>
+#include <mailutils/types.h>
+#include <mailutils/error.h>
 #include <mailutils/errno.h>
+#include <mailutils/util.h>
 
 int
 main (int argc, char **argv)
 {
-  char *delim = "";
-  char *comment = "#";
-  char buf[512];
+  int i;
+  int mode = MU_FILE_SAFETY_OWNER_MISMATCH, rc, m;
+  mu_list_t idlist;
+  uid_t uid;
+
+  if (argc == 1)
+    {
+      mu_error ("usage: %s [+-]mode... file...", argv[0]);
+      exit (1);
+    }
   
-  while (fgets (buf, sizeof buf, stdin))
+  rc = mu_list_create (&idlist);
+  if (rc)
     {
-      int status, c;
-      char **v;
-      char *s;
-
-      status = mu_argcv_get (buf, delim, comment, &c, &v);
-      if (status)
+      mu_error ("mu_list_create: %s", mu_strerror (rc));
+      exit (1);
+    }
+  uid = getuid ();
+  
+  for (i = 1; i < argc; i++)
+    {
+      if (argv[i][0] == '-' || argv[i][0] == '+')
        {
-         fprintf (stderr, "cannot parse: %s\n", mu_strerror (status));
-         continue;
+         rc = mu_file_safety_name_to_code (argv[i] + 1, &m);
+         if (rc)
+           {
+             mu_error ("%s: %s", argv[i], mu_strerror (rc));
+             exit (1);
+           }
+         if (argv[i][0] == '-')
+           mode &= ~m;
+         else
+           mode |= m;
        }
-      status = mu_argcv_string (c, v, &s);
-      if (status)
-       fprintf (stderr, "cannot create string: %s\n", mu_strerror (status));
       else
        {
-         printf ("%d: %s\n", c, s);
-         free (s);
+         rc = mu_file_safety_check (argv[i], mode, uid, idlist);
+         printf ("%s: %s\n", argv[i], mu_strerror (rc));
        }
-      mu_argcv_free (c, v);
-    } 
+    }
   exit (0);
 }
diff --git a/libmailutils/tests/testsuite.at b/libmailutils/tests/testsuite.at
index 31b0821..e29846b 100644
--- a/libmailutils/tests/testsuite.at
+++ b/libmailutils/tests/testsuite.at
@@ -58,6 +58,7 @@ m4_include([list.at])
 m4_include([address.at])
 m4_include([wordsplit.at])
 m4_include([url.at])
+m4_include([url-comp.at])
 m4_include([mailcap.at])
 m4_include([wicket.at])
 m4_include([prop.at])
@@ -77,3 +78,4 @@ m4_include([hdrflt.at])
 m4_include([linecon.at])
 m4_include([debugspec.at])
 
+m4_include([fsaf.at])
\ No newline at end of file
diff --git a/libmailutils/tests/url-comp.at b/libmailutils/tests/url-comp.at
new file mode 100644
index 0000000..e776e4b
--- /dev/null
+++ b/libmailutils/tests/url-comp.at
@@ -0,0 +1,72 @@
+# This file is part of GNU Mailutils. -*- Autotest -*-
+# Copyright (C) 2011 Free Software Foundation, Inc.
+#
+# GNU Mailutils is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or (at
+# your option) any later version.
+#
+# GNU Mailutils 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>.
+
+AT_BANNER(URL Composition)
+
+dnl ------------------------------------------------------------
+             1   2        3                4
+dnl URLCOMP(KW, ARGS, [STDOUT = `'], [STDERR = `'])
+dnl
+
+m4_pushdef([URLCOMP],[
+AT_SETUP([$2 => $3])
+AT_KEYWORDS([url-comp url-comp-$1])
+AT_CHECK([url-comp $2],
+[m4_if([$4],,0,1)],
+[m4_if([$3],,,[$3
+])],
+m4_if([$4],,,[url-comp: $4
+]))
+AT_CLEANUP
+])
+
+URLCOMP(0, [], [], [URL missing required parts])
+URLCOMP(1, [path=foo], [foo])
+URLCOMP(2, [scheme=file], [file://])
+URLCOMP(3, [scheme=file path=foo], [file://foo])
+URLCOMP(4, [scheme=smtp host=localhost port=587], [smtp://localhost:587])
+URLCOMP(5,
+        [scheme=smtp host=localhost port=587 param=strip-domain 
param=domain=example.com],
+        [smtp://localhost:587;strip-domain;domain=example.com])
+URLCOMP(6, [scheme=imap user=gray host=localhost path=INBOX],
+        [imap://address@hidden/INBOX])
+URLCOMP(7,
+        [scheme=imap user=gray pass=test host=localhost path=INBOX],
+       [imap://gray:address@hidden/INBOX])
+URLCOMP(8,     
+        [scheme=pop user=gray pass=test auth=+APOP host=localhost path=INBOX],
+       [pop://gray:***;address@hidden/INBOX])
+URLCOMP(9,
+        [scheme=prog path=/bin/mailman query=request query=list],
+        [prog:///bin/mailman?request&list])
+URLCOMP(10,
+        [scheme=prog path=/bin/mailman query=request query=list param=test],
+        [prog:///bin/mailman;test?request&list])
+URLCOMP(11,
+        [url=imap://address@hidden/INBOX path=],
+       [imap://address@hidden)
+URLCOMP(12,
+        [url=imap://address@hidden/INBOX path= user=],
+       [imap://localhost])
+URLCOMP(13,
+        [url='prog:///bin/mailman;test?request&list' query= param=],
+       [prog:///bin/mailman])
+URLCOMP(14,
+        [url=smtp://address@hidden/test host=],
+       [],
+       [URL missing required parts])
+       
+m4_popdef([URLCOMP])
\ No newline at end of file
diff --git a/libmailutils/tests/url-comp.c b/libmailutils/tests/url-comp.c
new file mode 100644
index 0000000..e1344ba
--- /dev/null
+++ b/libmailutils/tests/url-comp.c
@@ -0,0 +1,147 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   GNU Mailutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GNU Mailutils 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <mailutils/error.h>
+#include <mailutils/errno.h>
+#include <mailutils/url.h>
+#include <mailutils/secret.h>
+#include <mailutils/kwd.h>
+
+static const char *
+strval (const char *str)
+{
+  return str[0] ? str : NULL;
+}
+
+void
+usage (FILE *str, int code)
+{
+  fprintf (str, "usage: %s [url=URL] [OPTIONS]\n", mu_program_name);
+  exit (code);
+}
+
+int
+main (int argc, char **argv)
+{
+  int i = 1, rc;
+  mu_url_t url;
+  const char *arg;
+  
+  mu_set_program_name (argv[0]);
+  
+  if (argc > 1)
+    {
+      if (strcmp (argv[1], "help") == 0 ||
+         strcmp (argv[1], "--help") == 0 ||
+         strcmp (argv[1], "-h") == 0)
+       usage (stdout, 0);
+
+      if (strncmp (argv[1], "url=", 4) == 0)
+       {
+         MU_ASSERT (mu_url_create (&url, argv[1] + 4));
+         i = 2;
+       }
+    }
+
+  if (!url)
+    {
+      MU_ASSERT (mu_url_create_null (&url));
+      i = 1;
+    }
+  
+  for (; i < argc; i++)
+    {
+      if (strncmp (argv[i], "scheme=", 7) == 0)
+       {
+         MU_ASSERT (mu_url_set_scheme (url, strval (argv[i] + 7)));
+       }
+      else if (strncmp (argv[i], "user=", 5) == 0)
+       {
+         MU_ASSERT (mu_url_set_user (url, strval (argv[i] + 5)));
+       }
+      else if (strncmp (argv[i], "path=", 5) == 0)
+       {
+         MU_ASSERT (mu_url_set_path (url, strval (argv[i] + 5)));
+       }
+      else if (strncmp (argv[i], "host=", 5) == 0)
+       {
+         MU_ASSERT (mu_url_set_host (url, strval (argv[i] + 5)));
+       }
+      else if (strncmp (argv[i], "port=", 5) == 0)
+       {
+         MU_ASSERT (mu_url_set_port (url, atoi (argv[i] + 5)));
+       }
+      else if (strncmp (argv[i], "service=", 8) == 0)
+       {
+         MU_ASSERT (mu_url_set_service (url, strval (argv[i] + 8)));
+       }
+      else if (strncmp (argv[i], "auth=", 5) == 0)
+       {
+         MU_ASSERT (mu_url_set_auth (url, strval (argv[i] + 5)));
+       }
+      else if (strncmp (argv[i], "pass=", 5) == 0)
+       {
+         mu_secret_t secret;
+
+         arg = strval (argv[i] + 5);
+         if (arg)
+           {
+             MU_ASSERT (mu_secret_create (&secret, arg, strlen (arg)));
+           }
+         else
+           secret = NULL;
+         MU_ASSERT (mu_url_set_secret (url, secret));
+       }
+      else if (strncmp (argv[i], "param=", 6) == 0)
+       {
+         arg = strval (argv[i] + 6);
+         if (arg)
+           MU_ASSERT (mu_url_add_param (url, 1, (const char **)&arg));
+         else
+           MU_ASSERT (mu_url_clear_param (url));
+       }
+      else if (strncmp (argv[i], "query=", 6) == 0)
+       {
+         arg = strval (argv[i] + 6);
+         if (arg)
+           MU_ASSERT (mu_url_add_query (url, 1, (const char **)&arg));
+         else
+           MU_ASSERT (mu_url_clear_query (url));
+       }
+      else
+       {
+         mu_error ("unrecognized argument: %s", argv[i]);
+         return 1;
+       }
+    }
+                      
+  rc = mu_url_sget_name (url, &arg);
+  if (rc)
+    {
+      mu_error ("%s", mu_strerror (rc));
+      return 1;
+    }
+  
+
+  printf ("%s\n", arg);
+  return 0;
+}
diff --git a/libmailutils/url/Makefile.am b/libmailutils/url/Makefile.am
index 6f4a9c0..937f823 100644
--- a/libmailutils/url/Makefile.am
+++ b/libmailutils/url/Makefile.am
@@ -19,6 +19,10 @@ noinst_LTLIBRARIES = liburl.la
 
 liburl_la_SOURCES = \
  accessor.h\
+ add-param.c\
+ clr-param.c\
+ add-query.c\
+ clr-query.c\
  copy.c\
  create.c\
  decode.c\
@@ -36,9 +40,19 @@ liburl_la_SOURCES = \
  get-secret.c\
  get-user.c\
  match.c\
+ null.c\
  port.c\
  scheme.c\
+ set-auth.c\
+ set-host.c\
+ set-path.c\
+ set-port.c\
+ set-scheme.c\
+ set-secret.c\
+ set-service.c\
+ set-user.c\
  uplevel.c\
+ urlinv.c\
  urlstr.c
 
 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
diff --git a/libmailutils/url/get-query.c b/libmailutils/url/add-param.c
similarity index 57%
copy from libmailutils/url/get-query.c
copy to libmailutils/url/add-param.c
index 6d82d87..0bd0f43 100644
--- a/libmailutils/url/get-query.c
+++ b/libmailutils/url/add-param.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -28,45 +28,47 @@
 
 #include <mailutils/types.h>
 #include <mailutils/errno.h>
-#include <mailutils/argcv.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
+mu_url_add_param (mu_url_t url, size_t pc, const char **pv)
 {
-  if (url == NULL)
+  char **fv;
+  int i, j;
+    
+  if (!url)
     return EINVAL;
-  /* See FIXME below */
-  *qc = url->qargc;
-  *qv = url->qargv;
-  return 0;
-}
+  if (!pc || !pv)
+    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++)
+  fv = realloc (url->fvpairs,
+               sizeof (url->fvpairs[0]) * (url->fvcount + pc + 1));
+  if (!fv)
+    return ENOMEM;
+  url->fvpairs = fv;
+  for (i = url->fvcount, j = 0; j < pc; i++, j++)
     {
-      if (!(qcopy[i] = strdup (qargv[i])))
+      fv[i] = strdup (pv[j]);
+      if (!fv[i])
        {
-         mu_argcv_free (i, qcopy);
-         return errno;
+         /* Restore the status quo */
+         for (; j; j--)
+           free (fv[--i]);
+         if (url->fvcount)
+           fv[url->fvcount] = NULL;
+         else
+           {
+             free (url->fvpairs);
+             url->fvpairs = NULL;
+             url->fvcount = 0;
+           }
+         return ENOMEM;
        }
     }
-  qcopy[i] = NULL;
-  *qc = qargc;
-  *qv = qcopy;
+  fv[i] = NULL;
+  url->fvcount = i;
+  url->flags |= MU_URL_PARAM;
+  mu_url_invalidate (url);
   return 0;
 }
-
diff --git a/libmailutils/url/get-query.c b/libmailutils/url/add-query.c
similarity index 57%
copy from libmailutils/url/get-query.c
copy to libmailutils/url/add-query.c
index 6d82d87..8d810bb 100644
--- a/libmailutils/url/get-query.c
+++ b/libmailutils/url/add-query.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -28,45 +28,47 @@
 
 #include <mailutils/types.h>
 #include <mailutils/errno.h>
-#include <mailutils/argcv.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
+mu_url_add_query (mu_url_t url, size_t pc, const char **pv)
 {
-  if (url == NULL)
+  char **fv;
+  int i, j;
+    
+  if (!url)
     return EINVAL;
-  /* See FIXME below */
-  *qc = url->qargc;
-  *qv = url->qargv;
-  return 0;
-}
+  if (!pc || !pv)
+    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++)
+  fv = realloc (url->qargv,
+               sizeof (url->qargv[0]) * (url->qargc + pc + 1));
+  if (!fv)
+    return ENOMEM;
+  url->qargv = fv;
+  for (i = url->qargc, j = 0; j < pc; i++, j++)
     {
-      if (!(qcopy[i] = strdup (qargv[i])))
+      fv[i] = strdup (pv[j]);
+      if (!fv[i])
        {
-         mu_argcv_free (i, qcopy);
-         return errno;
+         /* Restore the status quo */
+         for (; j; j--)
+           free (fv[--i]);
+         if (url->qargc)
+           fv[url->qargc] = NULL;
+         else
+           {
+             free (url->qargv);
+             url->qargv = NULL;
+             url->qargc = 0;
+           }
+         return ENOMEM;
        }
     }
-  qcopy[i] = NULL;
-  *qc = qargc;
-  *qv = qcopy;
+  fv[i] = NULL;
+  url->qargc = i;
+  url->flags |= MU_URL_QUERY;
+  mu_url_invalidate (url);
   return 0;
 }
-
diff --git a/libmailutils/url/get-secret.c b/libmailutils/url/clr-param.c
similarity index 74%
copy from libmailutils/url/get-secret.c
copy to libmailutils/url/clr-param.c
index 7057315..0feb80f 100644
--- a/libmailutils/url/get-secret.c
+++ b/libmailutils/url/clr-param.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -28,17 +28,23 @@
 
 #include <mailutils/types.h>
 #include <mailutils/errno.h>
-#include <mailutils/secret.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret)
+mu_url_clear_param (mu_url_t url)
 {
-  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;
+  int i;
+  
+  if (!url)
+    return EINVAL;
+
+  for (i = 0; i < url->fvcount; i++)
+    free (url->fvpairs[i]);
+  free (url->fvpairs);
+  url->fvpairs = NULL;
+  url->fvcount = 0;
+  url->flags &= ~MU_URL_PARAM;
+  mu_url_invalidate (url);
   return 0;
 }
diff --git a/libmailutils/url/get-secret.c b/libmailutils/url/clr-query.c
similarity index 74%
copy from libmailutils/url/get-secret.c
copy to libmailutils/url/clr-query.c
index 7057315..186cb25 100644
--- a/libmailutils/url/get-secret.c
+++ b/libmailutils/url/clr-query.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -28,17 +28,23 @@
 
 #include <mailutils/types.h>
 #include <mailutils/errno.h>
-#include <mailutils/secret.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret)
+mu_url_clear_query (mu_url_t url)
 {
-  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;
+  int i;
+  
+  if (!url)
+    return EINVAL;
+
+  for (i = 0; i < url->qargc; i++)
+    free (url->qargv[i]);
+  free (url->qargv);
+  url->qargv = NULL;
+  url->qargc = 0;
+  url->flags &= ~MU_URL_QUERY;
+  mu_url_invalidate (url);
   return 0;
 }
diff --git a/libmailutils/url/create.c b/libmailutils/url/create.c
index 130b7a2..d6b01be 100644
--- a/libmailutils/url/create.c
+++ b/libmailutils/url/create.c
@@ -532,7 +532,11 @@ mu_url_create_hint (mu_url_t *purl, const char *str, int 
flags,
 {
   int rc;
   struct mu_url_ctx ctx;
-  mu_url_t url = calloc (1, sizeof (*url));
+  mu_url_t url;
+
+  if (!purl)
+    return EINVAL;
+  url = calloc (1, sizeof (*url));
   if (url == NULL)
     return ENOMEM;
   url->name = strdup (str);
diff --git a/libmailutils/url/flag.c b/libmailutils/url/flag.c
index 586c881..4387948 100644
--- a/libmailutils/url/flag.c
+++ b/libmailutils/url/flag.c
@@ -27,7 +27,7 @@ mu_url_get_flags (mu_url_t url, int *pf)
 {
   if (!url || !pf)
     return EINVAL;
-  *pf = url->flags;
+  *pf = url->flags; 
   return 0;
 }
 
diff --git a/libmailutils/url/flag.c b/libmailutils/url/null.c
similarity index 80%
copy from libmailutils/url/flag.c
copy to libmailutils/url/null.c
index 586c881..471f194 100644
--- a/libmailutils/url/flag.c
+++ b/libmailutils/url/null.c
@@ -18,23 +18,21 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-
+#include <stdlib.h>
 #include <errno.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_get_flags (mu_url_t url, int *pf)
+mu_url_create_null (mu_url_t *purl)
 {
-  if (!url || !pf)
-    return EINVAL;
-  *pf = url->flags;
-  return 0;
-}
+  mu_url_t url;
 
-int
-mu_url_has_flag (mu_url_t url, int flags)
-{
-  if (!url)
-    return 0;
-  return url->flags & flags;
+  if (!purl)
+    return EINVAL;  
+  url = calloc (1, sizeof (*url));
+  if (url == NULL)
+    return ENOMEM;
+  *purl = url;
+  return 0;
 }
diff --git a/libmailutils/url/scheme.c b/libmailutils/url/scheme.c
index fa9fbf1..ec42f70 100644
--- a/libmailutils/url/scheme.c
+++ b/libmailutils/url/scheme.c
@@ -31,19 +31,6 @@
 #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 
diff --git a/libmailutils/url/dup.c b/libmailutils/url/set-auth.c
similarity index 69%
copy from libmailutils/url/dup.c
copy to libmailutils/url/set-auth.c
index 5fb0288..b4e9e61 100644
--- a/libmailutils/url/dup.c
+++ b/libmailutils/url/set-auth.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -27,30 +27,32 @@
 #endif
 
 #include <mailutils/types.h>
-#include <mailutils/util.h>
+#include <mailutils/errno.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
+mu_url_set_auth (mu_url_t url, const char *auth)
 {
-  int rc;
-  mu_url_t url = calloc (1, sizeof (*url));
-
+  char *copy;
+  
   if (!url)
-    return ENOMEM;
-  url->name = strdup (old_url->name);
-  if (!url->name)
+    return EINVAL;
+  if (auth)
     {
-      free (url);
-      return ENOMEM;
+      copy = strdup (auth);
+      if (!copy)
+       return ENOMEM;
+      url->flags |= MU_URL_AUTH;
     }
-  
-  rc = mu_url_copy_hints (url, old_url);
-  if (rc)
+  else
     {
-      mu_url_destroy (&url);
-      return rc;
+      url->flags &= ~MU_URL_AUTH;
+      copy = NULL;
     }
-  *new_url = url;
+  free (url->auth);
+  url->auth = copy;
+  url->_get_auth = NULL;
+  mu_url_invalidate (url);
   return 0;
 }
diff --git a/libmailutils/url/get-query.c b/libmailutils/url/set-host.c
similarity index 59%
copy from libmailutils/url/get-query.c
copy to libmailutils/url/set-host.c
index 6d82d87..6cb21f6 100644
--- a/libmailutils/url/get-query.c
+++ b/libmailutils/url/set-host.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -28,45 +28,46 @@
 
 #include <mailutils/types.h>
 #include <mailutils/errno.h>
-#include <mailutils/argcv.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
+mu_url_set_host (mu_url_t url, const char *host)
 {
-  if (url == NULL)
+  char *copy;
+  
+  if (!url)
     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 (host)
     {
-      if (!(qcopy[i] = strdup (qargv[i])))
+      size_t len;
+      int flag = MU_URL_HOST;
+      
+      len = strlen (host);
+      if (len == 0)
+       return EINVAL;
+      if (host[0] == '[' && host[len-1] == ']')
        {
-         mu_argcv_free (i, qcopy);
-         return errno;
+         flag |= MU_URL_IPV6;
+         host++;
+         len -= 2;
        }
+      
+      copy = malloc (len + 1);
+      if (!copy)
+       return ENOMEM;
+      memcpy (copy, host, len);
+      copy[len] = 0;
+      url->flags |= flag;
     }
-  qcopy[i] = NULL;
-  *qc = qargc;
-  *qv = qcopy;
+  else
+    {
+      url->flags &= ~(MU_URL_HOST|MU_URL_IPV6);
+      copy = NULL;
+    }
+  url->_get_host = NULL;
+  free (url->host);
+  url->host = copy;
+  mu_url_invalidate (url);
   return 0;
 }
-
diff --git a/libmailutils/url/dup.c b/libmailutils/url/set-path.c
similarity index 69%
copy from libmailutils/url/dup.c
copy to libmailutils/url/set-path.c
index 5fb0288..686dfad 100644
--- a/libmailutils/url/dup.c
+++ b/libmailutils/url/set-path.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -27,30 +27,32 @@
 #endif
 
 #include <mailutils/types.h>
-#include <mailutils/util.h>
+#include <mailutils/errno.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
+mu_url_set_path (mu_url_t url, const char *path)
 {
-  int rc;
-  mu_url_t url = calloc (1, sizeof (*url));
-
+  char *copy;
+  
   if (!url)
-    return ENOMEM;
-  url->name = strdup (old_url->name);
-  if (!url->name)
+    return EINVAL;
+  if (path)
     {
-      free (url);
-      return ENOMEM;
+      copy = strdup (path);
+      if (!copy)
+       return ENOMEM;
+      url->flags |= MU_URL_PATH;
     }
-  
-  rc = mu_url_copy_hints (url, old_url);
-  if (rc)
+  else
     {
-      mu_url_destroy (&url);
-      return rc;
+      url->flags &= ~MU_URL_PATH;
+      copy = NULL;
     }
-  *new_url = url;
+  free (url->path);
+  url->path = copy;
+  url->_get_path = NULL;
+  mu_url_invalidate (url);
   return 0;
 }
diff --git a/libmailutils/url/dup.c b/libmailutils/url/set-port.c
similarity index 63%
copy from libmailutils/url/dup.c
copy to libmailutils/url/set-port.c
index 5fb0288..6549b72 100644
--- a/libmailutils/url/dup.c
+++ b/libmailutils/url/set-port.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -20,6 +20,7 @@
 #endif
 
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #ifdef HAVE_STRINGS_H
@@ -27,30 +28,38 @@
 #endif
 
 #include <mailutils/types.h>
-#include <mailutils/util.h>
+#include <mailutils/errno.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
+mu_url_set_port (mu_url_t url, unsigned port)
 {
-  int rc;
-  mu_url_t url = calloc (1, sizeof (*url));
-
+  char *copy;
+  
   if (!url)
-    return ENOMEM;
-  url->name = strdup (old_url->name);
-  if (!url->name)
+    return EINVAL;
+  if (port)
     {
-      free (url);
-      return ENOMEM;
+      char nbuf[128];
+      snprintf (nbuf, sizeof nbuf, "%u", port);
+      copy = strdup (nbuf);
+      if (!copy)
+       return ENOMEM;
+      url->flags |= MU_URL_PORT;
     }
-  
-  rc = mu_url_copy_hints (url, old_url);
-  if (rc)
+  else
     {
-      mu_url_destroy (&url);
-      return rc;
+      copy = NULL;
+      url->flags &= ~MU_URL_PORT;
     }
-  *new_url = url;
+  url->_get_port = NULL;
+  url->_get_portstr = NULL;
+  free (url->portstr);
+  url->port = port;
+  url->portstr = copy;
+  mu_url_invalidate (url);
   return 0;
 }
+
+  
diff --git a/libmailutils/url/scheme.c b/libmailutils/url/set-scheme.c
similarity index 70%
copy from libmailutils/url/scheme.c
copy to libmailutils/url/set-scheme.c
index fa9fbf1..2e8ed13 100644
--- a/libmailutils/url/scheme.c
+++ b/libmailutils/url/set-scheme.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -27,29 +27,32 @@
 #endif
 
 #include <mailutils/types.h>
-#include <mailutils/cstr.h>
+#include <mailutils/errno.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
 mu_url_set_scheme (mu_url_t url, const char *scheme)
 {
-  char *p;
-  if (!url || !scheme)
+  char *copy;
+  
+  if (!url)
     return EINVAL;
-  p = realloc (url->scheme, strlen (scheme) + 1);
-  if (!p)
-    return ENOMEM;
-  strcpy (url->scheme, scheme);
+  if (scheme)
+    {
+      copy = strdup (scheme);
+      if (!copy)
+       return ENOMEM;
+      url->flags |= MU_URL_SCHEME;
+    }
+  else
+    {
+      url->flags &= ~MU_URL_SCHEME;
+      copy = NULL;
+    }
+  free (url->scheme);
+  url->scheme = copy;
+  url->_get_scheme = NULL;
+  mu_url_invalidate (url);
   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/get-secret.c b/libmailutils/url/set-secret.c
similarity index 72%
copy from libmailutils/url/get-secret.c
copy to libmailutils/url/set-secret.c
index 7057315..30af285 100644
--- a/libmailutils/url/get-secret.c
+++ b/libmailutils/url/set-secret.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -28,17 +28,26 @@
 
 #include <mailutils/types.h>
 #include <mailutils/errno.h>
-#include <mailutils/secret.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
+#include <mailutils/secret.h>
 
 int
-mu_url_get_secret (const mu_url_t url, mu_secret_t *psecret)
+mu_url_set_secret (mu_url_t url, mu_secret_t secret)
 {
-  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;
+  if (!url)
+    return EINVAL;
+  if (secret)
+    {
+      url->flags |= MU_URL_SECRET;
+    }
+  else
+    {
+      url->flags &= ~MU_URL_SECRET;
+    }
+  mu_secret_destroy (&url->secret);
+  url->secret = secret;
+  url->_get_secret = NULL;
+  mu_url_invalidate (url);
   return 0;
 }
diff --git a/libmailutils/url/get-query.c b/libmailutils/url/set-service.c
similarity index 55%
copy from libmailutils/url/get-query.c
copy to libmailutils/url/set-service.c
index 6d82d87..f570977 100644
--- a/libmailutils/url/get-query.c
+++ b/libmailutils/url/set-service.c
@@ -22,51 +22,59 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <netdb.h>
+#include <arpa/inet.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>
+#include <mailutils/url.h>
 
 int
-mu_url_sget_query (const mu_url_t url, size_t *qc, char ***qv)
+mu_url_set_service (mu_url_t url, const char *str)
 {
-  if (url == NULL)
+  unsigned port;
+  char *copy;
+  
+  if (!url)
     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 (str)
     {
-      if (!(qcopy[i] = strdup (qargv[i])))
+      unsigned long n;
+      char *p;
+      
+      n = strtoul (str, &p, 10);
+      if (*p)
        {
-         mu_argcv_free (i, qcopy);
-         return errno;
+         /* FIXME: 1. This assumes MU_URL_PARSE_PORTSRV. */
+         /* FIXME: 2. Another proto? */
+         struct servent *sp = getservbyname (str, "tcp");
+         if (!sp)
+           return MU_ERR_TCP_NO_PORT; /*FIXME: Error code?*/
+         port = ntohs (sp->s_port);
        }
+      else if (n > USHRT_MAX)
+       return ERANGE;
+
+      copy = strdup (str);
+      if (!copy)
+       return ENOMEM;
+      url->flags |= MU_URL_PORT;
     }
-  qcopy[i] = NULL;
-  *qc = qargc;
-  *qv = qcopy;
+  else
+    {
+      copy = NULL;
+      port = 0;
+      url->flags &= ~MU_URL_PORT;
+    }
+  url->_get_port = NULL;
+  url->_get_portstr = NULL;
+  free (url->portstr);
+  url->port = port;
+  url->portstr = copy;
+  mu_url_invalidate (url);
   return 0;
 }
-
diff --git a/libmailutils/url/dup.c b/libmailutils/url/set-user.c
similarity index 69%
copy from libmailutils/url/dup.c
copy to libmailutils/url/set-user.c
index 5fb0288..8494f43 100644
--- a/libmailutils/url/dup.c
+++ b/libmailutils/url/set-user.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   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
@@ -27,30 +27,32 @@
 #endif
 
 #include <mailutils/types.h>
-#include <mailutils/util.h>
+#include <mailutils/errno.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/url.h>
 
 int
-mu_url_dup (mu_url_t old_url, mu_url_t *new_url)
+mu_url_set_user (mu_url_t url, const char *user)
 {
-  int rc;
-  mu_url_t url = calloc (1, sizeof (*url));
-
+  char *copy;
+  
   if (!url)
-    return ENOMEM;
-  url->name = strdup (old_url->name);
-  if (!url->name)
+    return EINVAL;
+  if (user)
     {
-      free (url);
-      return ENOMEM;
+      copy = strdup (user);
+      if (!copy)
+       return ENOMEM;
+      url->flags |= MU_URL_USER;
     }
-  
-  rc = mu_url_copy_hints (url, old_url);
-  if (rc)
+  else
     {
-      mu_url_destroy (&url);
-      return rc;
+      url->flags &= ~MU_URL_USER;
+      copy = NULL;
     }
-  *new_url = url;
+  free (url->user);
+  url->user = copy;
+  url->_get_user = NULL;
+  mu_url_invalidate (url);
   return 0;
 }
diff --git a/libmailutils/url/urlstr.c b/libmailutils/url/urlinv.c
similarity index 79%
copy from libmailutils/url/urlstr.c
copy to libmailutils/url/urlinv.c
index f2faa81..c4f8113 100644
--- a/libmailutils/url/urlstr.c
+++ b/libmailutils/url/urlinv.c
@@ -1,5 +1,5 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2011 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
@@ -19,13 +19,15 @@
 # include <config.h>
 #endif
 #include <stdlib.h>
-#include <mailutils/types.h>
+#include <errno.h>
 #include <mailutils/sys/url.h>
 
-const char *
-mu_url_to_string (const mu_url_t url)
+int
+mu_url_invalidate (mu_url_t url)
 {
-  if (url == NULL || url->name == NULL)
-    return "";
-  return url->name;
+  if (!url)
+    return EINVAL;
+  free (url->name);
+  url->name = NULL;
+  return 0;
 }
diff --git a/libmailutils/url/urlstr.c b/libmailutils/url/urlstr.c
index f2faa81..48a7805 100644
--- a/libmailutils/url/urlstr.c
+++ b/libmailutils/url/urlstr.c
@@ -19,13 +19,160 @@
 # include <config.h>
 #endif
 #include <stdlib.h>
+#include <string.h>
 #include <mailutils/types.h>
 #include <mailutils/sys/url.h>
+#include <mailutils/errno.h>
+#include <mailutils/util.h>
+#include <mailutils/opool.h>
+
+#define AUTH_PFX ";AUTH="
+
+static int
+url_reconstruct_to_pool (mu_url_t url, mu_opool_t pool)
+{
+  if (url->flags & MU_URL_SCHEME)
+    {
+      int i;
+      
+      mu_opool_append (pool, url->scheme, strlen (url->scheme));
+      mu_opool_append (pool, "://", 3);
+
+      if (url->flags & MU_URL_USER)
+       mu_opool_append (pool, url->user, strlen (url->user));
+      if (url->flags & MU_URL_SECRET)
+       mu_opool_append (pool, ":***", 4); /* FIXME: How about 
MU_URL_PARSE_HIDEPASS? */
+      if (url->flags & MU_URL_AUTH)
+       {
+         mu_opool_append (pool, AUTH_PFX, sizeof AUTH_PFX - 1);
+         mu_opool_append (pool, url->auth, strlen (url->auth));
+       }
+      if (url->flags & MU_URL_HOST)
+       {
+         if (url->flags & (MU_URL_USER|MU_URL_SECRET|MU_URL_AUTH))
+           mu_opool_append_char (pool, '@');
+         mu_opool_append (pool, url->host, strlen (url->host));
+         if (url->flags & MU_URL_PORT)
+           {
+             mu_opool_append_char (pool, ':');
+             mu_opool_append (pool, url->portstr, strlen (url->portstr));
+           }
+       }
+      else if (url->flags & (MU_URL_USER|MU_URL_SECRET|MU_URL_AUTH))
+       return MU_ERR_URL_MISS_PARTS;
+      
+      if (url->flags & MU_URL_PATH)
+       {
+         if (url->flags & MU_URL_HOST)
+           mu_opool_append_char (pool, '/');
+         mu_opool_append (pool, url->path, strlen (url->path));
+       }
+      
+      if (url->flags & MU_URL_PARAM)
+       {
+         for (i = 0; i < url->fvcount; i++)
+           {
+             mu_opool_append_char (pool, ';');
+             mu_opool_append (pool, url->fvpairs[i],
+                              strlen (url->fvpairs[i]));
+           }
+       }
+      if (url->flags & MU_URL_QUERY)
+       {
+         mu_opool_append_char (pool, '?');
+         mu_opool_append (pool, url->qargv[0],
+                          strlen (url->qargv[0]));
+         for (i = 1; i < url->qargc; i++)
+           {
+             mu_opool_append_char (pool, '&');
+             mu_opool_append (pool, url->qargv[i],
+                              strlen (url->qargv[i]));
+           }
+       }
+      return 0;
+    }
+  else if (url->flags == MU_URL_PATH)
+    {
+      mu_opool_append (pool, url->path, strlen (url->path));
+      return 0;
+    }
+  return MU_ERR_URL_MISS_PARTS;
+}
+
+int
+mu_url_sget_name (const mu_url_t url, const char **retptr)
+{
+  if (!url)
+    return EINVAL;
+  if (!url->name)
+    {
+      mu_opool_t pool;
+      int rc;
+      char *ptr, *newname;
+      size_t size;
+      
+      rc = mu_opool_create (&pool, 0);
+      if (rc)
+       return rc;
+      rc = url_reconstruct_to_pool (url, pool);
+      if (rc)
+       {
+         mu_opool_destroy (&pool);
+         return rc;
+       }
+      ptr = mu_opool_finish (pool, &size);       
+
+      newname = realloc (url->name, size + 1);
+      if (!newname)
+       {
+         mu_opool_destroy (&pool);
+         return ENOMEM;
+       }
+      memcpy (newname, ptr, size);
+      newname[size] = 0;
+      url->name = newname;
+      mu_opool_destroy (&pool);
+    }
+  if (retptr)
+    *retptr = url->name;
+  return 0;
+}
+
+int
+mu_url_aget_name (const mu_url_t url, char **ret)
+{
+  char *s;
+  const char *ptr;
+  int rc = mu_url_sget_name (url, &ptr);
+  if (rc)
+    return rc;
+  s = strdup (ptr);
+  if (!s)
+    return errno;
+  *ret = s;
+  return 0;
+}
+
+int
+mu_url_get_name (const mu_url_t url, char *buf, size_t size, size_t *n)
+{
+  size_t i;
+  const char *ptr;
+  int rc = mu_url_sget_name (url, &ptr);
+  if (rc)
+    return rc;
+  i = mu_cpystr (buf, ptr, size);
+  if (n)
+    *n = i;
+  return 0;
+}
 
 const char *
 mu_url_to_string (const mu_url_t url)
 {
-  if (url == NULL || url->name == NULL)
+  const char *ptr;
+  
+  if (mu_url_sget_name (url, &ptr))
     return "";
-  return url->name;
+  return ptr;
 }
diff --git a/libmu_cfg/tls.c b/libmu_cfg/tls.c
index 37afc10..c40586b 100644
--- a/libmu_cfg/tls.c
+++ b/libmu_cfg/tls.c
@@ -47,58 +47,25 @@ static struct mu_tls_module_config tls_settings = {
     SSL_CA_FILE_CHECKS
 };
 
-
 static int
 cb2_safety_checks (const char *name, void *data)
 {
-  int negate = 0;
-  int val;
-  int *res = data;
+  int defval;
   
-  if (*name == '-')
-    {
-      negate = 1;
-      name++;
-    }
-  else if (*name == '+')
-    name++;
-
-  if (strcmp (name, "none") == 0)
-    {
-      *res = negate ? MU_FILE_SAFETY_ALL : MU_FILE_SAFETY_NONE;
-      return 0;
-    }
-  else if (strcmp (name, "all") == 0)
-    {
-      *res = negate ? MU_FILE_SAFETY_NONE : MU_FILE_SAFETY_ALL;
-      return 0;
-    }
-  else if (strcmp (name, "default") == 0)
-    {
-      if (data == &tls_settings.ssl_key)
-       val = SSL_KEY_FILE_CHECKS;
-      else if (data == &tls_settings.ssl_cert)
-       val = SSL_CERT_FILE_CHECKS;
-      else if (data == &tls_settings.ssl_cafile)
-       val = SSL_CA_FILE_CHECKS;
-      else
-       {
-         mu_error (_("INTERNAL ERROR at %s:%d: unknown default value?"),
-                   __FILE__, __LINE__);
-         val = MU_FILE_SAFETY_ALL;
-       }
-    }
-  else if (mu_file_safety_name_to_code (name, &val))
+  if (data == &tls_settings.ssl_key)
+    defval = SSL_KEY_FILE_CHECKS;
+  else if (data == &tls_settings.ssl_cert)
+    defval = SSL_CERT_FILE_CHECKS;
+  else if (data == &tls_settings.ssl_cafile)
+    defval = SSL_CA_FILE_CHECKS;
+  else
     {
-      mu_error (_("unknown keyword: %s"), name);
-      return 0;
+      mu_error (_("INTERNAL ERROR at %s:%d: unknown default value?"),
+               __FILE__, __LINE__);
+      defval = MU_FILE_SAFETY_ALL;
     }
-
-  if (negate)
-    *res &= ~val;
-  else
-    *res |= val;
-  
+  if (mu_file_safety_compose (data, name, defval))
+    mu_error (_("unknown keyword: %s"), name);
   return 0;
 }
 
diff --git a/libmu_dbm/create.c b/libmu_dbm/create.c
index c1915a7..dec1801 100644
--- a/libmu_dbm/create.c
+++ b/libmu_dbm/create.c
@@ -35,7 +35,7 @@ mu_dbm_create (char *name, mu_dbm_file_t *db)
   int rc;
   mu_url_t url;
 
-  _mu_dbm_init ();
+  mu_dbm_init ();
   rc = mu_url_create_hint (&url, name, 0, mu_dbm_hint);
   if (rc)
     return rc;
diff --git a/libmu_dbm/dbm.c b/libmu_dbm/dbm.c
index e09cbbc..794affb 100644
--- a/libmu_dbm/dbm.c
+++ b/libmu_dbm/dbm.c
@@ -54,7 +54,7 @@ _implist_cmp (const void *a, const void *b)
 }
 
 void
-_mu_dbm_init ()
+mu_dbm_init ()
 {
   int rc;
 
@@ -86,42 +86,32 @@ _mu_dbm_init ()
   if (!mu_dbm_hint)
     {
       struct mu_dbm_impl *impl;
-      char *urlbuf;
-      
-      rc = mu_list_get (implist, 0, (void**) &impl);
-      if (rc)
+
+      if ((rc = mu_list_get (implist, 0, (void**) &impl)) ||
+         (rc = mu_url_create_null (&mu_dbm_hint)) ||
+         (rc = mu_url_set_scheme (mu_dbm_hint, impl->_dbm_name)))
        {
          mu_error (_("cannot initialize DBM hint: %s"),
                    mu_strerror (rc));
          abort ();
        }
-      urlbuf = malloc (strlen (impl->_dbm_name) + 4);
-      if (urlbuf)
-       {
-         strcpy (urlbuf, impl->_dbm_name);
-         strcat (urlbuf, "://");
-         rc = mu_url_create (&mu_dbm_hint, urlbuf);
-         free (urlbuf);
-       }
-      else
-       rc = ENOMEM;
-         
-      if (rc)
-       {
-         mu_error (_("cannot initialize DBM hint: %s"),
-                     mu_strerror (rc));
-         abort ();
-       }
     }
 }
 
+mu_url_t
+mu_dbm_get_hint ()
+{
+  mu_dbm_init ();
+  return mu_dbm_hint;
+}
+
 int
 mu_dbm_register (struct mu_dbm_impl *impl)
 {
   int rc;
   struct mu_dbm_impl *ptr;
 
-  _mu_dbm_init ();
+  mu_dbm_init ();
   ptr = calloc (1, sizeof (*ptr));
   if (!ptr)
     return ENOMEM;
@@ -151,7 +141,7 @@ mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db)
   int safety_flags = 0;
   uid_t owner_uid = getuid ();
 
-  _mu_dbm_init ();
+  mu_dbm_init ();
   
   mu_url_get_flags (url, &flags);
   if ((flags & (MU_URL_HOST | MU_URL_PATH)) == (MU_URL_HOST | MU_URL_PATH))
@@ -260,6 +250,6 @@ mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db)
 int
 mu_dbm_impl_iterator (mu_iterator_t *itr)
 {
-  _mu_dbm_init ();
+  mu_dbm_init ();
   return mu_list_get_iterator (implist, itr);
 }
diff --git a/maidag/maidag.c b/maidag/maidag.c
index 9faa36d..eee6d83 100644
--- a/maidag/maidag.c
+++ b/maidag/maidag.c
@@ -336,47 +336,16 @@ cb_group (void *data, mu_config_value_t *arg)
 static int
 cb2_forward_file_checks (const char *name, void *data)
 {
-  int val;
-  int negate = 0;
-  
-  if (*name == '-')
-    {
-      negate = 1;
-      name++;
-    }
-  else if (*name == '+')
-    name++;
-
-  if (strcmp (name, "none") == 0)
-    {
-      forward_file_checks = negate ? MU_FILE_SAFETY_ALL : MU_FILE_SAFETY_NONE;
-      return 0;
-    }
-  else if (strcmp (name, "all") == 0)
-    {
-      forward_file_checks = negate ? MU_FILE_SAFETY_NONE : MU_FILE_SAFETY_ALL;
-      return 0;
-    }
-  else if (strcmp (name, "default") == 0)
-    forward_file_checks = FORWARD_FILE_PERM_CHECK;
-  else if (mu_file_safety_name_to_code (name, &val))
-    {
-      mu_error (_("unknown keyword: %s"), name);
-      return 0;
-    }
-
-  if (negate)
-    forward_file_checks &= ~val;
-  else
-    forward_file_checks |= val;
-
+  if (mu_file_safety_compose (data, name, FORWARD_FILE_PERM_CHECK))
+    mu_error (_("unknown keyword: %s"), name);
   return 0;
 }
 
 static int
 cb_forward_file_checks (void *data, mu_config_value_t *arg)
 {
-  return mu_cfg_string_value_cb (arg, cb2_forward_file_checks, data);
+  return mu_cfg_string_value_cb (arg, cb2_forward_file_checks,
+                                &forward_file_checks);
 }
 
 static int
diff --git a/pop3d/apop.c b/pop3d/apop.c
index 7a2697f..ac9fbd7 100644
--- a/pop3d/apop.c
+++ b/pop3d/apop.c
@@ -42,27 +42,30 @@ char *
 pop3d_apopuser (const char *user)
 {
   char *password = NULL;
+  int rc;
   
 #ifdef ENABLE_DBM
   {
     size_t len;
     mu_dbm_file_t db;
     struct mu_dbm_datum key, data;
-    int rc;
 
-    rc = mu_dbm_create (APOP_PASSFILE, &db);
+    rc = mu_dbm_create (apop_database_name, &db);
     if (rc)
       {
        mu_diag_output (MU_DIAG_ERROR, _("unable to create APOP db"));
        return NULL;
       }
 
+    if (apop_database_safety_set)
+      mu_dbm_safety_set_flags (db, apop_database_safety);
+    
     rc = mu_dbm_safety_check (db);
     if (rc)
       {
        mu_diag_output (MU_DIAG_ERROR,
                        _("APOP file %s fails safety check: %s"),
-                       APOP_PASSFILE, mu_strerror (rc));
+                       apop_database_name, mu_strerror (rc));
        mu_dbm_destroy (&db);
        return NULL;
       }
@@ -115,20 +118,21 @@ pop3d_apopuser (const char *user)
     size_t ulen;
     FILE *apop_file;
 
-    /* FIXME */    
-/*     if (mu_check_perm (APOP_PASSFILE, 0600)) */
-/*       { */
-/*     mu_diag_output (MU_DIAG_INFO, */
-/*                     _("bad permissions on APOP password file")); */
-/*     return NULL; */
-/*     } */
-
-    apop_file = fopen (APOP_PASSFILE, "r");
+    rc = mu_file_safety_check (apop_database_name, apop_database_safety,
+                              apop_database_uid, NULL);
+    if (rc)
+      {
+       mu_diag_output (MU_DIAG_ERROR,
+                       _("APOP file %s fails safety check: %s"),
+                       apop_database_name, mu_strerror (rc));
+       return NULL;
+      }
+    apop_file = fopen (apop_database_name, "r");
     if (apop_file == NULL)
       {
        mu_diag_output (MU_DIAG_INFO,
                        _("unable to open APOP password file %s: %s"),
-                       APOP_PASSFILE, mu_strerror (errno));
+                       apop_database_name, mu_strerror (errno));
        return NULL;
       }
 
diff --git a/pop3d/pop3d.c b/pop3d/pop3d.c
index 5652b9d..4a15b38 100644
--- a/pop3d/pop3d.c
+++ b/pop3d/pop3d.c
@@ -31,6 +31,9 @@ int pop3d_transcript;
 int debug_mode;
 int tls_required;
 int pop3d_xlines;
+char *apop_database_name = APOP_PASSFILE;
+int apop_database_safety;
+int apop_database_safety_set;
 
 #ifdef WITH_TLS
 int tls_available;
@@ -77,6 +80,22 @@ cb_bulletin_source (void *data, mu_config_value_t *val)
   return 0;
 }
 
+static int
+cb2_file_safety_checks (const char *name, void *data)
+{
+  if (mu_file_safety_compose (data, name, MU_FILE_SAFETY_ALL))
+    mu_error (_("unknown keyword: %s"), name);
+  return 0;
+}
+
+static int
+cb_apop_safety_checks (void *data, mu_config_value_t *arg)
+{
+  apop_database_safety_set = 1;
+  return mu_cfg_string_value_cb (arg, cb2_file_safety_checks,
+                                &apop_database_safety);
+}
+
 #ifdef ENABLE_DBM
 static int
 cb_bulletin_db (void *data, mu_config_value_t *val)
@@ -98,6 +117,24 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
     N_("Delete expired messages upon closing the mailbox.") },
   { "scan-lines", mu_cfg_bool, &pop3d_xlines, 0, NULL,
     N_("Output the number of lines in the message in its scan listing.") },
+  { "apop-database-file", mu_cfg_string, &apop_database_name, 0, NULL,
+    N_("set APOP database file name or URL") },
+  { "apop-database-safety", mu_cfg_callback, NULL, 0, cb_apop_safety_checks,
+    N_("Configure safety checks for APOP database files.  Argument is a list 
or "
+       "sequence of check names optionally prefixed with '+' to enable or "
+       "'-' to disable the corresponding check.  Valid check names are:\n"
+       "\n"
+       "  none          disable all checks\n"
+       "  all           enable all checks\n"
+       "  gwrfil        forbid group writable files\n"
+       "  awrfil        forbid world writable files\n"
+       "  grdfil        forbid group readable files\n"
+       "  ardfil        forbid world writable files\n"
+       "  linkwrdir     forbid symbolic links in group or world writable 
directories\n"
+       "  gwrdir        forbid files in group writable directories\n"
+       "  awrdir        forbid files in world writable directories\n"),
+    N_("arg: list") },  
+    
 #ifdef WITH_TLS
   { "tls-required", mu_cfg_bool, &tls_required, 0, NULL,
      N_("Always require STLS before entering authentication phase.") },
@@ -303,6 +340,16 @@ pop3d_alloc_die ()
   pop3d_abquit (ERR_NO_MEM);
 }
 
+#ifdef ENABLE_DBM
+static void
+set_dbm_safety ()
+{
+  mu_url_t hints = mu_dbm_get_hint ();
+  const char *param[] = { "+all" };
+  mu_url_add_param (hints, 1, param);
+}
+#endif
+
 int
 main (int argc, char **argv)
 {
@@ -341,6 +388,10 @@ main (int argc, char **argv)
 
   mu_log_syslog = 1;
   manlock_mandatory_locking = 1;
+
+#ifdef ENABLE_DBM
+  set_dbm_safety ();
+#endif
   
   if (mu_app_init (&argp, pop3d_argp_capa, pop3d_cfg_param, 
                   argc, argv, 0, NULL, server))
diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h
index 833eb7f..0696c51 100644
--- a/pop3d/pop3d.h
+++ b/pop3d/pop3d.h
@@ -36,7 +36,7 @@
 #define APOP_PASSFILE_NAME "apop"
 
 #ifdef ENABLE_DBM
-# define APOP_PASSFILE SYSCONFDIR "/" APOP_PASSFILE_NAME
+# define APOP_PASSFILE SYSCONFDIR "/" APOP_PASSFILE_NAME ".db"
 # define ENABLE_LOGIN_DELAY
 #else
 # define APOP_PASSFILE SYSCONFDIR "/" APOP_PASSFILE_NAME ".passwd"
@@ -197,6 +197,9 @@ extern unsigned int idle_timeout;
 extern int pop3d_transcript;
 extern size_t pop3d_output_bufsize;
 extern int pop3d_xlines;
+extern char *apop_database_name;
+extern int apop_database_safety;
+extern int apop_database_safety_set;
 
 extern pop3d_command_handler_t pop3d_find_command (const char *name);
 


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]