Added ~-expansion in mountpoints. - susmb - mounting of SMB/CIFS shares via FUSE
 (HTM) git clone git://git.codemadness.org/susmb
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 846c8eb554047188b01591d9404325e1bf413e39
 (DIR) parent 64313aed26f8c03e48d817d01affe47eb2df5a1e
 (HTM) Author: Geoff Johnstone <qwerty@acm.org>
       Date:   Sat, 13 Mar 2010 14:55:24 +0000
       
       Added ~-expansion in mountpoints.
       
       Diffstat:
         M README                              |       3 +++
         M conffile.c                          |      53 ++++++++++++++++++++++++++++++
         M usmb.c                              |       2 ++
         M usmb.conf                           |       4 +++-
         M utils.c                             |      51 ++++++++++++++++++++++++++++---
         M utils.h                             |       9 +++++++--
       
       6 files changed, 114 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/README b/README
       @@ -13,6 +13,9 @@ a compilation problem on 64-bit platforms.
        Nigel Smith (Email me at <firstname>.<surname>.name) contributed the
        port to Samba 3.2.
        
       +Michal Suchanek (Email hramrach at centrum dot cz) contributed the
       +initial implementation of ~-expansion in mountpoints.
       +
        
        Introduction
        ------------
 (DIR) diff --git a/conffile.c b/conffile.c
       @@ -23,6 +23,7 @@
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
       +#include <pwd.h>
        #include <unistd.h>
        #include "utils.h"
        #include "xml.h"
       @@ -120,6 +121,57 @@ static bool do_xpath_text (xmlXPathContextPtr ctx,
        }
        
        
       +// Expand ~ in *mountpoint.
       +static bool expand_tilde (char **mountpoint)
       +{
       +  assert (NULL != mountpoint);
       +  assert (NULL != *mountpoint);
       +
       +  if ('~' != **mountpoint)
       +    return true;
       +
       +  // Extract the username.
       +  char * const username = (*mountpoint) + 1;
       +  char * const end = strchr (username, '/');
       +
       +  const char *dir = NULL;
       +
       +  if (('\0' == *username) || (end == username))  // No username => use HOME.
       +  {
       +    dir = getenv ("HOME");
       +  }
       +  else  // Else look up the user's home directory.
       +  {
       +    if (NULL != end)
       +      *end = '\0';
       +
       +    struct passwd * const pwd = getpwnam (username);
       +    if (NULL != pwd)
       +      dir = pwd->pw_dir;
       +
       +    if (NULL != end)
       +      *end = '/';
       +  }
       +
       +  if (NULL == dir)
       +  {
       +    fputs ("Failed to expand tilde in mount point.\n", stderr);
       +    return false;
       +  }
       +
       +  char *result;
       +  if (!baprintf (&result, "%s%s", dir, (NULL == end) ? "" : end))
       +  {
       +    perror ("Failed to expand tilde in mount point");
       +    return false;
       +  }
       +
       +  free (*mountpoint);
       +  *mountpoint = result;
       +  return true;
       +}
       +
       +
        bool conffile_get_mount (const char *filename, const char *key,
                                 char **server, char **share,
                                 char **mountpoint, char **options,
       @@ -147,6 +199,7 @@ bool conffile_get_mount (const char *filename, const char *key,
            if (!do_xpath_text (ctx, "mount", key, "server", server)) break;
            if (!do_xpath_text (ctx, "mount", key, "share", share)) break;
            if (!do_xpath_text (ctx, "mount", key, "mountpoint", mountpoint)) break;
       +    if (!expand_tilde (mountpoint)) break;
            (void)do_xpath_text (ctx, "mount", key, "options", options);
        
            if (!snprintf (xp, sizeof (xp), "/usmbconfig/mount[@id='%s']", key)) break;
 (DIR) diff --git a/usmb.c b/usmb.c
       @@ -311,6 +311,8 @@ int main (int argc, char **argv)
                                   &domain, &username, &password))
            return EXIT_FAILURE;
        
       +  DEBUG (fprintf (stderr, "Mountpoint: %s\n", mountpoint));
       +
          if (umount)
          {
            execlp ("fusermount", "fusermount", "-u", mountpoint, NULL);
 (DIR) diff --git a/usmb.conf b/usmb.conf
       @@ -51,7 +51,9 @@
          <mount id="music" credentials="cred2">
            <server>winbox</server>
            <share>music</share>
       -    <mountpoint>/tmp/music</mountpoint>
       +
       +    <!-- You can use ~/xyz or ~user/xyz for the mountpoint. -->
       +    <mountpoint>~/music</mountpoint>
            <options>allow_root</options>
          </mount>
        
 (DIR) diff --git a/utils.c b/utils.c
       @@ -17,6 +17,7 @@
        #include "config.h"
        #include <assert.h>
        #include <errno.h>
       +#include <limits.h>
        #include <stdarg.h>
        #include <stddef.h>
        #include <stdio.h>
       @@ -146,9 +147,6 @@ bool bsnprintf (char *str, size_t size, const char *format, ...)
          va_list ap;
          bool ret;
        
       -  assert (str);
       -  assert (format);
       -
          va_start (ap, format);
          ret = bvsnprintf (str, size, format, ap);
          va_end (ap);
       @@ -161,11 +159,54 @@ bool bvsnprintf (char *str, size_t size, const char *format, va_list ap)
        {
          int ret;
        
       -  assert (str);
       -  assert (format);
       +  assert (NULL != str);
       +  assert (NULL != format);
        
          ret = vsnprintf (str, size, format, ap);
        
          return ((ret >= 0) && ((size_t)ret < size));
        }
        
       +
       +bool baprintf (char **out, const char *format, ...)
       +{
       +  va_list ap;
       +  bool ret;
       +
       +  va_start (ap, format);
       +  ret = bvaprintf (out, format, ap);
       +  va_end (ap);
       +
       +  return ret;
       +}
       +
       +
       +bool bvaprintf (char **out, const char *format, va_list ap)
       +{
       +  assert (NULL != out);
       +  assert (NULL != format);
       +  *out = NULL;
       +
       +  int bytes = vsnprintf (NULL, 0, format, ap);
       +  if ((1 > bytes) || (INT_MAX == bytes))
       +    return false;
       +
       +  ++bytes;  // '\0'.
       +
       +  if (bytes != (int)(size_t)bytes)
       +    return false;
       +
       +  *out = malloc ((size_t)bytes);
       +  if (NULL == *out)
       +    return false;
       +
       +  if (!bvsnprintf (*out, bytes, format, ap))
       +  {
       +    free (*out);
       +    *out = NULL;
       +    return false;
       +  }
       +
       +  return true;
       +}
       +
 (DIR) diff --git a/utils.h b/utils.h
       @@ -36,7 +36,12 @@
          void free_errno (const void *ptr);
          void xfree_errno (const void *ptr);
          bool bsnprintf (char *str, size_t size, const char *format, ...)
       -    __attribute__ ((format (printf, 3, 4)));
       -  bool bvsnprintf (char *str, size_t size, const char *format, va_list ap);
       +    __attribute__ ((format (printf, 3, 4))) MUSTCHECK;
       +  bool bvsnprintf (char *str, size_t size,
       +                   const char *format,
       +                   va_list ap) MUSTCHECK;
       +  bool baprintf (char **out, const char *format, ...)
       +    __attribute__ ((format (printf, 2, 3))) MUSTCHECK;
       +  bool bvaprintf (char **out, const char *format, va_list ap) MUSTCHECK;
        
        #endif