[Bug 6069] Add a fstatvfs function for libsmbclient
authorDerrell Lipman <derrell.lipman@unwireduniverse.com>
Thu, 12 Feb 2009 14:16:48 +0000 (09:16 -0500)
committerKarolin Seeger <kseeger@samba.org>
Mon, 16 Feb 2009 08:57:02 +0000 (09:57 +0100)
- DFS is not a POSIX feature, so the state of that bit should be zero if DFS
  is *not* supported. Bit feature reversed.

- Added smbc_statvfs function

Derrell
(cherry picked from commit 0697cffe211a922c816b6c75230c4186328498ed)

examples/libsmbclient/Makefile
examples/libsmbclient/testfstatvfs.c
examples/libsmbclient/teststatvfs.c [new file with mode: 0644]
source/include/libsmb_internal.h
source/include/libsmbclient.h
source/libsmb/libsmb_compat.c
source/libsmb/libsmb_context.c
source/libsmb/libsmb_setget.c
source/libsmb/libsmb_stat.c

index 7ad28dcea0f83918d44322f87cfa8ca0c1a30117..728dbe0edbca9597afe3b24aa95b9ce83a0ce664 100644 (file)
@@ -24,6 +24,7 @@ TESTS=        testsmbc \
        teststat \
        teststat2 \
        teststat3 \
+       teststatvfs \
        testfstatvfs \
        testtruncate \
        testchmod \
@@ -75,6 +76,10 @@ teststat3: teststat3.o
        @echo Linking teststat3
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt
 
+teststatvfs: teststatvfs.o
+       @echo Linking teststatvfs
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt
+
 testfstatvfs: testfstatvfs.o
        @echo Linking testfstatvfs
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt
index f8a6870a921ee3ad67421bd88b77fd9047772313..b4dafefff60a4dc2991c9cf9b2659004b832a08e 100644 (file)
@@ -105,13 +105,13 @@ int main(int argc, char * argv[])
                 printf("case_sensitive ");
             }
 
-            if (statvfsbuf.f_flag & SMBC_VFS_FEATURE_NO_DFS)
+            if (statvfsbuf.f_flag & SMBC_VFS_FEATURE_DFS)
             {
-                printf("NO_DFS ");
+                printf("DFS ");
             }
             else
             {
-                printf("dfs ");
+                printf("no_dfs ");
             }
 
             printf("\n");
diff --git a/examples/libsmbclient/teststatvfs.c b/examples/libsmbclient/teststatvfs.c
new file mode 100644 (file)
index 0000000..8812002
--- /dev/null
@@ -0,0 +1,96 @@
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#include <stdio.h> 
+#include <unistd.h>
+#include <string.h> 
+#include <time.h> 
+#include <errno.h>
+#include <libsmbclient.h> 
+#include "get_auth_data_fn.h"
+
+
+int main(int argc, char * argv[]) 
+{ 
+    int             i;
+    int             fd;
+    int             ret;
+    int             debug = 0;
+    char *          p;
+    char            path[2048];
+    struct stat     statbuf;
+    struct statvfs  statvfsbuf;
+    
+    smbc_init(get_auth_data_fn, debug); 
+    
+    for (;;)
+    {
+        fprintf(stdout, "Path: ");
+        *path = '\0';
+        fgets(path, sizeof(path) - 1, stdin);
+        if (strlen(path) == 0)
+        {
+            return 0;
+        }
+
+        p = path + strlen(path) - 1;
+        if (*p == '\n')
+        {
+            *p = '\0';
+        }
+    
+        ret = smbc_statvfs(path, &statvfsbuf);
+
+        if (ret < 0)
+        {
+            perror("fstatvfs");
+        }
+        else
+        {
+            printf("\n");
+            printf("Block Size: %lu\n", statvfsbuf.f_bsize);
+            printf("Fragment Size: %lu\n", statvfsbuf.f_frsize);
+            printf("Blocks: %llu\n", statvfsbuf.f_blocks);
+            printf("Free Blocks: %llu\n", statvfsbuf.f_bfree);
+            printf("Available Blocks: %llu\n", statvfsbuf.f_bavail);
+            printf("Files : %llu\n", statvfsbuf.f_files);
+            printf("Free Files: %llu\n", statvfsbuf.f_ffree);
+            printf("Available Files: %llu\n", statvfsbuf.f_favail);
+            printf("File System ID: %lu\n", statvfsbuf.f_fsid);
+            printf("\n");
+
+            printf("Flags: 0x%lx\n", statvfsbuf.f_flag);
+            printf("Extended Features: ");
+
+            if (statvfsbuf.f_flag & SMBC_VFS_FEATURE_NO_UNIXCIFS)
+            {
+                printf("NO_UNIXCIFS ");
+            }
+            else
+            {
+                printf("unixcifs ");
+            }
+
+            if (statvfsbuf.f_flag & SMBC_VFS_FEATURE_CASE_INSENSITIVE)
+            {
+                printf("CASE_INSENSITIVE ");
+            }
+            else
+            {
+                printf("case_sensitive ");
+            }
+
+            if (statvfsbuf.f_flag & SMBC_VFS_FEATURE_DFS)
+            {
+                printf("DFS ");
+            }
+            else
+            {
+                printf("no_dfs ");
+            }
+
+            printf("\n");
+        }
+    }
+
+    return 0; 
+}
index edf3a6ed088aeed66bdc9ef2d9069c756a963638..166685c38015646509f8dde8c2906c7dc78cbbb2 100644 (file)
@@ -197,6 +197,7 @@ struct SMBC_internal_data {
                 smbc_stat_fn                    stat_fn;
                 smbc_fstat_fn                   fstat_fn;
 #endif
+                smbc_statvfs_fn                 statvfs_fn;
                 smbc_fstatvfs_fn                fstatvfs_fn;
                 smbc_ftruncate_fn               ftruncate_fn;
 #if 0 /* Left in libsmbclient.h for backward compatibility */
@@ -502,6 +503,12 @@ SMBC_fstat_ctx(SMBCCTX *context,
                struct stat *st);
 
 
+int
+SMBC_statvfs_ctx(SMBCCTX *context,
+                 char *path,
+                 struct statvfs *st);
+
+
 int
 SMBC_fstatvfs_ctx(SMBCCTX *context,
                   SMBCFILE *file,
index ec7e74287f0706f278a1c94a5e782f80d98343a8..67010a5bfe576eced9e39ab07208e2d2ae6aafaf 100644 (file)
@@ -185,7 +185,7 @@ typedef enum smbc_vfs_feature
     SMBC_VFS_FEATURE_RDONLY         = (1 << 0),
 
     /* Specific to libsmbclient (high-order bits) */
-    SMBC_VFS_FEATURE_NO_DFS           = (1 << 29),
+    SMBC_VFS_FEATURE_DFS              = (1 << 29),
     SMBC_VFS_FEATURE_CASE_INSENSITIVE = (1 << 30),
     SMBC_VFS_FEATURE_NO_UNIXCIFS      = (1 << 31)
 } smbc_vfs_feature;
@@ -869,6 +869,12 @@ typedef int (*smbc_fstat_fn)(SMBCCTX *c,
 smbc_fstat_fn smbc_getFunctionFstat(SMBCCTX *c);
 void smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn);
 
+typedef int (*smbc_statvfs_fn)(SMBCCTX *c,
+                               char *path,
+                               struct statvfs *st);
+smbc_statvfs_fn smbc_getFunctionStatVFS(SMBCCTX *c);
+void smbc_setFunctionStatVFS(SMBCCTX *c, smbc_statvfs_fn fn);
+
 typedef int (*smbc_fstatvfs_fn)(SMBCCTX *c,
                                 SMBCFILE *file,
                                 struct statvfs *st);
@@ -1613,6 +1619,28 @@ int smbc_stat(const char *url, struct stat *st);
 int smbc_fstat(int fd, struct stat *st);
 
 
+/**@ingroup attribute
+ * Get file system information for a specified path.
+ * 
+ * @param url       The smb url to get information for
+ *
+ * @param st        pointer to a buffer that will be filled with 
+ *                  standard Unix struct statvfs information.
+ * 
+ * @return          EBADF  filedes is bad.
+ *                  - EACCES Permission denied.
+ *                  - EBADF fd is not a valid file descriptor
+ *                  - EINVAL Problems occurred in the underlying routines
+ *                   or smbc_init not called.
+ *                  - ENOMEM Out of memory
+ *
+ * @see             Unix fstatvfs()
+ *
+ */
+int
+smbc_statvfs(char *url,
+             struct statvfs *st);
+
 /**@ingroup attribute
  * Get file system information via an file descriptor.
  * 
@@ -1636,6 +1664,7 @@ int
 smbc_fstatvfs(int fd,
               struct statvfs *st);
 
+
 /**@ingroup attribute
  * Truncate a file given a file descriptor
  * 
index 5bebc5ef87d33902d3c0a104a01eaacac7f4b6c1..56d113f31a221736c07454f2e7154b8711185def 100644 (file)
@@ -329,6 +329,13 @@ smbc_fstat(int fd,
         return smbc_getFunctionFstat(statcont)(statcont, file, st);
 }
 
+int
+smbc_statvfs(char *path,
+             struct statvfs *st)
+{
+        return smbc_getFunctionStatVFS(statcont)(statcont, path, st);
+}
+
 int
 smbc_fstatvfs(int fd,
               struct statvfs *st)
index fa0de2463955d22fbfac4535bf4c43830aac2473..3f8e0c573cbd4a92fe449f4a45d709c2fe4a66b2 100644 (file)
@@ -94,6 +94,7 @@ smbc_new_context(void)
         smbc_setFunctionLseek(context, SMBC_lseek_ctx);
         smbc_setFunctionFtruncate(context, SMBC_ftruncate_ctx);
         smbc_setFunctionStat(context, SMBC_stat_ctx);
+        smbc_setFunctionStatVFS(context, SMBC_statvfs_ctx);
         smbc_setFunctionFstatVFS(context, SMBC_fstatvfs_ctx);
         smbc_setFunctionFstat(context, SMBC_fstat_ctx);
         smbc_setFunctionOpendir(context, SMBC_opendir_ctx);
index 9fb608b30e7dc7fd2b3be0ad22c3724635c0cf3e..3493e4f8dd2f726c631703cf4122323828d2e8c3 100644 (file)
@@ -659,6 +659,18 @@ smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn)
         c->fstat = fn;
 }
 
+smbc_statvfs_fn
+smbc_getFunctionStatVFS(SMBCCTX *c)
+{
+        return c->internal->posix_emu.statvfs_fn;
+}
+
+void
+smbc_setFunctionStatVFS(SMBCCTX *c, smbc_statvfs_fn fn)
+{
+        c->internal->posix_emu.statvfs_fn = fn;
+}
+
 smbc_fstatvfs_fn
 smbc_getFunctionFstatVFS(SMBCCTX *c)
 {
index 02088c368bb623056140fcfc2ffe9ab597ba3265..bfcacdc87a03534edcd302a109b9aed3ca4a8691 100644 (file)
@@ -301,6 +301,58 @@ SMBC_fstat_ctx(SMBCCTX *context,
         
 }
 
+
+/*
+ * Routine to obtain file system information given a path
+ */
+int
+SMBC_statvfs_ctx(SMBCCTX *context,
+                 char *path,
+                 struct statvfs *st)
+{
+        int             ret;
+        bool            bIsDir;
+        struct stat     statbuf;
+        SMBCFILE *      pFile;
+
+        /* Determine if the provided path is a file or a folder */
+        if (SMBC_stat_ctx(context, path, &statbuf) < 0) {
+                return -1;
+        }
+
+        /* Is it a file or a directory?  */
+        if (S_ISDIR(statbuf.st_mode)) {
+                /* It's a directory. */
+                if ((pFile = SMBC_opendir_ctx(context, path)) < 0) {
+                        return -1;
+                }
+                bIsDir = true;
+        } else if (S_ISREG(statbuf.st_mode)) {
+                /* It's a file. */
+                if ((pFile = SMBC_open_ctx(context, path, O_RDONLY, 0)) < 0) {
+                        return -1;
+                }
+                bIsDir = false;
+        } else {
+                /* It's neither a file nor a directory. Not supported. */
+                errno = ENOSYS;
+                return -1;
+        }
+
+        /* Now we have an open file handle, so just use SMBC_fstatvfs */
+        ret = SMBC_fstatvfs_ctx(context, pFile, st);
+
+        /* Close the file or directory */
+        if (bIsDir) {
+                SMBC_closedir_ctx(context, pFile);
+        } else {
+                SMBC_close_ctx(context, pFile);
+        }
+
+        return ret;
+}
+
+
 /*
  * Routine to obtain file system information given an fd
  */
@@ -411,8 +463,8 @@ SMBC_fstatvfs_ctx(SMBCCTX *context,
         }
 
         /* See if DFS is supported */
-       if (! (cli->capabilities & CAP_DFS) ||  ! cli->dfsroot) {
-                st->f_flag |= SMBC_VFS_FEATURE_NO_DFS;
+       if ((cli->capabilities & CAP_DFS) &&  cli->dfsroot) {
+                st->f_flag |= SMBC_VFS_FEATURE_DFS;
         }
 
         return 0;