This commit was manufactured by cvs2svn to create branch 'SAMBA_TNG'.
[Samba.git] / source / smbd / quotas.c
blob1e81443c5efb2cd6bdc64b70aea043c78d18f707
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 support for quotas
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.
23 /*
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
26 * things :-(
29 #include "includes.h"
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 */
44 #ifdef LINUX
46 #include <sys/types.h>
47 #include <asm/types.h>
48 #include <sys/quota.h>
50 #include <mntent.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)
61 int r;
62 struct dqblk D;
63 SMB_STRUCT_STAT S;
64 FILE *fp;
65 struct mntent *mnt;
66 SMB_DEV_T devno;
67 int found;
68 uid_t euser_id;
70 euser_id = geteuid();
72 /* find the block device file */
74 if ( sys_stat(path, &S) == -1 ) {
75 return(False) ;
78 devno = S.st_dev ;
80 fp = setmntent(MOUNTED,"r");
81 found = False ;
83 while ((mnt = getmntent(fp))) {
84 if ( sys_stat(mnt->mnt_dir,&S) == -1 )
85 continue ;
86 if (S.st_dev == devno) {
87 found = True ;
88 break ;
91 endmntent(fp) ;
93 if (!found) {
94 return(False);
97 save_re_uid();
98 set_effective_uid(0);
99 r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D);
100 restore_re_uid();
102 /* Use softlimit to determine disk space, except when it has been exceeded */
103 *bsize = 1024;
104 if (r)
106 if (errno == EDQUOT)
108 *dfree =0;
109 *dsize =D.dqb_curblocks;
110 return (True);
112 else return(False);
114 /* Use softlimit to determine disk space, except when it has been exceeded */
115 if (
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)
122 *dfree = 0;
123 *dsize = D.dqb_curblocks;
125 else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
127 return(False);
129 else {
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;
135 return (True);
138 #elif defined(CRAY)
140 #include <sys/quota.h>
141 #include <mntent.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)
149 struct mntent *mnt;
150 FILE *fd;
151 SMB_STRUCT_STAT sbuf;
152 SMB_DEV_T devno ;
153 static SMB_DEV_T devno_cached = 0 ;
154 static pstring name;
155 struct q_request request ;
156 struct qf_header header ;
157 static int quota_default = 0 ;
158 int found ;
160 if ( sys_stat(path,&sbuf) == -1 )
161 return(False) ;
163 devno = sbuf.st_dev ;
165 if ( devno != devno_cached ) {
167 devno_cached = devno ;
169 if ((fd = setmntent(KMTAB)) == NULL)
170 return(False) ;
172 found = False ;
174 while ((mnt = getmntent(fd)) != NULL) {
176 if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
177 continue ;
179 if (sbuf.st_dev == devno) {
181 found = True ;
182 break ;
188 pstrcpy(name,mnt->mnt_dir) ;
189 endmntent(fd) ;
191 if ( ! found )
192 return(False) ;
195 request.qf_magic = QF_MAGIC ;
196 request.qf_entry.id = geteuid() ;
198 if (quotactl(name, Q_GETQUOTA, &request) == -1)
199 return(False) ;
201 if ( ! request.user )
202 return(False) ;
204 if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
206 if ( ! quota_default ) {
208 if ( quotactl(name, Q_GETHEADER, &header) == -1 )
209 return(False) ;
210 else
211 quota_default = header.user_h.def_fq ;
214 *dfree = quota_default ;
216 }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
218 *dfree = 0 ;
220 }else{
222 *dfree = request.qf_entry.user_q.f_quota ;
226 *dsize = request.qf_entry.user_q.f_use ;
228 if ( *dfree < *dsize )
229 *dfree = 0 ;
230 else
231 *dfree -= *dsize ;
233 *bsize = 4096 ; /* Cray blocksize */
235 return(True) ;
240 #elif defined(SUNOS5) || defined(SUNOS4)
242 #include <fcntl.h>
243 #include <sys/param.h>
244 #if defined(SUNOS5)
245 #include <sys/fs/ufs_quota.h>
246 #include <sys/mnttab.h>
247 #else /* defined(SUNOS4) */
248 #include <ufs/quota.h>
249 #include <mntent.h>
250 #endif
252 /****************************************************************************
253 try to get the disk space from disk quotas (SunOS & Solaris2 version)
254 Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).
255 ****************************************************************************/
257 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
259 uid_t euser_id;
260 int ret;
261 struct dqblk D;
262 #if defined(SUNOS5)
263 struct quotctl command;
264 int file;
265 static struct mnttab mnt;
266 static pstring name;
267 #else /* SunOS4 */
268 struct mntent *mnt;
269 static pstring name;
270 #endif
271 FILE *fd;
272 SMB_STRUCT_STAT sbuf;
273 SMB_DEV_T devno ;
274 static SMB_DEV_T devno_cached = 0 ;
275 int found ;
277 euser_id = geteuid();
279 if ( sys_stat(path,&sbuf) == -1 )
280 return(False) ;
282 devno = sbuf.st_dev ;
283 DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%o\n", path,devno));
284 if ( devno != devno_cached ) {
285 devno_cached = devno ;
286 #if defined(SUNOS5)
287 if ((fd = sys_fopen(MNTTAB, "r")) == NULL)
288 return(False) ;
290 found = False ;
291 while (getmntent(fd, &mnt) == 0) {
292 if ( sys_stat(mnt.mnt_mountp,&sbuf) == -1 )
293 continue ;
294 DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n",
295 mnt.mnt_mountp,sbuf.st_dev));
296 if (sbuf.st_dev == devno) {
297 found = True ;
298 break ;
302 pstrcpy(name,mnt.mnt_mountp) ;
303 pstrcat(name,"/quotas") ;
304 fclose(fd) ;
305 #else /* SunOS4 */
306 if ((fd = setmntent(MOUNTED, "r")) == NULL)
307 return(False) ;
309 found = False ;
310 while ((mnt = getmntent(fd)) != NULL) {
311 if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
312 continue ;
313 DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n",
314 mnt->mnt_dir,sbuf.st_dev));
315 if (sbuf.st_dev == devno) {
316 found = True ;
317 break ;
321 pstrcpy(name,mnt->mnt_fsname) ;
322 endmntent(fd) ;
323 #endif
325 if ( ! found )
326 return(False) ;
329 save_re_uid();
330 set_effective_uid(0);
332 #if defined(SUNOS5)
333 DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
334 if((file=sys_open(name, O_RDONLY,0))<0) {
335 restore_re_uid();
336 return(False);
338 command.op = Q_GETQUOTA;
339 command.uid = euser_id;
340 command.addr = (caddr_t) &D;
341 ret = ioctl(file, Q_QUOTACTL, &command);
342 close(file);
343 #else
344 DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name));
345 ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
346 #endif
348 restore_re_uid();
350 if (ret < 0) {
351 DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));
353 #if defined(SUNOS5) && defined(VXFS_QUOTA)
354 /* If normal quotactl() fails, try vxfs private calls */
355 set_effective_uid(euser_id);
356 DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype));
357 if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) {
358 ret = disk_quotas_vxfs(name, path, bsize, dfree, dsize);
359 return(ret);
361 #else
362 return(False);
363 #endif
366 /* If softlimit is zero, set it equal to hardlimit.
369 if (D.dqb_bsoftlimit==0)
370 D.dqb_bsoftlimit = D.dqb_bhardlimit;
372 /* Use softlimit to determine disk space. A user exceeding the quota is told
373 * that there's no space left. Writes might actually work for a bit if the
374 * hardlimit is set higher than softlimit. Effectively the disk becomes
375 * made of rubber latex and begins to expand to accommodate the user :-)
378 if (D.dqb_bsoftlimit==0)
379 return(False);
380 *bsize = DEV_BSIZE;
381 *dsize = D.dqb_bsoftlimit;
383 if (D.dqb_curblocks > D.dqb_bsoftlimit) {
384 *dfree = 0;
385 *dsize = D.dqb_curblocks;
386 } else
387 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
389 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
390 path,(double)*bsize,(double)*dfree,(double)*dsize));
392 return(True);
396 #elif defined(OSF1)
397 #include <ufs/quota.h>
399 /****************************************************************************
400 try to get the disk space from disk quotas - OSF1 version
401 ****************************************************************************/
403 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
405 int r, save_errno;
406 struct dqblk D;
407 SMB_STRUCT_STAT S;
408 uid_t euser_id;
411 * This code presumes that OSF1 will only
412 * give out quota info when the real uid
413 * matches the effective uid. JRA.
415 euser_id = geteuid();
416 save_re_uid();
417 if (set_re_uid() != 0) return False;
419 r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D);
420 if (r) {
421 save_errno = errno;
424 restore_re_uid();
426 *bsize = DEV_BSIZE;
428 if (r)
430 if (save_errno == EDQUOT) // disk quota exceeded
432 *dfree = 0;
433 *dsize = D.dqb_curblocks;
434 return (True);
436 else
437 return (False);
440 /* If softlimit is zero, set it equal to hardlimit.
443 if (D.dqb_bsoftlimit==0)
444 D.dqb_bsoftlimit = D.dqb_bhardlimit;
446 /* Use softlimit to determine disk space, except when it has been exceeded */
448 if (D.dqb_bsoftlimit==0)
449 return(False);
451 if ((D.dqb_curblocks>D.dqb_bsoftlimit)) {
452 *dfree = 0;
453 *dsize = D.dqb_curblocks;
454 } else {
455 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
456 *dsize = D.dqb_bsoftlimit;
458 return (True);
461 #elif defined (IRIX6)
462 /****************************************************************************
463 try to get the disk space from disk quotas (IRIX 6.2 version)
464 ****************************************************************************/
466 #include <sys/quota.h>
467 #include <mntent.h>
469 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
471 uid_t euser_id;
472 int r;
473 struct dqblk D;
474 struct fs_disk_quota F;
475 SMB_STRUCT_STAT S;
476 FILE *fp;
477 struct mntent *mnt;
478 SMB_DEV_T devno;
479 int found;
481 /* find the block device file */
483 if ( sys_stat(path, &S) == -1 ) {
484 return(False) ;
487 devno = S.st_dev ;
489 fp = setmntent(MOUNTED,"r");
490 found = False ;
492 while ((mnt = getmntent(fp))) {
493 if ( sys_stat(mnt->mnt_dir,&S) == -1 )
494 continue ;
495 if (S.st_dev == devno) {
496 found = True ;
497 break ;
500 endmntent(fp) ;
502 if (!found) {
503 return(False);
506 euser_id=geteuid();
507 save_re_uid();
508 set_effective_uid(0);
510 /* Use softlimit to determine disk space, except when it has been exceeded */
512 *bsize = 512;
514 if ( 0 == strcmp ( mnt->mnt_type, "efs" ))
516 r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);
518 restore_re_uid();
520 if (r==-1)
521 return(False);
523 /* Use softlimit to determine disk space, except when it has been exceeded */
524 if (
525 (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
526 (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
527 (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) ||
528 (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit)
531 *dfree = 0;
532 *dsize = D.dqb_curblocks;
534 else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
536 return(False);
538 else
540 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
541 *dsize = D.dqb_bsoftlimit;
545 else if ( 0 == strcmp ( mnt->mnt_type, "xfs" ))
547 r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);
549 restore_re_uid();
551 if (r==-1)
552 return(False);
554 /* Use softlimit to determine disk space, except when it has been exceeded */
555 if (
556 (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
557 (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) ||
558 (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) ||
559 (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit)
562 *dfree = 0;
563 *dsize = F.d_bcount;
565 else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
567 return(False);
569 else
571 *dfree = (F.d_blk_softlimit - F.d_bcount);
572 *dsize = F.d_blk_softlimit;
576 else
578 restore_re_uid();
579 return(False);
582 return (True);
586 #else
588 #if defined(__FreeBSD__) || defined(__OpenBSD__)
589 #include <ufs/ufs/quota.h>
590 #include <machine/param.h>
591 #elif AIX
592 /* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */
593 #include <jfs/quota.h>
594 /* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */
595 #define dqb_curfiles dqb_curinodes
596 #define dqb_fhardlimit dqb_ihardlimit
597 #define dqb_fsoftlimit dqb_isoftlimit
598 #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
599 #include <sys/quota.h>
600 #include <devnm.h>
601 #endif
603 /****************************************************************************
604 try to get the disk space from disk quotas - default version
605 ****************************************************************************/
607 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
609 int r;
610 struct dqblk D;
611 uid_t euser_id;
612 #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__)
613 char dev_disk[256];
614 SMB_STRUCT_STAT S;
615 /* find the block device file */
616 if ((sys_stat(path, &S)<0) ||
617 (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) return (False);
618 #endif
620 euser_id = geteuid();
622 #ifdef HPUX
623 /* for HPUX, real uid must be same as euid to execute quotactl for euid */
624 save_re_uid();
625 if (set_re_uid() != 0) return False;
627 r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
629 restore_re_uid();
630 #else
631 #if defined(__FreeBSD__) || defined(__OpenBSD__)
633 /* FreeBSD patches from Marty Moll <martym@arbor.edu> */
634 gid_t egrp_id;
636 save_re_uid();
637 set_effective_uid(0);
639 egrp_id = getegid();
640 r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
642 /* As FreeBSD has group quotas, if getting the user
643 quota fails, try getting the group instead. */
644 if (r) {
645 r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
648 restore_re_uid();
650 #elif defined(AIX)
651 /* AIX has both USER and GROUP quotas:
652 Get the USER quota (ohnielse@fysik.dtu.dk) */
653 r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
654 #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
655 r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
656 #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
657 #endif /* HPUX */
659 /* Use softlimit to determine disk space, except when it has been exceeded */
660 #if defined(__FreeBSD__) || defined(__OpenBSD__)
661 *bsize = DEV_BSIZE;
662 #else /* !__FreeBSD__ && !__OpenBSD__ */
663 *bsize = 1024;
664 #endif /*!__FreeBSD__ && !__OpenBSD__ */
666 if (r)
668 if (errno == EDQUOT)
670 *dfree =0;
671 *dsize =D.dqb_curblocks;
672 return (True);
674 else return(False);
677 /* If softlimit is zero, set it equal to hardlimit.
680 if (D.dqb_bsoftlimit==0)
681 D.dqb_bsoftlimit = D.dqb_bhardlimit;
683 if (D.dqb_bsoftlimit==0)
684 return(False);
685 /* Use softlimit to determine disk space, except when it has been exceeded */
686 if ((D.dqb_curblocks>D.dqb_bsoftlimit)
687 #if !defined(__FreeBSD__) && !defined(__OpenBSD__)
688 ||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0))
689 #endif
691 *dfree = 0;
692 *dsize = D.dqb_curblocks;
694 else {
695 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
696 *dsize = D.dqb_bsoftlimit;
698 return (True);
701 #endif
703 #if defined(VXFS_QUOTA)
705 /****************************************************************************
706 Try to get the disk space from Veritas disk quotas.
707 David Lee <T.D.Lee@durham.ac.uk> August 1999.
709 Background assumptions:
710 Potentially under many Operating Systems. Initially Solaris 2.
712 My guess is that Veritas is largely, though not entirely,
713 independent of OS. So I have separated it out.
715 There may be some details. For example, OS-specific "include" files.
717 It is understood that HPUX 10 somehow gets Veritas quotas without
718 any special effort; if so, this routine need not be compiled in.
719 Dirk De Wachter <Dirk.DeWachter@rug.ac.be>
721 Warning:
722 It is understood that Veritas do not publicly support this ioctl interface.
723 Rather their preference would be for the user (us) to call the native
724 OS and then for the OS itself to call through to the VxFS filesystem.
725 Presumably HPUX 10, see above, does this.
727 Hints for porting:
728 Add your OS to "IFLIST" below.
729 Get it to compile successfully:
730 Almost certainly "include"s require attention: see SUNOS5.
731 In the main code above, arrange for it to be called: see SUNOS5.
732 Test!
734 ****************************************************************************/
736 /* "IFLIST"
737 * This "if" is a list of ports:
738 * if defined(OS1) || defined(OS2) || ...
740 #if defined(SUNOS5)
742 #if defined(SUNOS5)
743 #include <sys/fs/vx_solaris.h>
744 #endif
745 #include <sys/fs/vx_machdep.h>
746 #include <sys/fs/vx_layout.h>
747 #include <sys/fs/vx_quota.h>
748 #include <sys/fs/vx_aioctl.h>
749 #include <sys/fs/vx_ioctl.h>
751 BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
753 uid_t user_id, euser_id;
754 int ret;
755 struct vx_dqblk D;
756 struct vx_quotctl quotabuf;
757 struct vx_genioctl genbuf;
758 pstring qfname;
759 int file;
762 * "name" may or may not include a trailing "/quotas".
763 * Arranging consistency of calling here in "quotas.c" may not be easy and
764 * it might be easier to examine and adjust it here.
765 * Fortunately, VxFS seems not to mind at present.
767 pstrcpy(qfname, name) ;
768 /* pstrcat(qfname, "/quotas") ; */ /* possibly examine and adjust "name" */
770 euser_id = geteuid();
771 set_effective_uid(0);
773 DEBUG(5,("disk_quotas: looking for VxFS quotas file \"%s\"\n", qfname));
774 if((file=sys_open(qfname, O_RDONLY,0))<0) {
775 set_effective_uid(euser_id);
776 return(False);
778 genbuf.ioc_cmd = VX_QUOTACTL;
779 genbuf.ioc_up = (void *) &quotabuf;
781 quotabuf.cmd = VX_GETQUOTA;
782 quotabuf.uid = euser_id;
783 quotabuf.addr = (caddr_t) &D;
784 ret = ioctl(file, VX_ADMIN_IOCTL, &genbuf);
785 close(file);
787 set_effective_uid(euser_id);
789 if (ret < 0) {
790 DEBUG(5,("disk_quotas ioctl (VxFS) failed. Error = %s\n", strerror(errno) ));
791 return(False);
794 /* If softlimit is zero, set it equal to hardlimit.
797 if (D.dqb_bsoftlimit==0)
798 D.dqb_bsoftlimit = D.dqb_bhardlimit;
800 /* Use softlimit to determine disk space. A user exceeding the quota is told
801 * that there's no space left. Writes might actually work for a bit if the
802 * hardlimit is set higher than softlimit. Effectively the disk becomes
803 * made of rubber latex and begins to expand to accommodate the user :-)
805 DEBUG(5,("disk_quotas for path \"%s\" block c/s/h %ld/%ld/%ld; file c/s/h %ld/%ld/%ld\n",
806 path, D.dqb_curblocks, D.dqb_bsoftlimit, D.dqb_bhardlimit,
807 D.dqb_curfiles, D.dqb_fsoftlimit, D.dqb_fhardlimit));
809 if (D.dqb_bsoftlimit==0)
810 return(False);
811 *bsize = DEV_BSIZE;
812 *dsize = D.dqb_bsoftlimit;
814 if (D.dqb_curblocks > D.dqb_bsoftlimit) {
815 *dfree = 0;
816 *dsize = D.dqb_curblocks;
817 } else
818 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
820 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
821 path,(double)*bsize,(double)*dfree,(double)*dsize));
823 return(True);
826 #endif /* SUNOS5 || ... */
828 #endif /* VXFS_QUOTA */