From bd037226cf4a14330a38b1370ed42b33618edb5c Mon Sep 17 00:00:00 2001 From: Geoff Johnstone Date: Wed, 25 Jun 2008 22:53:53 +0100 Subject: [PATCH] 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. --- Makefile | 3 +- usmb.c | 13 +++----- usmb_dir.c | 13 +++----- usmb_file.c | 102 ++++++++++++++++++++++++++++++++++++++++++------------------ utils.c | 17 ++++++++++ utils.h | 2 ++ xml.c | 6 ++-- 7 files changed, 106 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index de9bb9a..029a366 100644 --- 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 diff --git a/usmb.c b/usmb.c index a6d6ba8..c407677 100644 --- 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)); } diff --git a/usmb_dir.c b/usmb_dir.c index 1230e39..9fce867 100644 --- 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; } diff --git a/usmb_file.c b/usmb_file.c index b2fa2c5..02cc35a 100644 --- a/usmb_file.c +++ b/usmb_file.c @@ -16,9 +16,11 @@ #include // struct timeval needed by libsmbclient.h #include +#include #include #include #include +#include #include #include #include @@ -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; } diff --git a/utils.c b/utils.c index b7e8e86..d51dfce 100644 --- a/utils.c +++ b/utils.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -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; +} + diff --git a/utils.h b/utils.h index 68e86ab..958e2be 100644 --- 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 diff --git a/xml.c b/xml.c index 955c984..567aeac 100644 --- 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)); -- 2.11.4.GIT