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));