Fix st_nlink for directories. Added free_errno() and xfree_errno(). Fix returned errno when free (url) follows the Samba call. Added UNUSED; removed (void)variable. - 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 bd037226cf4a14330a38b1370ed42b33618edb5c
 (DIR) parent 2d2b162d712d698357ae550c630545734f8543fb
 (HTM) Author: Geoff Johnstone <geoffSHEEP.johnstoneFROG@googlemail.com>
       Date:   Wed, 25 Jun 2008 22:53:53 +0100
       
       Fix st_nlink for directories.
       Added free_errno() and xfree_errno().
       Fix returned errno when free (url) follows the Samba call.
       Added UNUSED; removed (void)variable.
       
       Diffstat:
         M Makefile                            |       3 ++-
         M usmb.c                              |      13 +++++--------
         M usmb_dir.c                          |      13 ++++---------
         M usmb_file.c                         |     102 ++++++++++++++++++++++---------
         M utils.c                             |      17 +++++++++++++++++
         M utils.h                             |       2 ++
         M xml.c                               |       6 ++++--
       
       7 files changed, 106 insertions(+), 50 deletions(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       @@ -23,7 +23,8 @@ BINDIR = $(PREFIX)/bin
        
        CFLAGS += -Wall -Wextra -Werror -std=c99 -pedantic -O \
                  -I$(SAMBA)/include -D_BSD_SOURCE -DFUSE_USE_VERSION=26 \
       -          -DHAVE_UTIME_H -DMUSTCHECK='__attribute__ ((warn_unused_result))'
       +          -DHAVE_UTIME_H -DMUSTCHECK='__attribute__ ((warn_unused_result))' \
       +          -DUNUSED='__attribute__ ((unused))'
        
        LDLIBS = -lsmbclient
        LDFLAGS = -L$(SAMBA)/lib
 (DIR) diff --git a/usmb.c b/usmb.c
       @@ -57,11 +57,10 @@ static inline void do_strncpy (char *to, const char *from, int tolen)
        }
        
        
       -static void auth_fn (const char *srv, const char *shr, char *wg, int wglen,
       -                     char *un, int unlen, char *pw, int pwlen)
       +static void auth_fn (const char *srv UNUSED, const char *shr UNUSED,
       +                     char *wg, int wglen, char *un, int unlen,
       +                     char *pw, int pwlen)
        {
       -  (void)srv;
       -  (void)shr;
          DEBUG (fprintf (stderr, "Authenticating for \\\\%s\\%s\n", srv, shr));
          DEBUG (fprintf (stderr, "Domain: %s; User: %s; Password:%s\n",
                          domain, username, password));
       @@ -118,17 +117,15 @@ static int usmb_statfs (const char *path, struct statvfs *vfs)
        #endif
        
        
       -static void * usmb_init (struct fuse_conn_info *conn)
       +static void * usmb_init (struct fuse_conn_info *conn UNUSED)
        {
          DEBUG (fputs ("usmb_init()\n", stderr));
       -  (void)conn;
          return NULL;
        }
        
        
       -static void usmb_destroy (void *unused)
       +static void usmb_destroy (void *unused UNUSED)
        {
       -  (void)unused;
          DEBUG (fputs ("usmb_destroy()\n", stderr));
        }
        
 (DIR) diff --git a/usmb_dir.c b/usmb_dir.c
       @@ -73,12 +73,9 @@ int usmb_opendir (const char *dirname, struct fuse_file_info *fi)
        }
        
        
       -int usmb_readdir (const char *path, void *h, fuse_fill_dir_t filler,
       -                  off_t offset, struct fuse_file_info *fi)
       +int usmb_readdir (const char *path UNUSED, void *h, fuse_fill_dir_t filler,
       +                  off_t offset UNUSED, struct fuse_file_info *fi)
        {
       -  (void)path;
       -  (void)offset;
       -
          struct smbc_dirent *dirent;
          errno = 0;
          SMBCFILE *file = fd_to_smbcfile (fi->fh);
       @@ -115,13 +112,11 @@ int usmb_readdir (const char *path, void *h, fuse_fill_dir_t filler,
        }
        
        
       -int usmb_releasedir (const char *path, struct fuse_file_info *fi)
       +int usmb_releasedir (const char *path UNUSED, struct fuse_file_info *fi)
        {
       -  (void)path;
       -
          SMBCFILE *file = fd_to_smbcfile (fi->fh);
          DEBUG (fprintf (stderr, "releasedir (%s, %p)\n", path, (void *)file));
       -  return (ctx->closedir (ctx, file) < 0) ? -errno : 0;
       +  return (0 > ctx->closedir (ctx, file)) ? -errno : 0;
        }
        
        
 (DIR) diff --git a/usmb_file.c b/usmb_file.c
       @@ -16,9 +16,11 @@
        
        #include <sys/time.h>        // struct timeval needed by libsmbclient.h
        #include <libsmbclient.h>
       +#include <limits.h>
        #include <assert.h>
        #include <fuse.h>
        #include <errno.h>
       +#include <stdbool.h>
        #include <stddef.h>
        #include <stdio.h>
        #include <stdlib.h>
       @@ -28,6 +30,34 @@
        #include "utils.h"
        
        
       +// Samba gets st_nlink wrong for directories.
       +static bool fix_nlink (const char *url, struct stat *st)
       +{
       +  assert (NULL != url);
       +  assert (NULL != st);
       +
       +  if (!S_ISDIR (st->st_mode))
       +    return true;
       +
       +  SMBCFILE *file = ctx->opendir (ctx, url);
       +  if (NULL == file)
       +    return false;
       +
       +  st->st_nlink = 2;
       +  errno = ERANGE;
       +
       +  struct smbc_dirent *dirent;
       +
       +  while (NULL != (dirent = ctx->readdir (ctx, file)))
       +    if (SMBC_DIR == dirent->smbc_type)
       +      if (INT_MAX == st->st_nlink++)
       +        break;
       +
       +  (void)ctx->closedir (ctx, file);
       +  return (NULL == dirent);
       +}
       +  
       +
        int usmb_getattr (const char *filename, struct stat *st)
        {
          char *url = make_url (filename);
       @@ -37,18 +67,38 @@ int usmb_getattr (const char *filename, struct stat *st)
          DEBUG (fprintf (stderr, "stat (%s)\n", url));
        
          int ret = ctx->stat (ctx, url, st);
       +
       +  if ((0 > ret) || !fix_nlink (url, st))
       +    ret = -errno;
       +
          free (url);
       -  return (ret < 0) ? -errno : 0;
       +  return ret;
        }
        
        
       -int usmb_fgetattr (const char *filename, struct stat *st,
       +int usmb_fgetattr (const char *filename UNUSED, struct stat *st,
                           struct fuse_file_info *fi)
        {
       -  (void)filename;
          SMBCFILE *file = fd_to_smbcfile (fi->fh);
          DEBUG (fprintf (stderr, "fgetattr (%s, %p)\n", filename, (void *)file));
       -  return (ctx->fstat (ctx, file, st) < 0) ? -errno : 0;
       +
       +  if (0 > ctx->fstat (ctx, file, st))
       +    return -errno;
       +
       +  if (S_ISDIR (st->st_mode))
       +  {
       +    char *url = make_url (filename);
       +    if (NULL == url)
       +      return -ENOMEM;
       +
       +    bool ok = fix_nlink (url, st);
       +    free_errno (url);
       +
       +    if (!ok)
       +      return -errno;
       +  }
       +
       +  return 0;
        }
        
        
       @@ -59,7 +109,7 @@ int usmb_unlink (const char *filename)
            return -ENOMEM;
        
          DEBUG (fprintf (stderr, "unlink (%s)\n", url));
       -  int ret = (ctx->unlink (ctx, url) < 0) ? -errno : 0;
       +  int ret = (0 > ctx->unlink (ctx, url)) ? -errno : 0;
          free (url);
          return ret;
        }
       @@ -75,36 +125,32 @@ int usmb_open (const char *filename, struct fuse_file_info *fi)
          SMBCFILE *file = ctx->open (ctx, url, fi->flags, 0);
          DEBUG (fprintf (stderr, " = %p\n", (void *)file));
        
       -  free (url);
          int ret = (NULL == file) ? -errno : 0;
       +  free (url);
          fi->fh = smbcfile_to_fd (file);
        
          return ret;
        }
        
        
       -int usmb_release (const char *filename, struct fuse_file_info *fi)
       +int usmb_release (const char *filename UNUSED, struct fuse_file_info *fi)
        {
       -  (void)filename;
          SMBCFILE *file = fd_to_smbcfile (fi->fh);
          DEBUG (fprintf (stderr, "release (%s, %p)\n", filename, (void *)file));
       -  return (ctx->close_fn (ctx, file) < 0) ? -errno : 0;
       +  return (0 > ctx->close_fn (ctx, file)) ? -errno : 0;
        }
        
        
       -int usmb_read (const char *filename, char *buff, size_t len, off_t off,
       +int usmb_read (const char *filename UNUSED, char *buff, size_t len, off_t off,
                       struct fuse_file_info *fi)
        {
       -  (void)filename;
       -  (void)off;
       -
          assert (len <= 32768);
        
          SMBCFILE *file = fd_to_smbcfile (fi->fh);
          DEBUG (fprintf (stderr, "read (%p, %p, %u, %lld) ",
                          (void *)file, buff, len, off));
        
       -  if (ctx->lseek (ctx, file, off, SEEK_SET) < 0)
       +  if (0 > ctx->lseek (ctx, file, off, SEEK_SET))
          {
            fprintf (stderr, "- seek failed: %d\n", -errno);
            return -errno;
       @@ -112,21 +158,18 @@ int usmb_read (const char *filename, char *buff, size_t len, off_t off,
        
          int bytes = ctx->read (ctx, file, buff, len);
          DEBUG (fprintf (stderr, "= %d\n", bytes));
       -  return (bytes < 0) ? -errno : (int)bytes;
       +  return (0 > bytes) ? -errno : (int)bytes;
        }
        
        
       -int usmb_write (const char *filename, const char *buff, size_t len, off_t off,
       -                struct fuse_file_info *fi)
       +int usmb_write (const char *filename UNUSED, const char *buff, size_t len,
       +                off_t off, struct fuse_file_info *fi)
        {
       -  (void)filename;
       -  (void)off;
       -
          SMBCFILE *file = fd_to_smbcfile (fi->fh);
          DEBUG (fprintf (stderr, "write (%p, %p, len=%u, off=%lld) ",
                          (void *)file, buff, len, off));
        
       -  if (ctx->lseek (ctx, file, off, SEEK_SET) < 0)
       +  if (0 > ctx->lseek (ctx, file, off, SEEK_SET))
          {
            fprintf (stderr, "- seek failed: %d\n", -errno);
            return -errno;
       @@ -140,8 +183,7 @@ int usmb_write (const char *filename, const char *buff, size_t len, off_t off,
          while (written < len)
          {
            bytes = ctx->write (ctx, file, (char *)buff, (len > 32768) ? 32768 : len);
       -
       -    if (bytes < 0)
       +    if (0 > bytes)
              break;
        
            written += bytes;
       @@ -152,8 +194,8 @@ int usmb_write (const char *filename, const char *buff, size_t len, off_t off,
              break;
          }
        
       -  DEBUG (fprintf (stderr, "= %d\n", (bytes < 0) ? -errno : (int)written));
       -  return (bytes < 0) ? -errno : (int)written;
       +  DEBUG (fprintf (stderr, "= %d\n", (0 > bytes) ? -errno : (int)written));
       +  return (0 > bytes) ? -errno : (int)written;
        }
        
        
       @@ -189,7 +231,7 @@ int usmb_rename (const char *from, const char *to)
          }
        
          DEBUG (fprintf (stderr, "rename (%s, %s)\n", fromurl, tourl));
       -  int ret = (ctx->rename (ctx, fromurl, ctx, tourl) < 0) ? -errno : 0;
       +  int ret = (0 > ctx->rename (ctx, fromurl, ctx, tourl)) ? -errno : 0;
          free (tourl);
          free (fromurl);
          return ret;
       @@ -228,7 +270,7 @@ int usmb_utime (const char *filename, struct utimbuf *utb)
          };
        
          DEBUG (fprintf (stderr, "utime (%s)\n", url));
       -  int ret = (ctx->utimes (ctx, url, tv) < 0) ? -errno : 0;
       +  int ret = (0 > ctx->utimes (ctx, url, tv)) ? -errno : 0;
          free (url);
          return ret;
        }
       @@ -243,7 +285,7 @@ int usmb_utimes (const char *filename, const struct timespec ts[2])
            return -ENOMEM;
        
          DEBUG (fprintf (stderr, "utimes (%s)\n", url));
       -  int ret = (ctx->utimes (ctx, url, ts) < 0) ? -errno : 0;
       +  int ret = (0 > ctx->utimes (ctx, url, ts)) ? -errno : 0;
          free (url);
          return ret;
        }
       @@ -272,7 +314,7 @@ int usmb_truncate (const char *filename, off_t offset)
            SMBCFILE *file = ctx->open (ctx, url, O_WRONLY | O_TRUNC, 0);
            if (NULL == file)
            {
       -      free (url);
       +      free_errno (url);
              return -errno;
            }
          
       @@ -299,7 +341,7 @@ int usmb_chmod (const char *filename, mode_t mode)
            return -ENOMEM;
          
          DEBUG (fprintf (stderr, "chmod (%s, %u)\n", url, mode));
       -  int ret = (ctx->chmod (ctx, url, mode) < 0) ? -errno : 0;
       +  int ret = (0 > ctx->chmod (ctx, url, mode)) ? -errno : 0;
          free (url);
          return ret;
        }
 (DIR) diff --git a/utils.c b/utils.c
       @@ -15,6 +15,7 @@
         */
        
        #include <assert.h>
       +#include <errno.h>
        #include <stdarg.h>
        #include <stddef.h>
        #include <stdio.h>
       @@ -122,3 +123,19 @@ void clear_and_free (char *ptr)
          }
        }
        
       +
       +void free_errno (const void *ptr)
       +{
       +  int err = errno;
       +  free ((void *)ptr);
       +  errno = err;
       +}
       +
       +
       +void xfree_errno (const void *ptr)
       +{
       +  int err = errno;
       +  xfree (ptr);
       +  errno = err;
       +}
       +
 (DIR) diff --git a/utils.h b/utils.h
       @@ -29,5 +29,7 @@
          char * xstrdup (const char *in) MUSTCHECK;
          void xfree (const void *ptr);
          void clear_and_free (char *ptr);
       +  void free_errno (const void *ptr);
       +  void xfree_errno (const void *ptr);
        
        #endif
 (DIR) diff --git a/xml.c b/xml.c
       @@ -84,7 +84,8 @@ bool xml_xpath_attr_value (xmlXPathContextPtr ctx,
            return false;
          }
        
       -  do {
       +  do
       +  {
            if (XPATH_NODESET != obj->type)
            {
              DEBUG (fputs ("XPath evaluation didn't return a nodeset\n", stderr));
       @@ -142,7 +143,8 @@ bool xml_xpath_text (xmlXPathContextPtr ctx, char *xpath, char **out)
            return false;
          }
        
       -  do {
       +  do
       +  {
            if (XPATH_NODESET != obj->type)
            {
              DEBUG (fputs ("XPath evaluation didn't return a nodeset\n", stderr));