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
37 # include <sys/quota.h>
40 # include <sys/quota.h>
45 /****************************************************************************
46 try to get the disk space from disk quotas (LINUX version)
47 ****************************************************************************/
49 If you didn't make the symlink to the quota package, too bad :(
51 #include "quota/quotactl.c"
52 #include "quota/hasquota.c"
53 static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
65 /* find the block device file */
67 if ( stat(path, &S) == -1 )
72 fp = setmntent(MOUNTED,"r");
75 while ((mnt = getmntent(fp)) != (struct mntent *) 0) {
76 if ( stat(mnt->mnt_dir,&S) == -1 )
78 if (S.st_dev == devno) {
88 qcmd = QCMD(Q_GETQUOTA, USRQUOTA);
90 if (hasmntopt(mnt, MNTOPT_NOAUTO) || hasmntopt(mnt, MNTOPT_NOQUOTA))
93 if (!hasquota(mnt, USRQUOTA, &qfpathname))
99 if (quotactl(qcmd, mnt->mnt_fsname, euser_id, (caddr_t)&D) != 0) {
100 if ((fd = open(qfpathname, O_RDONLY)) < 0) {
104 lseek(fd, (long) dqoff(euser_id), L_SET);
105 switch (read(fd, &D, sizeof(struct dqblk))) {
107 memset((caddr_t)&D, 0, sizeof(struct dqblk));
109 case sizeof(struct dqblk): /* OK */
120 if (D.dqb_bsoftlimit==0)
122 if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curinodes>D.dqb_isoftlimit))
125 *dsize = D.dqb_curblocks;
128 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
129 *dsize = D.dqb_bsoftlimit;
136 #include <sys/quota.h>
139 /****************************************************************************
140 try to get the disk space from disk quotas (CRAY VERSION)
141 ****************************************************************************/
142 static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
148 static dev_t devno_cached = 0 ;
149 static char name[MNTMAXSTR] ;
150 struct q_request request ;
151 struct qf_header header ;
152 static int quota_default = 0 ;
155 if ( stat(path,&sbuf) == -1 )
158 devno = sbuf.st_dev ;
160 if ( devno != devno_cached ) {
162 devno_cached = devno ;
164 if ((fd = setmntent(KMTAB)) == NULL)
169 while ((mnt = getmntent(fd)) != NULL) {
171 if ( stat(mnt->mnt_dir,&sbuf) == -1 )
174 if (sbuf.st_dev == devno) {
183 strcpy(name,mnt->mnt_dir) ;
190 request.qf_magic = QF_MAGIC ;
191 request.qf_entry.id = geteuid() ;
193 if (quotactl(name, Q_GETQUOTA, &request) == -1)
196 if ( ! request.user )
199 if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
201 if ( ! quota_default ) {
203 if ( quotactl(name, Q_GETHEADER, &header) == -1 )
206 quota_default = header.user_h.def_fq ;
209 *dfree = quota_default ;
211 }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
217 *dfree = request.qf_entry.user_q.f_quota ;
221 *dsize = request.qf_entry.user_q.f_use ;
229 *bsize = 4096 ; /* Cray blocksize */
236 #elif defined(SUNOS5)
240 #include <sys/fs/ufs_quota.h>
242 /****************************************************************************
243 try to get the disk space from disk quotas (solaris 2 version)
244 ****************************************************************************/
245 /* Quota code by Peter Urbanec (amiga@cse.unsw.edu.au) */
246 static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
248 uid_t user_id, euser_id;
251 struct quotctl command;
255 if((file=open(path, O_RDONLY))<0) return(False);
257 euser_id = geteuid();
260 command.op = Q_GETQUOTA;
261 command.uid = euser_id;
262 command.addr = (caddr_t) &D;
264 setuid(0); /* Solaris seems to want to give info only to super-user */
267 ret = ioctl(file, Q_QUOTACTL, &command);
269 setuid(user_id); /* Restore the original UID status */
274 DEBUG(2,("disk_quotas ioctl (Solaris) failed\n"));
280 /* Use softlimit to determine disk space. A user exceeding the quota is told
281 * that there's no space left. Writes might actually work for a bit if the
282 * hardlimit is set higher than softlimit. Effectively the disk becomes
283 * made of rubber latex and begins to expand to accommodate the user :-)
287 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
288 *dsize = D.dqb_bsoftlimit;
292 *dsize = D.dqb_curblocks;
295 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %d, dfree %d, dsize %d\n",
296 path,*bsize,*dfree,*dsize));
303 #include <sys/quota.h>
306 /****************************************************************************
307 try to get the disk space from disk quotas - default version
308 ****************************************************************************/
309 static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
311 uid_t user_id, euser_id;
316 /* find the block device file */
317 if ((stat(path, &S)<0) ||
318 (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) return (False);
320 euser_id = geteuid();
323 /* for HPUX, real uid must be same as euid to execute quotactl for euid */
325 setresuid(euser_id,-1,-1);
327 r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
329 if (setresuid(user_id,-1,-1))
330 DEBUG(5,("Unable to reset uid to %d\n", user_id));
332 /* Use softlimit to determine disk space, except when it has been exceeded */
339 *dsize =D.dqb_curblocks;
344 /* Use softlimit to determine disk space, except when it has been exceeded */
345 if ((D.dqb_curblocks>D.dqb_bsoftlimit)||(D.dqb_curfiles>D.dqb_fsoftlimit))
348 *dsize = D.dqb_curblocks;
351 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
352 *dsize = D.dqb_bsoftlimit;