s3:smbd: FSCTL_PIPE_TRANSCEIVE on a none IPC$ share should give NOT_SUPPORTED
[ira/wip.git] / source3 / smbd / dfree.c
index dad7d917e8e81689448e2d87b17e4d31323643e5..dc5719a4a504f66c9c43ee5bbbb48415998cd822 100644 (file)
@@ -5,7 +5,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "smbd/globals.h"
 
 /****************************************************************************
  Normalise for DOS usage.
 ****************************************************************************/
 
-static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+static void disk_norm(bool small_query, uint64_t *bsize,uint64_t *dfree,uint64_t *dsize)
 {
        /* check if the disk is beyond the max disk size */
-       SMB_BIG_UINT maxdisksize = lp_maxdisksize();
+       uint64_t maxdisksize = lp_maxdisksize();
        if (maxdisksize) {
                /* convert to blocks - and don't overflow */
                maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
@@ -63,13 +63,13 @@ static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,
  Return number of 1K blocks available on a path and total number.
 ****************************************************************************/
 
-SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small_query, 
-                              SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_query, 
+                              uint64_t *bsize,uint64_t *dfree,uint64_t *dsize)
 {
-       int dfree_retval;
-       SMB_BIG_UINT dfree_q = 0;
-       SMB_BIG_UINT bsize_q = 0;
-       SMB_BIG_UINT dsize_q = 0;
+       uint64_t dfree_retval;
+       uint64_t dfree_q = 0;
+       uint64_t bsize_q = 0;
+       uint64_t dsize_q = 0;
        const char *dfree_command;
 
        (*dfree) = (*dsize) = 0;
@@ -82,10 +82,18 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small
        dfree_command = lp_dfree_command(SNUM(conn));
        if (dfree_command && *dfree_command) {
                const char *p;
-               char **lines;
-               pstring syscmd;
+               char **lines = NULL;
+               char *syscmd = NULL;
+
+               syscmd = talloc_asprintf(talloc_tos(),
+                               "%s %s",
+                               dfree_command,
+                               path);
+
+               if (!syscmd) {
+                       return (uint64_t)-1;
+               }
 
-               slprintf(syscmd, sizeof(syscmd)-1, "%s %s", dfree_command, path);
                DEBUG (3, ("disk_free: Running command %s\n", syscmd));
 
                lines = file_lines_pload(syscmd, NULL);
@@ -105,7 +113,7 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small
                                *bsize = STR_TO_SMB_BIG_UINT(p, NULL);
                        else
                                *bsize = 1024;
-                       file_lines_free(lines);
+                       TALLOC_FREE(lines);
                        DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n",
                                (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize));
 
@@ -119,14 +127,14 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small
                        if (sys_fsusage(path, dfree, dsize) != 0) {
                                DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n",
                                        strerror(errno) ));
-                               return (SMB_BIG_UINT)-1;
+                               return (uint64_t)-1;
                        }
                }
        } else {
                if (sys_fsusage(path, dfree, dsize) != 0) {
                        DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n",
                                strerror(errno) ));
-                       return (SMB_BIG_UINT)-1;
+                       return (uint64_t)-1;
                }
        }
 
@@ -143,10 +151,9 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small
        }
 
        if ((*dsize)<1) {
-               static int done;
-               if (!done) {
+               if (!dfree_broken) {
                        DEBUG(0,("WARNING: dfree is broken on this system\n"));
-                       done=1;
+                       dfree_broken=true;
                }
                *dsize = 20*1024*1024/(*bsize);
                *dfree = MAX(1,*dfree);
@@ -167,16 +174,16 @@ SMB_BIG_UINT sys_disk_free(connection_struct *conn, const char *path, BOOL small
  Potentially returned cached dfree info.
 ****************************************************************************/
 
-SMB_BIG_UINT get_dfree_info(connection_struct *conn,
+uint64_t get_dfree_info(connection_struct *conn,
                        const char *path,
-                       BOOL small_query,
-                       SMB_BIG_UINT *bsize,
-                       SMB_BIG_UINT *dfree,
-                       SMB_BIG_UINT *dsize)
+                       bool small_query,
+                       uint64_t *bsize,
+                       uint64_t *dfree,
+                       uint64_t *dsize)
 {
        int dfree_cache_time = lp_dfree_cache_time(SNUM(conn));
        struct dfree_cached_info *dfc = conn->dfree_info;
-       SMB_BIG_UINT dfree_ret;
+       uint64_t dfree_ret;
 
        if (!dfree_cache_time) {
                return SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize);
@@ -192,14 +199,14 @@ SMB_BIG_UINT get_dfree_info(connection_struct *conn,
 
        dfree_ret = SMB_VFS_DISK_FREE(conn,path,small_query,bsize,dfree,dsize);
 
-       if (dfree_ret == (SMB_BIG_UINT)-1) {
+       if (dfree_ret == (uint64_t)-1) {
                /* Don't cache bad data. */
                return dfree_ret;
        }
 
        /* No cached info or time to refresh. */
        if (!dfc) {
-               dfc = TALLOC_P(conn->mem_ctx, struct dfree_cached_info);
+               dfc = TALLOC_P(conn, struct dfree_cached_info);
                if (!dfc) {
                        return dfree_ret;
                }