1996-05-05 15:25:33 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
support for quotas
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 1998
1996-05-05 15:25:33 +04:00
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
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
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 0213 9 , USA .
*/
1996-05-31 19:13:29 +04:00
/*
* This is one of the most system dependent parts of Samba , and its
* done a litle differently . Each system has its own way of doing
* things : - (
*/
# include "includes.h"
1996-05-05 15:25:33 +04:00
1996-06-08 08:33:37 +04:00
extern int DEBUGLEVEL ;
1996-05-05 15:25:33 +04:00
# ifdef LINUX
1996-05-31 19:13:29 +04:00
1997-06-11 05:03:06 +04:00
# include <sys/types.h>
# include <asm/types.h>
# include <sys/quota.h>
1996-05-31 19:13:29 +04:00
# include <mntent.h>
1997-06-11 05:03:06 +04:00
# include <linux/unistd.h>
_syscall4 ( int , quotactl , int , cmd , const char * , special , int , id , caddr_t , addr ) ;
1996-05-31 19:13:29 +04:00
1996-05-05 15:25:33 +04:00
/****************************************************************************
try to get the disk space from disk quotas ( LINUX version )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-06-11 05:03:06 +04:00
1998-11-06 21:40:51 +03:00
BOOL disk_quotas ( char * path , SMB_BIG_UINT * bsize , SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
1996-05-05 15:25:33 +04:00
{
1997-06-11 05:03:06 +04:00
int r ;
1996-05-05 15:25:33 +04:00
struct dqblk D ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT S ;
1996-05-05 15:25:33 +04:00
FILE * fp ;
1997-06-11 05:03:06 +04:00
struct mntent * mnt ;
1998-09-03 22:40:31 +04:00
SMB_DEV_T devno ;
1997-06-11 05:03:06 +04:00
int found ;
1999-12-13 16:27:58 +03:00
uid_t euser_id ;
euser_id = geteuid ( ) ;
1996-05-05 15:25:33 +04:00
/* find the block device file */
1998-09-03 22:40:31 +04:00
if ( sys_stat ( path , & S ) = = - 1 ) {
1996-05-05 15:25:33 +04:00
return ( False ) ;
1997-06-11 05:03:06 +04:00
}
1996-05-05 15:25:33 +04:00
devno = S . st_dev ;
fp = setmntent ( MOUNTED , " r " ) ;
found = False ;
1997-06-11 05:03:06 +04:00
while ( ( mnt = getmntent ( fp ) ) ) {
1998-09-03 22:40:31 +04:00
if ( sys_stat ( mnt - > mnt_dir , & S ) = = - 1 )
1996-05-05 15:25:33 +04:00
continue ;
if ( S . st_dev = = devno ) {
found = True ;
break ;
}
}
endmntent ( fp ) ;
1997-06-11 05:03:06 +04:00
if ( ! found ) {
1996-05-05 15:25:33 +04:00
return ( False ) ;
}
1997-06-11 05:03:06 +04:00
1999-12-13 16:27:58 +03:00
save_re_uid ( ) ;
set_effective_uid ( 0 ) ;
1997-06-11 05:03:06 +04:00
r = quotactl ( QCMD ( Q_GETQUOTA , USRQUOTA ) , mnt - > mnt_fsname , euser_id , ( caddr_t ) & D ) ;
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
1997-06-11 05:03:06 +04:00
/* Use softlimit to determine disk space, except when it has been exceeded */
* bsize = 1024 ;
if ( r )
{
if ( errno = = EDQUOT )
{
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
return ( True ) ;
1996-05-05 15:25:33 +04:00
}
1997-06-11 05:03:06 +04:00
else return ( False ) ;
1996-05-05 15:25:33 +04:00
}
1997-06-11 05:03:06 +04:00
/* Use softlimit to determine disk space, except when it has been exceeded */
if (
( D . dqb_bsoftlimit & & D . dqb_curblocks > = D . dqb_bsoftlimit ) | |
( D . dqb_bhardlimit & & D . dqb_curblocks > = D . dqb_bhardlimit ) | |
( D . dqb_isoftlimit & & D . dqb_curinodes > = D . dqb_isoftlimit ) | |
( D . dqb_ihardlimit & & D . dqb_curinodes > = D . dqb_ihardlimit )
)
1996-05-05 15:25:33 +04:00
{
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
}
1997-06-11 05:03:06 +04:00
else if ( D . dqb_bsoftlimit = = 0 & & D . dqb_bhardlimit = = 0 )
{
return ( False ) ;
}
1996-05-05 15:25:33 +04:00
else {
1998-03-24 03:37:53 +03:00
if ( D . dqb_bsoftlimit = = 0 )
D . dqb_bsoftlimit = D . dqb_bhardlimit ;
1996-05-05 15:25:33 +04:00
* dfree = D . dqb_bsoftlimit - D . dqb_curblocks ;
* dsize = D . dqb_bsoftlimit ;
}
return ( True ) ;
}
# elif defined(CRAY)
1996-05-31 19:13:29 +04:00
# include <sys/quota.h>
# include <mntent.h>
1996-05-05 15:25:33 +04:00
/****************************************************************************
try to get the disk space from disk quotas ( CRAY VERSION )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-06 21:40:51 +03:00
BOOL disk_quotas ( char * path , SMB_BIG_UINT * bsize , SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
1996-05-05 15:25:33 +04:00
{
struct mntent * mnt ;
FILE * fd ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT sbuf ;
1998-09-03 22:40:31 +04:00
SMB_DEV_T devno ;
static SMB_DEV_T devno_cached = 0 ;
1998-05-12 04:55:32 +04:00
static pstring name ;
1996-05-05 15:25:33 +04:00
struct q_request request ;
struct qf_header header ;
static int quota_default = 0 ;
int found ;
1998-09-03 22:40:31 +04:00
if ( sys_stat ( path , & sbuf ) = = - 1 )
1996-05-05 15:25:33 +04:00
return ( False ) ;
devno = sbuf . st_dev ;
if ( devno ! = devno_cached ) {
devno_cached = devno ;
if ( ( fd = setmntent ( KMTAB ) ) = = NULL )
return ( False ) ;
found = False ;
while ( ( mnt = getmntent ( fd ) ) ! = NULL ) {
1998-09-03 22:40:31 +04:00
if ( sys_stat ( mnt - > mnt_dir , & sbuf ) = = - 1 )
1996-05-05 15:25:33 +04:00
continue ;
if ( sbuf . st_dev = = devno ) {
found = True ;
break ;
}
}
1998-05-12 04:55:32 +04:00
pstrcpy ( name , mnt - > mnt_dir ) ;
1996-05-05 15:25:33 +04:00
endmntent ( fd ) ;
if ( ! found )
return ( False ) ;
}
request . qf_magic = QF_MAGIC ;
request . qf_entry . id = geteuid ( ) ;
if ( quotactl ( name , Q_GETQUOTA , & request ) = = - 1 )
return ( False ) ;
if ( ! request . user )
return ( False ) ;
if ( request . qf_entry . user_q . f_quota = = QFV_DEFAULT ) {
if ( ! quota_default ) {
if ( quotactl ( name , Q_GETHEADER , & header ) = = - 1 )
return ( False ) ;
else
quota_default = header . user_h . def_fq ;
}
* dfree = quota_default ;
} else if ( request . qf_entry . user_q . f_quota = = QFV_PREVENT ) {
* dfree = 0 ;
} else {
* dfree = request . qf_entry . user_q . f_quota ;
}
* dsize = request . qf_entry . user_q . f_use ;
1999-12-13 16:27:58 +03:00
if ( * dfree < * dsize )
1996-05-05 15:25:33 +04:00
* dfree = 0 ;
1999-12-13 16:27:58 +03:00
else
* dfree - = * dsize ;
1996-05-05 15:25:33 +04:00
* bsize = 4096 ; /* Cray blocksize */
return ( True ) ;
}
1996-06-08 08:33:37 +04:00
# elif defined(SUNOS5) || defined(SUNOS4)
1996-05-05 15:25:33 +04:00
# include <fcntl.h>
1998-11-06 21:40:51 +03:00
# include <sys/param.h>
1996-06-08 08:33:37 +04:00
# if defined(SUNOS5)
1996-05-05 15:25:33 +04:00
# include <sys/fs/ufs_quota.h>
1996-06-08 08:33:37 +04:00
# include <sys/mnttab.h>
# else /* defined(SUNOS4) */
# include <ufs/quota.h>
# include <mntent.h>
# endif
1996-05-05 15:25:33 +04:00
/****************************************************************************
1998-11-06 21:40:51 +03:00
try to get the disk space from disk quotas ( SunOS & Solaris2 version )
1998-11-09 23:33:37 +03:00
Quota code by Peter Urbanec ( amiga @ cse . unsw . edu . au ) .
1998-11-06 21:40:51 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL disk_quotas ( char * path , SMB_BIG_UINT * bsize , SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
1996-05-05 15:25:33 +04:00
{
1999-12-13 16:27:58 +03:00
uid_t euser_id ;
1996-06-08 08:33:37 +04:00
int ret ;
1996-05-05 15:25:33 +04:00
struct dqblk D ;
1996-06-08 08:33:37 +04:00
# if defined(SUNOS5)
1996-05-05 15:25:33 +04:00
struct quotctl command ;
int file ;
1996-06-08 08:33:37 +04:00
struct mnttab mnt ;
1998-05-12 04:55:32 +04:00
static pstring name ;
1998-11-06 21:40:51 +03:00
# else /* SunOS4 */
1996-06-08 08:33:37 +04:00
struct mntent * mnt ;
1998-05-12 04:55:32 +04:00
static pstring name ;
1996-06-08 08:33:37 +04:00
# endif
FILE * fd ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT sbuf ;
1998-09-03 22:40:31 +04:00
SMB_DEV_T devno ;
static SMB_DEV_T devno_cached = 0 ;
1996-06-08 08:33:37 +04:00
int found ;
1999-12-13 16:27:58 +03:00
euser_id = geteuid ( ) ;
1996-06-08 08:33:37 +04:00
1998-09-03 22:40:31 +04:00
if ( sys_stat ( path , & sbuf ) = = - 1 )
1996-06-08 08:33:37 +04:00
return ( False ) ;
devno = sbuf . st_dev ;
1996-06-10 08:38:24 +04:00
DEBUG ( 5 , ( " disk_quotas: looking for path \" %s \" devno=%o \n " , path , devno ) ) ;
1996-06-08 08:33:37 +04:00
if ( devno ! = devno_cached ) {
devno_cached = devno ;
# if defined(SUNOS5)
1998-11-17 23:50:07 +03:00
if ( ( fd = sys_fopen ( MNTTAB , " r " ) ) = = NULL )
1996-06-08 08:33:37 +04:00
return ( False ) ;
found = False ;
while ( getmntent ( fd , & mnt ) = = 0 ) {
1998-09-03 22:40:31 +04:00
if ( sys_stat ( mnt . mnt_mountp , & sbuf ) = = - 1 )
1996-06-08 08:33:37 +04:00
continue ;
1996-06-10 08:38:24 +04:00
DEBUG ( 5 , ( " disk_quotas: testing \" %s \" devno=%o \n " ,
mnt . mnt_mountp , sbuf . st_dev ) ) ;
1996-06-08 08:33:37 +04:00
if ( sbuf . st_dev = = devno ) {
found = True ;
break ;
}
}
1998-05-12 04:55:32 +04:00
pstrcpy ( name , mnt . mnt_mountp ) ;
pstrcat ( name , " /quotas " ) ;
1996-06-08 08:33:37 +04:00
fclose ( fd ) ;
1998-11-06 21:40:51 +03:00
# else /* SunOS4 */
1996-06-08 08:33:37 +04:00
if ( ( fd = setmntent ( MOUNTED , " r " ) ) = = NULL )
return ( False ) ;
found = False ;
while ( ( mnt = getmntent ( fd ) ) ! = NULL ) {
1998-09-03 22:40:31 +04:00
if ( sys_stat ( mnt - > mnt_dir , & sbuf ) = = - 1 )
1996-06-08 08:33:37 +04:00
continue ;
1996-06-10 08:38:24 +04:00
DEBUG ( 5 , ( " disk_quotas: testing \" %s \" devno=%o \n " ,
mnt - > mnt_dir , sbuf . st_dev ) ) ;
1996-06-08 08:33:37 +04:00
if ( sbuf . st_dev = = devno ) {
found = True ;
break ;
}
}
1998-05-12 04:55:32 +04:00
pstrcpy ( name , mnt - > mnt_fsname ) ;
1996-06-08 08:33:37 +04:00
endmntent ( fd ) ;
# endif
if ( ! found )
return ( False ) ;
}
1996-05-05 15:25:33 +04:00
1999-12-13 16:27:58 +03:00
save_re_uid ( ) ;
set_effective_uid ( 0 ) ;
1996-05-31 19:13:29 +04:00
1996-06-08 08:33:37 +04:00
# if defined(SUNOS5)
1996-06-10 08:38:24 +04:00
DEBUG ( 5 , ( " disk_quotas: looking for quotas file \" %s \" \n " , name ) ) ;
1998-11-17 23:50:07 +03:00
if ( ( file = sys_open ( name , O_RDONLY , 0 ) ) < 0 ) {
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
return ( False ) ;
1996-06-08 08:33:37 +04:00
}
command . op = Q_GETQUOTA ;
command . uid = euser_id ;
command . addr = ( caddr_t ) & D ;
1996-05-31 19:13:29 +04:00
ret = ioctl ( file , Q_QUOTACTL , & command ) ;
1996-06-08 08:33:37 +04:00
close ( file ) ;
# else
1996-06-10 08:38:24 +04:00
DEBUG ( 5 , ( " disk_quotas: trying quotactl on device \" %s \" \n " , name ) ) ;
1996-06-08 08:33:37 +04:00
ret = quotactl ( Q_GETQUOTA , name , euser_id , & D ) ;
# endif
1996-05-05 15:25:33 +04:00
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
1996-05-05 15:25:33 +04:00
1996-05-31 19:13:29 +04:00
if ( ret < 0 ) {
1998-11-06 21:40:51 +03:00
DEBUG ( 5 , ( " disk_quotas ioctl (Solaris) failed. Error = %s \n " , strerror ( errno ) ) ) ;
1996-05-31 19:13:29 +04:00
return ( False ) ;
}
1996-05-05 15:25:33 +04:00
/* Use softlimit to determine disk space. A user exceeding the quota is told
* that there ' s no space left . Writes might actually work for a bit if the
* hardlimit is set higher than softlimit . Effectively the disk becomes
* made of rubber latex and begins to expand to accommodate the user : - )
*/
1996-06-08 08:33:37 +04:00
if ( D . dqb_bsoftlimit = = 0 )
return ( False ) ;
1998-11-06 21:40:51 +03:00
* bsize = DEV_BSIZE ;
1996-05-05 15:25:33 +04:00
* dsize = D . dqb_bsoftlimit ;
1998-11-06 21:40:51 +03:00
1999-12-13 16:27:58 +03:00
if ( D . dqb_curblocks > D . dqb_bsoftlimit ) {
1996-05-05 15:25:33 +04:00
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
1999-12-13 16:27:58 +03:00
} else
* dfree = D . dqb_bsoftlimit - D . dqb_curblocks ;
1996-05-05 15:25:33 +04:00
1998-11-06 21:40:51 +03:00
DEBUG ( 5 , ( " disk_quotas for path \" %s \" returning bsize %.0f, dfree %.0f, dsize %.0f \n " ,
path , ( double ) * bsize , ( double ) * dfree , ( double ) * dsize ) ) ;
1996-05-05 15:25:33 +04:00
return ( True ) ;
}
1997-08-19 23:22:26 +04:00
# elif defined(OSF1)
# include <ufs/quota.h>
/****************************************************************************
1998-11-13 05:07:07 +03:00
try to get the disk space from disk quotas - OSF1 version
1997-08-19 23:22:26 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-06 21:40:51 +03:00
BOOL disk_quotas ( char * path , SMB_BIG_UINT * bsize , SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
1997-08-19 23:22:26 +04:00
{
1997-09-23 23:19:06 +04:00
int r , save_errno ;
1997-08-19 23:22:26 +04:00
struct dqblk D ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT S ;
1999-12-13 16:27:58 +03:00
uid_t euser_id ;
1997-08-19 23:22:26 +04:00
1999-12-13 16:27:58 +03:00
/*
* This code presumes that OSF1 will only
* give out quota info when the real uid
* matches the effective uid . JRA .
*/
1997-08-19 23:22:26 +04:00
euser_id = geteuid ( ) ;
1999-12-13 16:27:58 +03:00
save_re_uid ( ) ;
if ( set_re_uid ( ) ! = 0 ) return False ;
1997-08-19 23:22:26 +04:00
r = quotactl ( path , QCMD ( Q_GETQUOTA , USRQUOTA ) , euser_id , ( char * ) & D ) ;
1999-12-13 16:27:58 +03:00
if ( r ) {
1997-09-23 23:19:06 +04:00
save_errno = errno ;
1999-12-13 16:27:58 +03:00
}
1997-09-23 23:19:06 +04:00
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
1997-08-19 23:22:26 +04:00
* bsize = DEV_BSIZE ;
if ( r )
1997-09-23 23:19:06 +04:00
{
if ( save_errno = = EDQUOT ) // disk quota exceeded
{
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
return ( True ) ;
}
else
return ( False ) ;
}
1997-08-19 23:22:26 +04:00
/* Use softlimit to determine disk space, except when it has been exceeded */
if ( D . dqb_bsoftlimit = = 0 )
return ( False ) ;
if ( ( D . dqb_curblocks > D . dqb_bsoftlimit ) ) {
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
} else {
* dfree = D . dqb_bsoftlimit - D . dqb_curblocks ;
* dsize = D . dqb_bsoftlimit ;
}
return ( True ) ;
}
1997-10-09 00:34:13 +04:00
1999-12-13 16:27:58 +03:00
# elif defined (IRIX6)
1997-10-09 00:34:13 +04:00
/****************************************************************************
try to get the disk space from disk quotas ( IRIX 6.2 version )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <sys/quota.h>
# include <mntent.h>
1998-11-06 21:40:51 +03:00
BOOL disk_quotas ( char * path , SMB_BIG_UINT * bsize , SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
1997-10-09 00:34:13 +04:00
{
uid_t euser_id ;
int r ;
struct dqblk D ;
struct fs_disk_quota F ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT S ;
1997-10-09 00:34:13 +04:00
FILE * fp ;
struct mntent * mnt ;
1998-09-03 22:40:31 +04:00
SMB_DEV_T devno ;
1997-10-09 00:34:13 +04:00
int found ;
/* find the block device file */
1998-09-03 22:40:31 +04:00
if ( sys_stat ( path , & S ) = = - 1 ) {
1997-10-09 00:34:13 +04:00
return ( False ) ;
}
devno = S . st_dev ;
fp = setmntent ( MOUNTED , " r " ) ;
found = False ;
while ( ( mnt = getmntent ( fp ) ) ) {
1998-09-03 22:40:31 +04:00
if ( sys_stat ( mnt - > mnt_dir , & S ) = = - 1 )
1997-10-09 00:34:13 +04:00
continue ;
if ( S . st_dev = = devno ) {
found = True ;
break ;
}
}
endmntent ( fp ) ;
if ( ! found ) {
return ( False ) ;
}
euser_id = geteuid ( ) ;
1999-12-13 16:27:58 +03:00
save_re_uid ( ) ;
set_effective_uid ( 0 ) ;
1997-10-09 00:34:13 +04:00
/* Use softlimit to determine disk space, except when it has been exceeded */
* bsize = 512 ;
if ( 0 = = strcmp ( mnt - > mnt_type , " efs " ) )
{
r = quotactl ( Q_GETQUOTA , mnt - > mnt_fsname , euser_id , ( caddr_t ) & D ) ;
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
1997-11-17 22:16:38 +03:00
1997-10-09 00:34:13 +04:00
if ( r = = - 1 )
return ( False ) ;
/* Use softlimit to determine disk space, except when it has been exceeded */
if (
( D . dqb_bsoftlimit & & D . dqb_curblocks > = D . dqb_bsoftlimit ) | |
( D . dqb_bhardlimit & & D . dqb_curblocks > = D . dqb_bhardlimit ) | |
( D . dqb_fsoftlimit & & D . dqb_curfiles > = D . dqb_fsoftlimit ) | |
( D . dqb_fhardlimit & & D . dqb_curfiles > = D . dqb_fhardlimit )
)
{
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
}
else if ( D . dqb_bsoftlimit = = 0 & & D . dqb_bhardlimit = = 0 )
{
return ( False ) ;
}
else
{
* dfree = D . dqb_bsoftlimit - D . dqb_curblocks ;
* dsize = D . dqb_bsoftlimit ;
}
}
else if ( 0 = = strcmp ( mnt - > mnt_type , " xfs " ) )
{
r = quotactl ( Q_XGETQUOTA , mnt - > mnt_fsname , euser_id , ( caddr_t ) & F ) ;
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
1997-11-17 22:16:38 +03:00
1997-10-09 00:34:13 +04:00
if ( r = = - 1 )
return ( False ) ;
/* Use softlimit to determine disk space, except when it has been exceeded */
if (
( F . d_blk_softlimit & & F . d_bcount > = F . d_blk_softlimit ) | |
( F . d_blk_hardlimit & & F . d_bcount > = F . d_blk_hardlimit ) | |
( F . d_ino_softlimit & & F . d_icount > = F . d_ino_softlimit ) | |
( F . d_ino_hardlimit & & F . d_icount > = F . d_ino_hardlimit )
)
{
* dfree = 0 ;
1998-11-06 21:40:51 +03:00
* dsize = F . d_bcount ;
1997-10-09 00:34:13 +04:00
}
else if ( F . d_blk_softlimit = = 0 & & F . d_blk_hardlimit = = 0 )
{
return ( False ) ;
}
else
{
1998-11-06 21:40:51 +03:00
* dfree = ( F . d_blk_softlimit - F . d_bcount ) ;
* dsize = F . d_blk_softlimit ;
1997-10-09 00:34:13 +04:00
}
}
else
1997-11-17 22:16:38 +03:00
{
1999-12-13 16:27:58 +03:00
restore_re_uid ( ) ;
return ( False ) ;
1997-11-17 22:16:38 +03:00
}
1997-10-09 00:34:13 +04:00
return ( True ) ;
}
1996-05-05 15:25:33 +04:00
# else
1997-12-23 10:15:59 +03:00
# if defined(__FreeBSD__) || defined(__OpenBSD__)
1996-12-10 20:58:11 +03:00
# include <ufs/ufs/quota.h>
1997-10-09 00:34:13 +04:00
# include <machine/param.h>
1997-07-08 20:54:44 +04:00
# elif AIX
/* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */
# include <jfs/quota.h>
/* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */
# define dqb_curfiles dqb_curinodes
# define dqb_fhardlimit dqb_ihardlimit
# define dqb_fsoftlimit dqb_isoftlimit
1997-12-23 10:15:59 +03:00
# else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
1996-05-31 19:13:29 +04:00
# include <sys/quota.h>
# include <devnm.h>
1996-12-10 20:58:11 +03:00
# endif
1996-05-31 19:13:29 +04:00
1996-05-05 15:25:33 +04:00
/****************************************************************************
try to get the disk space from disk quotas - default version
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-06 21:40:51 +03:00
BOOL disk_quotas ( char * path , SMB_BIG_UINT * bsize , SMB_BIG_UINT * dfree , SMB_BIG_UINT * dsize )
1996-05-05 15:25:33 +04:00
{
int r ;
struct dqblk D ;
1999-12-13 16:27:58 +03:00
uid_t euser_id ;
1997-12-23 10:15:59 +03:00
# if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__)
1997-07-02 05:19:41 +04:00
char dev_disk [ 256 ] ;
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT S ;
1996-05-05 15:25:33 +04:00
/* find the block device file */
1998-09-03 22:40:31 +04:00
if ( ( sys_stat ( path , & S ) < 0 ) | |
1996-05-05 15:25:33 +04:00
( devnm ( S_IFBLK , S . st_dev , dev_disk , 256 , 0 ) < 0 ) ) return ( False ) ;
1996-12-10 20:58:11 +03:00
# endif
1996-05-05 15:25:33 +04:00
euser_id = geteuid ( ) ;
1998-07-29 07:08:05 +04:00
# ifdef HPUX
1999-12-13 16:27:58 +03:00
/* for HPUX, real uid must be same as euid to execute quotactl for euid */
save_re_uid ( ) ;
if ( set_re_uid ( ) ! = 0 ) return False ;
r = quotactl ( Q_GETQUOTA , dev_disk , euser_id , & D ) ;
restore_re_uid ( ) ;
1998-07-29 07:08:05 +04:00
# else
1997-12-23 10:15:59 +03:00
# if defined(__FreeBSD__) || defined(__OpenBSD__)
1997-10-09 00:34:13 +04:00
{
/* FreeBSD patches from Marty Moll <martym@arbor.edu> */
gid_t egrp_id ;
1999-12-13 16:27:58 +03:00
save_re_uid ( ) ;
set_effective_uid ( 0 ) ;
1997-10-09 00:34:13 +04:00
egrp_id = getegid ( ) ;
r = quotactl ( path , QCMD ( Q_GETQUOTA , USRQUOTA ) , euser_id , ( char * ) & D ) ;
/* As FreeBSD has group quotas, if getting the user
quota fails , try getting the group instead . */
1999-12-13 16:27:58 +03:00
if ( r ) {
r = quotactl ( path , QCMD ( Q_GETQUOTA , GRPQUOTA ) , egrp_id , ( char * ) & D ) ;
}
restore_re_uid ( ) ;
1997-10-09 00:34:13 +04:00
}
1997-07-08 20:54:44 +04:00
# elif defined(AIX)
/* AIX has both USER and GROUP quotas:
Get the USER quota ( ohnielse @ fysik . dtu . dk ) */
r = quotactl ( path , QCMD ( Q_GETQUOTA , USRQUOTA ) , euser_id , ( char * ) & D ) ;
1997-12-23 10:15:59 +03:00
# else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
1996-12-10 20:58:11 +03:00
r = quotactl ( Q_GETQUOTA , dev_disk , euser_id , & D ) ;
1997-12-23 10:15:59 +03:00
# endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
1999-12-13 16:27:58 +03:00
# endif /* HPUX */
1996-12-10 20:58:11 +03:00
1996-05-05 15:25:33 +04:00
/* Use softlimit to determine disk space, except when it has been exceeded */
1997-12-23 10:15:59 +03:00
# if defined(__FreeBSD__) || defined(__OpenBSD__)
1997-10-09 00:34:13 +04:00
* bsize = DEV_BSIZE ;
1997-12-23 10:15:59 +03:00
# else /* !__FreeBSD__ && !__OpenBSD__ */
1996-05-05 15:25:33 +04:00
* bsize = 1024 ;
1997-12-23 10:15:59 +03:00
# endif /*!__FreeBSD__ && !__OpenBSD__ */
1997-10-09 00:34:13 +04:00
1996-05-05 15:25:33 +04:00
if ( r )
{
if ( errno = = EDQUOT )
{
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
return ( True ) ;
}
else return ( False ) ;
}
1996-06-08 08:33:37 +04:00
if ( D . dqb_bsoftlimit = = 0 )
return ( False ) ;
1996-05-05 15:25:33 +04:00
/* Use softlimit to determine disk space, except when it has been exceeded */
1996-12-10 20:58:11 +03:00
if ( ( D . dqb_curblocks > D . dqb_bsoftlimit )
1997-12-23 10:15:59 +03:00
# if !defined(__FreeBSD__) && !defined(__OpenBSD__)
1997-07-18 00:11:58 +04:00
| | ( ( D . dqb_curfiles > D . dqb_fsoftlimit ) & & ( D . dqb_fsoftlimit ! = 0 ) )
1996-12-10 20:58:11 +03:00
# endif
) {
1996-05-05 15:25:33 +04:00
* dfree = 0 ;
* dsize = D . dqb_curblocks ;
}
else {
* dfree = D . dqb_bsoftlimit - D . dqb_curblocks ;
* dsize = D . dqb_bsoftlimit ;
}
return ( True ) ;
}
# endif