2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * This is one of the most system dependent parts of Samba, and its
25 * done a litle differently. Each system has its own way of doing
31 extern int DEBUGLEVEL
;
33 #if defined(VXFS_QUOTA)
36 * In addition to their native filesystems, some systems have Veritas VxFS.
37 * Declare here, define at end: reduces likely "include" interaction problems.
38 * David Lee <T.D.Lee@durham.ac.uk>
40 BOOL
disk_quotas_vxfs(const pstring name
, char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
);
42 #endif /* VXFS_QUOTA */
46 #include <sys/types.h>
47 #include <asm/types.h>
48 #include <sys/quota.h>
51 #include <linux/unistd.h>
53 _syscall4(int, quotactl
, int, cmd
, const char *, special
, int, id
, caddr_t
, addr
);
55 /****************************************************************************
56 try to get the disk space from disk quotas (LINUX version)
57 ****************************************************************************/
59 BOOL
disk_quotas(char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
72 /* find the block device file */
74 if ( sys_stat(path
, &S
) == -1 ) {
80 fp
= setmntent(MOUNTED
,"r");
83 while ((mnt
= getmntent(fp
))) {
84 if ( sys_stat(mnt
->mnt_dir
,&S
) == -1 )
86 if (S
.st_dev
== devno
) {
99 r
=quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), mnt
->mnt_fsname
, euser_id
, (caddr_t
)&D
);
102 /* Use softlimit to determine disk space, except when it has been exceeded */
109 *dsize
=D
.dqb_curblocks
;
114 /* Use softlimit to determine disk space, except when it has been exceeded */
116 (D
.dqb_bsoftlimit
&& D
.dqb_curblocks
>=D
.dqb_bsoftlimit
) ||
117 (D
.dqb_bhardlimit
&& D
.dqb_curblocks
>=D
.dqb_bhardlimit
) ||
118 (D
.dqb_isoftlimit
&& D
.dqb_curinodes
>=D
.dqb_isoftlimit
) ||
119 (D
.dqb_ihardlimit
&& D
.dqb_curinodes
>=D
.dqb_ihardlimit
)
123 *dsize
= D
.dqb_curblocks
;
125 else if (D
.dqb_bsoftlimit
==0 && D
.dqb_bhardlimit
==0)
130 if (D
.dqb_bsoftlimit
== 0)
131 D
.dqb_bsoftlimit
= D
.dqb_bhardlimit
;
132 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
133 *dsize
= D
.dqb_bsoftlimit
;
140 #include <sys/quota.h>
143 /****************************************************************************
144 try to get the disk space from disk quotas (CRAY VERSION)
145 ****************************************************************************/
147 BOOL
disk_quotas(char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
151 SMB_STRUCT_STAT sbuf
;
153 static SMB_DEV_T devno_cached
= 0 ;
155 struct q_request request
;
156 struct qf_header header
;
157 static int quota_default
= 0 ;
160 if ( sys_stat(path
,&sbuf
) == -1 )
163 devno
= sbuf
.st_dev
;
165 if ( devno
!= devno_cached
) {
167 devno_cached
= devno
;
169 if ((fd
= setmntent(KMTAB
)) == NULL
)
174 while ((mnt
= getmntent(fd
)) != NULL
) {
176 if ( sys_stat(mnt
->mnt_dir
,&sbuf
) == -1 )
179 if (sbuf
.st_dev
== devno
) {
188 pstrcpy(name
,mnt
->mnt_dir
) ;
195 request
.qf_magic
= QF_MAGIC
;
196 request
.qf_entry
.id
= geteuid() ;
198 if (quotactl(name
, Q_GETQUOTA
, &request
) == -1)
201 if ( ! request
.user
)
204 if ( request
.qf_entry
.user_q
.f_quota
== QFV_DEFAULT
) {
206 if ( ! quota_default
) {
208 if ( quotactl(name
, Q_GETHEADER
, &header
) == -1 )
211 quota_default
= header
.user_h
.def_fq
;
214 *dfree
= quota_default
;
216 }else if ( request
.qf_entry
.user_q
.f_quota
== QFV_PREVENT
) {
222 *dfree
= request
.qf_entry
.user_q
.f_quota
;
226 *dsize
= request
.qf_entry
.user_q
.f_use
;
228 if ( *dfree
< *dsize
)
233 *bsize
= 4096 ; /* Cray blocksize */
240 #elif defined(SUNOS5) || defined(SUNOS4)
243 #include <sys/param.h>
245 #include <sys/fs/ufs_quota.h>
246 #include <sys/mnttab.h>
247 #include <sys/mntent.h>
248 #else /* defined(SUNOS4) */
249 #include <ufs/quota.h>
255 /****************************************************************************
256 Allows querying of remote hosts for quotas on NFS mounted shares.
257 Supports normal NFS and AMD mounts.
258 Alan Romeril <a.romeril@ic.ac.uk> July 2K.
259 ****************************************************************************/
262 #include <rpc/types.h>
263 #include <rpcsvc/rquota.h>
264 #include <rpc/nettype.h>
267 static int quotastat
;
269 static int xdr_getquota_args(XDR
*xdrsp
, struct getquota_args
*args
)
271 if (!xdr_string(xdrsp
, &args
->gqa_pathp
, RQ_PATHLEN
))
273 if (!xdr_int(xdrsp
, &args
->gqa_uid
))
278 static int xdr_getquota_rslt(XDR
*xdrsp
, struct getquota_rslt
*gqr
)
280 if (!xdr_int(xdrsp
, "astat
)) {
281 DEBUG(6,("nfs_quotas: Status bad or zero\n"));
284 if (!xdr_int(xdrsp
, &gqr
->getquota_rslt_u
.gqr_rquota
.rq_bsize
)) {
285 DEBUG(6,("nfs_quotas: Block size bad or zero\n"));
288 if (!xdr_bool(xdrsp
, &gqr
->getquota_rslt_u
.gqr_rquota
.rq_active
)) {
289 DEBUG(6,("nfs_quotas: Active bad or zero\n"));
292 if (!xdr_int(xdrsp
, &gqr
->getquota_rslt_u
.gqr_rquota
.rq_bhardlimit
)) {
293 DEBUG(6,("nfs_quotas: Hardlimit bad or zero\n"));
296 if (!xdr_int(xdrsp
, &gqr
->getquota_rslt_u
.gqr_rquota
.rq_bsoftlimit
)) {
297 DEBUG(6,("nfs_quotas: Softlimit bad or zero\n"));
300 if (!xdr_int(xdrsp
, &gqr
->getquota_rslt_u
.gqr_rquota
.rq_curblocks
)) {
301 DEBUG(6,("nfs_quotas: Currentblocks bad or zero\n"));
307 /* Restricted to SUNOS5 for the moment, I haven`t access to others to test. */
308 static BOOL
nfs_quotas(char *nfspath
, uid_t euser_id
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
310 uid_t uid
= euser_id
;
312 char *mnttype
= nfspath
;
314 struct getquota_rslt gqr
;
315 struct getquota_args args
;
316 char *cutstr
, *pathname
, *host
, *testpath
;
318 static struct timeval timeout
= {2,0};
319 enum clnt_stat clnt_stat
;
322 *bsize
= *dfree
= *dsize
= (SMB_BIG_UINT
)0;
324 len
=strcspn(mnttype
, ":");
325 pathname
=strstr(mnttype
, ":");
326 cutstr
= (char *) malloc(sizeof(char) * len
);
330 host
= strncat(cutstr
,mnttype
, sizeof(char) * len
);
331 DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr
));
332 DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype
));
333 testpath
=strchr(mnttype
, ':');
334 args
.gqa_pathp
= testpath
+1;
337 DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\" network \"%s\"\n", host
, RQUOTAPROG
, RQUOTAVERS
, "udp"));
339 if ((clnt
= clnt_create(host
, RQUOTAPROG
, RQUOTAVERS
, "udp")) == NULL
) {
344 clnt
->cl_auth
= authunix_create_default();
345 DEBUG(9,("nfs_quotas: auth_success\n"));
347 clnt_stat
=clnt_call(clnt
, RQUOTAPROC_GETQUOTA
, xdr_getquota_args
, (caddr_t
)&args
, xdr_getquota_rslt
, (caddr_t
)&gqr
, timeout
);
349 if (clnt_stat
!= RPC_SUCCESS
) {
350 DEBUG(9,("nfs_quotas: clnt_call fail\n"));
356 * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is
357 * no quota set, and 3 if no permission to get the quota. If 0 or 3 return
358 * something sensible.
361 switch ( quotastat
) {
363 DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat
));
368 DEBUG(9,("nfs_quotas: Good quota data\n"));
369 D
.dqb_bsoftlimit
= gqr
.getquota_rslt_u
.gqr_rquota
.rq_bsoftlimit
;
370 D
.dqb_bhardlimit
= gqr
.getquota_rslt_u
.gqr_rquota
.rq_bhardlimit
;
371 D
.dqb_curblocks
= gqr
.getquota_rslt_u
.gqr_rquota
.rq_curblocks
;
376 D
.dqb_bsoftlimit
= 1;
378 DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat
));
382 DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat
));
386 DEBUG(10,("nfs_quotas: Let`s look at D a bit closer... status \"%i\" bsize \"%i\" active? \"%i\" bhard \"%i\" bsoft \"%i\" curb \"%i\" \n",
388 gqr
.getquota_rslt_u
.gqr_rquota
.rq_bsize
,
389 gqr
.getquota_rslt_u
.gqr_rquota
.rq_active
,
390 gqr
.getquota_rslt_u
.gqr_rquota
.rq_bhardlimit
,
391 gqr
.getquota_rslt_u
.gqr_rquota
.rq_bsoftlimit
,
392 gqr
.getquota_rslt_u
.gqr_rquota
.rq_curblocks
));
394 *bsize
= gqr
.getquota_rslt_u
.gqr_rquota
.rq_bsize
;
395 *dsize
= D
.dqb_bsoftlimit
;
397 if (D
.dqb_curblocks
== D
.dqb_curblocks
== 1)
400 if (D
.dqb_curblocks
> D
.dqb_bsoftlimit
) {
402 *dsize
= D
.dqb_curblocks
;
404 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
410 auth_destroy(clnt
->cl_auth
);
414 DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args
.gqa_pathp
,(double)*bsize
,(double)*dfree
,(double)*dsize
));
417 DEBUG(10,("nfs_quotas: End of nfs_quotas\n" ));
422 /****************************************************************************
423 try to get the disk space from disk quotas (SunOS & Solaris2 version)
424 Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).
425 ****************************************************************************/
427 BOOL
disk_quotas(char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
433 struct quotctl command
;
435 static struct mnttab mnt
;
443 SMB_STRUCT_STAT sbuf
;
445 static SMB_DEV_T devno_cached
= 0 ;
448 euser_id
= geteuid();
450 if ( sys_stat(path
,&sbuf
) == -1 )
453 devno
= sbuf
.st_dev
;
454 DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path
,(unsigned int)devno
));
455 if ( devno
!= devno_cached
) {
456 devno_cached
= devno
;
458 if ((fd
= sys_fopen(MNTTAB
, "r")) == NULL
)
462 slprintf(devopt
, sizeof(devopt
) - 1, "dev=%x", (unsigned int)devno
);
463 while (getmntent(fd
, &mnt
) == 0) {
464 if( !hasmntopt(&mnt
, devopt
) )
467 DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt
.mnt_mountp
,devopt
));
469 /* quotas are only on vxfs, UFS or NFS */
470 if ( strcmp( mnt
.mnt_fstype
, MNTTYPE_UFS
) == 0 ||
471 strcmp( mnt
.mnt_fstype
, "nfs" ) == 0 ||
472 strcmp( mnt
.mnt_fstype
, "vxfs" ) == 0 ) {
478 pstrcpy(name
,mnt
.mnt_mountp
) ;
479 pstrcat(name
,"/quotas") ;
482 if ((fd
= setmntent(MOUNTED
, "r")) == NULL
)
486 while ((mnt
= getmntent(fd
)) != NULL
) {
487 if ( sys_stat(mnt
->mnt_dir
,&sbuf
) == -1 )
489 DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt
->mnt_dir
,(unsigned int)sbuf
.st_dev
));
490 if (sbuf
.st_dev
== devno
) {
496 pstrcpy(name
,mnt
->mnt_fsname
) ;
505 set_effective_uid(0);
508 if ( strcmp( mnt
.mnt_fstype
, "nfs" ) == 0) {
510 DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt
.mnt_special
));
511 retval
= nfs_quotas(mnt
.mnt_special
, euser_id
, bsize
, dfree
, dsize
);
516 DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name
));
517 if((file
=sys_open(name
, O_RDONLY
,0))<0) {
521 command
.op
= Q_GETQUOTA
;
522 command
.uid
= euser_id
;
523 command
.addr
= (caddr_t
) &D
;
524 ret
= ioctl(file
, Q_QUOTACTL
, &command
);
527 DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name
));
528 ret
= quotactl(Q_GETQUOTA
, name
, euser_id
, &D
);
534 DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno
) ));
536 #if defined(SUNOS5) && defined(VXFS_QUOTA)
537 /* If normal quotactl() fails, try vxfs private calls */
538 set_effective_uid(euser_id
);
539 DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt
.mnt_fstype
));
540 if ( 0 == strcmp ( mnt
.mnt_fstype
, "vxfs" )) {
542 retval
= disk_quotas_vxfs(name
, path
, bsize
, dfree
, dsize
);
550 /* If softlimit is zero, set it equal to hardlimit.
553 if (D
.dqb_bsoftlimit
==0)
554 D
.dqb_bsoftlimit
= D
.dqb_bhardlimit
;
556 /* Use softlimit to determine disk space. A user exceeding the quota is told
557 * that there's no space left. Writes might actually work for a bit if the
558 * hardlimit is set higher than softlimit. Effectively the disk becomes
559 * made of rubber latex and begins to expand to accommodate the user :-)
562 if (D
.dqb_bsoftlimit
==0)
565 *dsize
= D
.dqb_bsoftlimit
;
567 if (D
.dqb_curblocks
> D
.dqb_bsoftlimit
) {
569 *dsize
= D
.dqb_curblocks
;
571 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
573 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
574 path
,(double)*bsize
,(double)*dfree
,(double)*dsize
));
581 #include <ufs/quota.h>
583 /****************************************************************************
584 try to get the disk space from disk quotas - OSF1 version
585 ****************************************************************************/
587 BOOL
disk_quotas(char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
595 * This code presumes that OSF1 will only
596 * give out quota info when the real uid
597 * matches the effective uid. JRA.
599 euser_id
= geteuid();
601 if (set_re_uid() != 0) return False
;
603 r
= quotactl(path
,QCMD(Q_GETQUOTA
, USRQUOTA
),euser_id
,(char *) &D
);
614 if (save_errno
== EDQUOT
) /* disk quota exceeded */
617 *dsize
= D
.dqb_curblocks
;
624 /* If softlimit is zero, set it equal to hardlimit.
627 if (D
.dqb_bsoftlimit
==0)
628 D
.dqb_bsoftlimit
= D
.dqb_bhardlimit
;
630 /* Use softlimit to determine disk space, except when it has been exceeded */
632 if (D
.dqb_bsoftlimit
==0)
635 if ((D
.dqb_curblocks
>D
.dqb_bsoftlimit
)) {
637 *dsize
= D
.dqb_curblocks
;
639 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
640 *dsize
= D
.dqb_bsoftlimit
;
645 #elif defined (IRIX6)
646 /****************************************************************************
647 try to get the disk space from disk quotas (IRIX 6.2 version)
648 ****************************************************************************/
650 #include <sys/quota.h>
653 BOOL
disk_quotas(char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
658 struct fs_disk_quota F
;
665 /* find the block device file */
667 if ( sys_stat(path
, &S
) == -1 ) {
673 fp
= setmntent(MOUNTED
,"r");
676 while ((mnt
= getmntent(fp
))) {
677 if ( sys_stat(mnt
->mnt_dir
,&S
) == -1 )
679 if (S
.st_dev
== devno
) {
692 set_effective_uid(0);
694 /* Use softlimit to determine disk space, except when it has been exceeded */
698 if ( 0 == strcmp ( mnt
->mnt_type
, "efs" ))
700 r
=quotactl (Q_GETQUOTA
, mnt
->mnt_fsname
, euser_id
, (caddr_t
) &D
);
707 /* Use softlimit to determine disk space, except when it has been exceeded */
709 (D
.dqb_bsoftlimit
&& D
.dqb_curblocks
>=D
.dqb_bsoftlimit
) ||
710 (D
.dqb_bhardlimit
&& D
.dqb_curblocks
>=D
.dqb_bhardlimit
) ||
711 (D
.dqb_fsoftlimit
&& D
.dqb_curfiles
>=D
.dqb_fsoftlimit
) ||
712 (D
.dqb_fhardlimit
&& D
.dqb_curfiles
>=D
.dqb_fhardlimit
)
716 *dsize
= D
.dqb_curblocks
;
718 else if (D
.dqb_bsoftlimit
==0 && D
.dqb_bhardlimit
==0)
724 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
725 *dsize
= D
.dqb_bsoftlimit
;
729 else if ( 0 == strcmp ( mnt
->mnt_type
, "xfs" ))
731 r
=quotactl (Q_XGETQUOTA
, mnt
->mnt_fsname
, euser_id
, (caddr_t
) &F
);
738 /* Use softlimit to determine disk space, except when it has been exceeded */
740 (F
.d_blk_softlimit
&& F
.d_bcount
>=F
.d_blk_softlimit
) ||
741 (F
.d_blk_hardlimit
&& F
.d_bcount
>=F
.d_blk_hardlimit
) ||
742 (F
.d_ino_softlimit
&& F
.d_icount
>=F
.d_ino_softlimit
) ||
743 (F
.d_ino_hardlimit
&& F
.d_icount
>=F
.d_ino_hardlimit
)
749 else if (F
.d_blk_softlimit
==0 && F
.d_blk_hardlimit
==0)
755 *dfree
= (F
.d_blk_softlimit
- F
.d_bcount
);
756 *dsize
= F
.d_blk_softlimit
;
772 #if defined(__FreeBSD__) || defined(__OpenBSD__)
773 #include <ufs/ufs/quota.h>
774 #include <machine/param.h>
776 /* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */
777 #include <jfs/quota.h>
778 /* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */
779 #define dqb_curfiles dqb_curinodes
780 #define dqb_fhardlimit dqb_ihardlimit
781 #define dqb_fsoftlimit dqb_isoftlimit
782 #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
783 #include <sys/quota.h>
787 /****************************************************************************
788 try to get the disk space from disk quotas - default version
789 ****************************************************************************/
791 BOOL
disk_quotas(char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
796 #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__)
799 /* find the block device file */
800 if ((sys_stat(path
, &S
)<0) ||
801 (devnm(S_IFBLK
, S
.st_dev
, dev_disk
, 256, 0)<0)) return (False
);
804 euser_id
= geteuid();
807 /* for HPUX, real uid must be same as euid to execute quotactl for euid */
809 if (set_re_uid() != 0) return False
;
811 r
=quotactl(Q_GETQUOTA
, dev_disk
, euser_id
, &D
);
815 #if defined(__FreeBSD__) || defined(__OpenBSD__)
817 /* FreeBSD patches from Marty Moll <martym@arbor.edu> */
821 set_effective_uid(0);
824 r
= quotactl(path
,QCMD(Q_GETQUOTA
,USRQUOTA
),euser_id
,(char *) &D
);
826 /* As FreeBSD has group quotas, if getting the user
827 quota fails, try getting the group instead. */
829 r
= quotactl(path
,QCMD(Q_GETQUOTA
,GRPQUOTA
),egrp_id
,(char *) &D
);
835 /* AIX has both USER and GROUP quotas:
836 Get the USER quota (ohnielse@fysik.dtu.dk) */
837 r
= quotactl(path
,QCMD(Q_GETQUOTA
,USRQUOTA
),euser_id
,(char *) &D
);
838 #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
839 r
=quotactl(Q_GETQUOTA
, dev_disk
, euser_id
, &D
);
840 #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
843 /* Use softlimit to determine disk space, except when it has been exceeded */
844 #if defined(__FreeBSD__) || defined(__OpenBSD__)
846 #else /* !__FreeBSD__ && !__OpenBSD__ */
848 #endif /*!__FreeBSD__ && !__OpenBSD__ */
855 *dsize
=D
.dqb_curblocks
;
861 /* If softlimit is zero, set it equal to hardlimit.
864 if (D
.dqb_bsoftlimit
==0)
865 D
.dqb_bsoftlimit
= D
.dqb_bhardlimit
;
867 if (D
.dqb_bsoftlimit
==0)
869 /* Use softlimit to determine disk space, except when it has been exceeded */
870 if ((D
.dqb_curblocks
>D
.dqb_bsoftlimit
)
871 #if !defined(__FreeBSD__) && !defined(__OpenBSD__)
872 ||((D
.dqb_curfiles
>D
.dqb_fsoftlimit
) && (D
.dqb_fsoftlimit
!= 0))
876 *dsize
= D
.dqb_curblocks
;
879 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
880 *dsize
= D
.dqb_bsoftlimit
;
887 #if defined(VXFS_QUOTA)
889 /****************************************************************************
890 Try to get the disk space from Veritas disk quotas.
891 David Lee <T.D.Lee@durham.ac.uk> August 1999.
893 Background assumptions:
894 Potentially under many Operating Systems. Initially Solaris 2.
896 My guess is that Veritas is largely, though not entirely,
897 independent of OS. So I have separated it out.
899 There may be some details. For example, OS-specific "include" files.
901 It is understood that HPUX 10 somehow gets Veritas quotas without
902 any special effort; if so, this routine need not be compiled in.
903 Dirk De Wachter <Dirk.DeWachter@rug.ac.be>
906 It is understood that Veritas do not publicly support this ioctl interface.
907 Rather their preference would be for the user (us) to call the native
908 OS and then for the OS itself to call through to the VxFS filesystem.
909 Presumably HPUX 10, see above, does this.
912 Add your OS to "IFLIST" below.
913 Get it to compile successfully:
914 Almost certainly "include"s require attention: see SUNOS5.
915 In the main code above, arrange for it to be called: see SUNOS5.
918 ****************************************************************************/
921 * This "if" is a list of ports:
922 * if defined(OS1) || defined(OS2) || ...
927 #include <sys/fs/vx_solaris.h>
929 #include <sys/fs/vx_machdep.h>
930 #include <sys/fs/vx_layout.h>
931 #include <sys/fs/vx_quota.h>
932 #include <sys/fs/vx_aioctl.h>
933 #include <sys/fs/vx_ioctl.h>
935 BOOL
disk_quotas_vxfs(const pstring name
, char *path
, SMB_BIG_UINT
*bsize
, SMB_BIG_UINT
*dfree
, SMB_BIG_UINT
*dsize
)
937 uid_t user_id
, euser_id
;
940 struct vx_quotctl quotabuf
;
941 struct vx_genioctl genbuf
;
946 * "name" may or may not include a trailing "/quotas".
947 * Arranging consistency of calling here in "quotas.c" may not be easy and
948 * it might be easier to examine and adjust it here.
949 * Fortunately, VxFS seems not to mind at present.
951 pstrcpy(qfname
, name
) ;
952 /* pstrcat(qfname, "/quotas") ; */ /* possibly examine and adjust "name" */
954 euser_id
= geteuid();
955 set_effective_uid(0);
957 DEBUG(5,("disk_quotas: looking for VxFS quotas file \"%s\"\n", qfname
));
958 if((file
=sys_open(qfname
, O_RDONLY
,0))<0) {
959 set_effective_uid(euser_id
);
962 genbuf
.ioc_cmd
= VX_QUOTACTL
;
963 genbuf
.ioc_up
= (void *) "abuf
;
965 quotabuf
.cmd
= VX_GETQUOTA
;
966 quotabuf
.uid
= euser_id
;
967 quotabuf
.addr
= (caddr_t
) &D
;
968 ret
= ioctl(file
, VX_ADMIN_IOCTL
, &genbuf
);
971 set_effective_uid(euser_id
);
974 DEBUG(5,("disk_quotas ioctl (VxFS) failed. Error = %s\n", strerror(errno
) ));
978 /* If softlimit is zero, set it equal to hardlimit.
981 if (D
.dqb_bsoftlimit
==0)
982 D
.dqb_bsoftlimit
= D
.dqb_bhardlimit
;
984 /* Use softlimit to determine disk space. A user exceeding the quota is told
985 * that there's no space left. Writes might actually work for a bit if the
986 * hardlimit is set higher than softlimit. Effectively the disk becomes
987 * made of rubber latex and begins to expand to accommodate the user :-)
989 DEBUG(5,("disk_quotas for path \"%s\" block c/s/h %ld/%ld/%ld; file c/s/h %ld/%ld/%ld\n",
990 path
, D
.dqb_curblocks
, D
.dqb_bsoftlimit
, D
.dqb_bhardlimit
,
991 D
.dqb_curfiles
, D
.dqb_fsoftlimit
, D
.dqb_fhardlimit
));
993 if (D
.dqb_bsoftlimit
==0)
996 *dsize
= D
.dqb_bsoftlimit
;
998 if (D
.dqb_curblocks
> D
.dqb_bsoftlimit
) {
1000 *dsize
= D
.dqb_curblocks
;
1002 *dfree
= D
.dqb_bsoftlimit
- D
.dqb_curblocks
;
1004 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
1005 path
,(double)*bsize
,(double)*dfree
,(double)*dsize
));
1010 #endif /* SUNOS5 || ... */
1012 #endif /* VXFS_QUOTA */