3 Unix SMB/Netbios implementation.
6 Copyright (C) Andrew Tridgell 1992-1995
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * This is one of the most system dependent parts of Samba, and its
26 * done a litle differently. Each system has its own way of doing
32 extern int DEBUGLEVEL;
38 # include <sys/quota.h>
41 # include <sys/quota.h>
46 /****************************************************************************
47 try to get the disk space from disk quotas (LINUX version)
48 ****************************************************************************/
50 If you didn't make the symlink to the quota package, too bad :(
52 #include "quota/quotactl.c"
53 #include "quota/hasquota.c"
54 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
66 /* find the block device file */
68 if ( stat(path, &S) == -1 )
73 fp = setmntent(MOUNTED,"r");
76 while ((mnt = getmntent(fp)) != (struct mntent *) 0) {
77 if ( stat(mnt->mnt_dir,&S) == -1 )
79 if (S.st_dev == devno) {
89 qcmd = QCMD(Q_GETQUOTA, USRQUOTA);
91 if (hasmntopt(mnt, MNTOPT_NOAUTO) || hasmntopt(mnt, MNTOPT_NOQUOTA))
94 if (!hasquota(mnt, USRQUOTA, &qfpathname))
100 if (quotactl(qcmd, mnt->mnt_fsname, euser_id, (caddr_t)&D) != 0) {
101 if ((fd = open(qfpathname, O_RDONLY)) < 0) {
105 lseek(fd, (long) dqoff(euser_id), L_SET);
106 switch (read(fd, &D, sizeof(struct dqblk))) {
108 memset((caddr_t)&D, 0, sizeof(struct dqblk));
110 case sizeof(struct dqblk): /* OK */
121 if (D.dqb_bsoftlimit==0)
123 if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curinodes>D.dqb_isoftlimit))
126 *dsize = D.dqb_curblocks;
129 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
130 *dsize = D.dqb_bsoftlimit;
137 #include <sys/quota.h>
140 /****************************************************************************
141 try to get the disk space from disk quotas (CRAY VERSION)
142 ****************************************************************************/
143 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
149 static dev_t devno_cached = 0 ;
150 static char name[MNTMAXSTR] ;
151 struct q_request request ;
152 struct qf_header header ;
153 static int quota_default = 0 ;
156 if ( stat(path,&sbuf) == -1 )
159 devno = sbuf.st_dev ;
161 if ( devno != devno_cached ) {
163 devno_cached = devno ;
165 if ((fd = setmntent(KMTAB)) == NULL)
170 while ((mnt = getmntent(fd)) != NULL) {
172 if ( stat(mnt->mnt_dir,&sbuf) == -1 )
175 if (sbuf.st_dev == devno) {
184 strcpy(name,mnt->mnt_dir) ;
191 request.qf_magic = QF_MAGIC ;
192 request.qf_entry.id = geteuid() ;
194 if (quotactl(name, Q_GETQUOTA, &request) == -1)
197 if ( ! request.user )
200 if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
202 if ( ! quota_default ) {
204 if ( quotactl(name, Q_GETHEADER, &header) == -1 )
207 quota_default = header.user_h.def_fq ;
210 *dfree = quota_default ;
212 }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
218 *dfree = request.qf_entry.user_q.f_quota ;
222 *dsize = request.qf_entry.user_q.f_use ;
230 *bsize = 4096 ; /* Cray blocksize */
237 #elif defined(SUNOS5) || defined(SUNOS4)
241 #include <sys/fs/ufs_quota.h>
242 #include <sys/mnttab.h>
243 #else /* defined(SUNOS4) */
244 #include <ufs/quota.h>
248 /****************************************************************************
249 try to get the disk space from disk quotas (solaris 2 version)
250 ****************************************************************************/
251 /* Quota code by Peter Urbanec (amiga@cse.unsw.edu.au) */
252 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
254 uid_t user_id, euser_id;
258 struct quotctl command;
261 static char name[MNT_LINE_MAX] ;
264 static char name[MNTMAXSTR] ;
269 static dev_t devno_cached = 0 ;
272 if ( stat(path,&sbuf) == -1 )
275 devno = sbuf.st_dev ;
276 DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%o\n", path,devno));
277 if ( devno != devno_cached ) {
278 devno_cached = devno ;
280 if ((fd = fopen(MNTTAB, "r")) == NULL)
284 while (getmntent(fd, &mnt) == 0) {
285 if ( stat(mnt.mnt_mountp,&sbuf) == -1 )
287 DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n", mnt.mnt_mountp,sbuf.st_dev));
288 if (sbuf.st_dev == devno) {
294 strcpy(name,mnt.mnt_mountp) ;
295 strcat(name,"/quotas") ;
298 if ((fd = setmntent(MOUNTED, "r")) == NULL)
302 while ((mnt = getmntent(fd)) != NULL) {
303 if ( stat(mnt->mnt_dir,&sbuf) == -1 )
305 DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n", mnt->mnt_dir,sbuf.st_dev));
306 if (sbuf.st_dev == devno) {
312 strcpy(name,mnt->mnt_fsname) ;
320 euser_id = geteuid();
323 setuid(0); /* Solaris seems to want to give info only to super-user */
327 DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
328 if((file=open(name, O_RDONLY))<0) {
329 setuid(user_id); /* Restore the original UID status */
333 command.op = Q_GETQUOTA;
334 command.uid = euser_id;
335 command.addr = (caddr_t) &D;
336 ret = ioctl(file, Q_QUOTACTL, &command);
339 DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name));
340 ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
343 setuid(user_id); /* Restore the original UID status */
347 DEBUG(2,("disk_quotas ioctl (Solaris) failed\n"));
352 /* Use softlimit to determine disk space. A user exceeding the quota is told
353 * that there's no space left. Writes might actually work for a bit if the
354 * hardlimit is set higher than softlimit. Effectively the disk becomes
355 * made of rubber latex and begins to expand to accommodate the user :-)
358 if (D.dqb_bsoftlimit==0)
361 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
362 *dsize = D.dqb_bsoftlimit;
366 *dsize = D.dqb_curblocks;
369 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %d, dfree %d, dsize %d\n",
370 path,*bsize,*dfree,*dsize));
377 #include <sys/quota.h>
380 /****************************************************************************
381 try to get the disk space from disk quotas - default version
382 ****************************************************************************/
383 BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
385 uid_t user_id, euser_id;
390 /* find the block device file */
391 if ((stat(path, &S)<0) ||
392 (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) return (False);
394 euser_id = geteuid();
397 /* for HPUX, real uid must be same as euid to execute quotactl for euid */
399 setresuid(euser_id,-1,-1);
401 r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
403 if (setresuid(user_id,-1,-1))
404 DEBUG(5,("Unable to reset uid to %d\n", user_id));
406 /* Use softlimit to determine disk space, except when it has been exceeded */
413 *dsize =D.dqb_curblocks;
418 if (D.dqb_bsoftlimit==0)
420 /* Use softlimit to determine disk space, except when it has been exceeded */
421 if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curfiles>D.dqb_fsoftlimit))
424 *dsize = D.dqb_curblocks;
427 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
428 *dsize = D.dqb_bsoftlimit;
436 /* this keeps fussy compilers happy */
437 void quotas_dummy(void) {}