116c2ba93SPeter Wemm /* 216c2ba93SPeter Wemm * Copyright (C) 1991, 1994 Wolfgang Solfrank. 316c2ba93SPeter Wemm * Copyright (C) 1991, 1994 TooLs GmbH. 416c2ba93SPeter Wemm * All rights reserved. 516c2ba93SPeter Wemm * 616c2ba93SPeter Wemm * Redistribution and use in source and binary forms, with or without 716c2ba93SPeter Wemm * modification, are permitted provided that the following conditions 816c2ba93SPeter Wemm * are met: 916c2ba93SPeter Wemm * 1. Redistributions of source code must retain the above copyright 1016c2ba93SPeter Wemm * notice, this list of conditions and the following disclaimer. 1116c2ba93SPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 1216c2ba93SPeter Wemm * notice, this list of conditions and the following disclaimer in the 1316c2ba93SPeter Wemm * documentation and/or other materials provided with the distribution. 1416c2ba93SPeter Wemm * 3. All advertising materials mentioning features or use of this software 1516c2ba93SPeter Wemm * must display the following acknowledgement: 1616c2ba93SPeter Wemm * This product includes software developed by TooLs GmbH. 1716c2ba93SPeter Wemm * 4. The name of TooLs GmbH may not be used to endorse or promote products 1816c2ba93SPeter Wemm * derived from this software without specific prior written permission. 1916c2ba93SPeter Wemm * 2016c2ba93SPeter Wemm * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 2116c2ba93SPeter Wemm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2216c2ba93SPeter Wemm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2316c2ba93SPeter Wemm * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2416c2ba93SPeter Wemm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2516c2ba93SPeter Wemm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2616c2ba93SPeter Wemm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2716c2ba93SPeter Wemm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2816c2ba93SPeter Wemm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2916c2ba93SPeter Wemm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3016c2ba93SPeter Wemm */ 3116c2ba93SPeter Wemm 3216c2ba93SPeter Wemm #ifndef lint 336980f0ebSPhilippe Charnier static const char rcsid[] = 349983067eSMatthew Dillon "$Id: quot.c,v 1.8 1998/01/17 16:45:03 bde Exp $"; 3516c2ba93SPeter Wemm #endif /* not lint */ 3616c2ba93SPeter Wemm 3716c2ba93SPeter Wemm #include <sys/param.h> 3816c2ba93SPeter Wemm #include <sys/mount.h> 3916c2ba93SPeter Wemm #include <sys/time.h> 4016c2ba93SPeter Wemm #include <ufs/ffs/fs.h> 4116c2ba93SPeter Wemm #include <ufs/ufs/quota.h> 4216c2ba93SPeter Wemm #include <ufs/ufs/inode.h> 4316c2ba93SPeter Wemm 446980f0ebSPhilippe Charnier #include <err.h> 456980f0ebSPhilippe Charnier #include <fcntl.h> 466980f0ebSPhilippe Charnier #include <errno.h> 476980f0ebSPhilippe Charnier #include <pwd.h> 4816c2ba93SPeter Wemm #include <stdio.h> 4916c2ba93SPeter Wemm #include <stdlib.h> 5016c2ba93SPeter Wemm #include <string.h> 516980f0ebSPhilippe Charnier #include <unistd.h> 5216c2ba93SPeter Wemm 5316c2ba93SPeter Wemm /* some flags of what to do: */ 5416c2ba93SPeter Wemm static char estimate; 5516c2ba93SPeter Wemm static char count; 5616c2ba93SPeter Wemm static char unused; 576980f0ebSPhilippe Charnier static void (*func)(); 5816c2ba93SPeter Wemm static long blocksize; 5916c2ba93SPeter Wemm static char *header; 6016c2ba93SPeter Wemm static int headerlen; 6116c2ba93SPeter Wemm 6216c2ba93SPeter Wemm /* 6316c2ba93SPeter Wemm * Original BSD quot doesn't round to number of frags/blocks, 6416c2ba93SPeter Wemm * doesn't account for indirection blocks and gets it totally 6516c2ba93SPeter Wemm * wrong if the size is a multiple of the blocksize. 6616c2ba93SPeter Wemm * The new code always counts the number of 512 byte blocks 6716c2ba93SPeter Wemm * instead of the number of kilobytes and converts them to 6816c2ba93SPeter Wemm * kByte when done (on request). 699983067eSMatthew Dillon * 709983067eSMatthew Dillon * Due to the size of modern disks, we must cast intermediate 719983067eSMatthew Dillon * values to 64 bits to prevent potential overflows. 7216c2ba93SPeter Wemm */ 7316c2ba93SPeter Wemm #ifdef COMPAT 7416c2ba93SPeter Wemm #define SIZE(n) (n) 7516c2ba93SPeter Wemm #else 769983067eSMatthew Dillon #define SIZE(n) ((int)(((quad_t)(n) * 512 + blocksize - 1)/blocksize)) 7716c2ba93SPeter Wemm #endif 7816c2ba93SPeter Wemm 7916c2ba93SPeter Wemm #define INOCNT(fs) ((fs)->fs_ipg) 8016c2ba93SPeter Wemm #define INOSZ(fs) (sizeof(struct dinode) * INOCNT(fs)) 8116c2ba93SPeter Wemm 826980f0ebSPhilippe Charnier static struct dinode * 836980f0ebSPhilippe Charnier get_inode(fd,super,ino) 8416c2ba93SPeter Wemm struct fs *super; 8516c2ba93SPeter Wemm ino_t ino; 8616c2ba93SPeter Wemm { 8716c2ba93SPeter Wemm static struct dinode *ip; 8816c2ba93SPeter Wemm static ino_t last; 8916c2ba93SPeter Wemm 9016c2ba93SPeter Wemm if (fd < 0) { /* flush cache */ 9116c2ba93SPeter Wemm if (ip) { 9216c2ba93SPeter Wemm free(ip); 9316c2ba93SPeter Wemm ip = 0; 9416c2ba93SPeter Wemm } 9516c2ba93SPeter Wemm return 0; 9616c2ba93SPeter Wemm } 9716c2ba93SPeter Wemm 9816c2ba93SPeter Wemm if (!ip || ino < last || ino >= last + INOCNT(super)) { 9916c2ba93SPeter Wemm if (!ip 1006980f0ebSPhilippe Charnier && !(ip = (struct dinode *)malloc(INOSZ(super)))) 1016980f0ebSPhilippe Charnier errx(1, "allocate inodes"); 10216c2ba93SPeter Wemm last = (ino / INOCNT(super)) * INOCNT(super); 103c9d12677SJordan K. Hubbard if (lseek(fd, (off_t)ino_to_fsba(super, last) << super->fs_fshift, 0) < (off_t)0 1046980f0ebSPhilippe Charnier || read(fd,ip,INOSZ(super)) != INOSZ(super)) 1056980f0ebSPhilippe Charnier err(1, "read inodes"); 10616c2ba93SPeter Wemm } 10716c2ba93SPeter Wemm 10816c2ba93SPeter Wemm return ip + ino % INOCNT(super); 10916c2ba93SPeter Wemm } 11016c2ba93SPeter Wemm 11116c2ba93SPeter Wemm #ifdef COMPAT 11216c2ba93SPeter Wemm #define actualblocks(super,ip) ((ip)->di_blocks/2) 11316c2ba93SPeter Wemm #else 11416c2ba93SPeter Wemm #define actualblocks(super,ip) ((ip)->di_blocks) 11516c2ba93SPeter Wemm #endif 11616c2ba93SPeter Wemm 1176980f0ebSPhilippe Charnier static int virtualblocks(super,ip) 11816c2ba93SPeter Wemm struct fs *super; 11916c2ba93SPeter Wemm struct dinode *ip; 12016c2ba93SPeter Wemm { 12116c2ba93SPeter Wemm register off_t nblk, sz; 12216c2ba93SPeter Wemm 12316c2ba93SPeter Wemm sz = ip->di_size; 12416c2ba93SPeter Wemm #ifdef COMPAT 12516c2ba93SPeter Wemm if (lblkno(super,sz) >= NDADDR) { 12616c2ba93SPeter Wemm nblk = blkroundup(super,sz); 12716c2ba93SPeter Wemm if (sz == nblk) 12816c2ba93SPeter Wemm nblk += super->fs_bsize; 12916c2ba93SPeter Wemm } 13016c2ba93SPeter Wemm 13116c2ba93SPeter Wemm return sz / 1024; 13216c2ba93SPeter Wemm 13316c2ba93SPeter Wemm #else /* COMPAT */ 13416c2ba93SPeter Wemm 13516c2ba93SPeter Wemm if (lblkno(super,sz) >= NDADDR) { 13616c2ba93SPeter Wemm nblk = blkroundup(super,sz); 13716c2ba93SPeter Wemm sz = lblkno(super,nblk); 13816c2ba93SPeter Wemm sz = (sz - NDADDR + NINDIR(super) - 1) / NINDIR(super); 13916c2ba93SPeter Wemm while (sz > 0) { 14016c2ba93SPeter Wemm nblk += sz * super->fs_bsize; 14116c2ba93SPeter Wemm /* sz - 1 rounded up */ 14216c2ba93SPeter Wemm sz = (sz - 1 + NINDIR(super) - 1) / NINDIR(super); 14316c2ba93SPeter Wemm } 14416c2ba93SPeter Wemm } else 14516c2ba93SPeter Wemm nblk = fragroundup(super,sz); 14616c2ba93SPeter Wemm 14716c2ba93SPeter Wemm return nblk / 512; 14816c2ba93SPeter Wemm #endif /* COMPAT */ 14916c2ba93SPeter Wemm } 15016c2ba93SPeter Wemm 1516980f0ebSPhilippe Charnier static int 1526980f0ebSPhilippe Charnier isfree(ip) 15316c2ba93SPeter Wemm struct dinode *ip; 15416c2ba93SPeter Wemm { 15516c2ba93SPeter Wemm #ifdef COMPAT 15616c2ba93SPeter Wemm return (ip->di_mode&IFMT) == 0; 15716c2ba93SPeter Wemm #else /* COMPAT */ 15816c2ba93SPeter Wemm 15916c2ba93SPeter Wemm switch (ip->di_mode&IFMT) { 16016c2ba93SPeter Wemm case IFIFO: 16116c2ba93SPeter Wemm case IFLNK: /* should check FASTSYMLINK? */ 16216c2ba93SPeter Wemm case IFDIR: 16316c2ba93SPeter Wemm case IFREG: 16416c2ba93SPeter Wemm return 0; 16516c2ba93SPeter Wemm default: 16616c2ba93SPeter Wemm return 1; 16716c2ba93SPeter Wemm } 16816c2ba93SPeter Wemm #endif 16916c2ba93SPeter Wemm } 17016c2ba93SPeter Wemm 17116c2ba93SPeter Wemm static struct user { 17216c2ba93SPeter Wemm uid_t uid; 17316c2ba93SPeter Wemm char *name; 17416c2ba93SPeter Wemm daddr_t space; 17516c2ba93SPeter Wemm long count; 17616c2ba93SPeter Wemm daddr_t spc30; 17716c2ba93SPeter Wemm daddr_t spc60; 17816c2ba93SPeter Wemm daddr_t spc90; 17916c2ba93SPeter Wemm } *users; 18016c2ba93SPeter Wemm static int nusers; 18116c2ba93SPeter Wemm 1826980f0ebSPhilippe Charnier static void 1836980f0ebSPhilippe Charnier inituser() 18416c2ba93SPeter Wemm { 18516c2ba93SPeter Wemm register i; 18616c2ba93SPeter Wemm register struct user *usr; 18716c2ba93SPeter Wemm 18816c2ba93SPeter Wemm if (!nusers) { 18916c2ba93SPeter Wemm nusers = 8; 19016c2ba93SPeter Wemm if (!(users = 1916980f0ebSPhilippe Charnier (struct user *)calloc(nusers,sizeof(struct user)))) 1926980f0ebSPhilippe Charnier errx(1, "allocate users"); 19316c2ba93SPeter Wemm } else { 19416c2ba93SPeter Wemm for (usr = users, i = nusers; --i >= 0; usr++) { 19516c2ba93SPeter Wemm usr->space = usr->spc30 = usr->spc60 = usr->spc90 = 0; 19616c2ba93SPeter Wemm usr->count = 0; 19716c2ba93SPeter Wemm } 19816c2ba93SPeter Wemm } 19916c2ba93SPeter Wemm } 20016c2ba93SPeter Wemm 2016980f0ebSPhilippe Charnier static void 2026980f0ebSPhilippe Charnier usrrehash() 20316c2ba93SPeter Wemm { 20416c2ba93SPeter Wemm register i; 20516c2ba93SPeter Wemm register struct user *usr, *usrn; 20616c2ba93SPeter Wemm struct user *svusr; 20716c2ba93SPeter Wemm 20816c2ba93SPeter Wemm svusr = users; 20916c2ba93SPeter Wemm nusers <<= 1; 2106980f0ebSPhilippe Charnier if (!(users = (struct user *)calloc(nusers,sizeof(struct user)))) 2116980f0ebSPhilippe Charnier errx(1, "allocate users"); 21216c2ba93SPeter Wemm for (usr = svusr, i = nusers >> 1; --i >= 0; usr++) { 21316c2ba93SPeter Wemm for (usrn = users + (usr->uid&(nusers - 1)); usrn->name; 21416c2ba93SPeter Wemm usrn--) { 21516c2ba93SPeter Wemm if (usrn <= users) 21616c2ba93SPeter Wemm usrn = users + nusers; 21716c2ba93SPeter Wemm } 21816c2ba93SPeter Wemm *usrn = *usr; 21916c2ba93SPeter Wemm } 22016c2ba93SPeter Wemm } 22116c2ba93SPeter Wemm 2226980f0ebSPhilippe Charnier static struct user * 2236980f0ebSPhilippe Charnier user(uid) 22416c2ba93SPeter Wemm uid_t uid; 22516c2ba93SPeter Wemm { 22616c2ba93SPeter Wemm register struct user *usr; 22716c2ba93SPeter Wemm register i; 22816c2ba93SPeter Wemm struct passwd *pwd; 22916c2ba93SPeter Wemm 23016c2ba93SPeter Wemm while (1) { 23116c2ba93SPeter Wemm for (usr = users + (uid&(nusers - 1)), i = nusers; --i >= 0; 23216c2ba93SPeter Wemm usr--) { 23316c2ba93SPeter Wemm if (!usr->name) { 23416c2ba93SPeter Wemm usr->uid = uid; 23516c2ba93SPeter Wemm 23616c2ba93SPeter Wemm if (!(pwd = getpwuid(uid))) { 2376980f0ebSPhilippe Charnier if ((usr->name = (char *)malloc(7))) 23816c2ba93SPeter Wemm sprintf(usr->name,"#%d",uid); 23916c2ba93SPeter Wemm } else { 2406980f0ebSPhilippe Charnier if ((usr->name = (char *) 2416980f0ebSPhilippe Charnier malloc(strlen(pwd->pw_name) + 1))) 24216c2ba93SPeter Wemm strcpy(usr->name,pwd->pw_name); 24316c2ba93SPeter Wemm } 2446980f0ebSPhilippe Charnier if (!usr->name) 2456980f0ebSPhilippe Charnier errx(1, "allocate users"); 24616c2ba93SPeter Wemm 24716c2ba93SPeter Wemm return usr; 24816c2ba93SPeter Wemm 24916c2ba93SPeter Wemm } else if (usr->uid == uid) 25016c2ba93SPeter Wemm return usr; 25116c2ba93SPeter Wemm 25216c2ba93SPeter Wemm if (usr <= users) 25316c2ba93SPeter Wemm usr = users + nusers; 25416c2ba93SPeter Wemm } 25516c2ba93SPeter Wemm usrrehash(); 25616c2ba93SPeter Wemm } 25716c2ba93SPeter Wemm } 25816c2ba93SPeter Wemm 2596980f0ebSPhilippe Charnier static int 2606980f0ebSPhilippe Charnier cmpusers(u1,u2) 26116c2ba93SPeter Wemm struct user *u1, *u2; 26216c2ba93SPeter Wemm { 26316c2ba93SPeter Wemm return u2->space - u1->space; 26416c2ba93SPeter Wemm } 26516c2ba93SPeter Wemm 26616c2ba93SPeter Wemm #define sortusers(users) (qsort((users),nusers,sizeof(struct user), \ 26716c2ba93SPeter Wemm cmpusers)) 26816c2ba93SPeter Wemm 2696980f0ebSPhilippe Charnier static void 2706980f0ebSPhilippe Charnier uses(uid,blks,act) 27116c2ba93SPeter Wemm uid_t uid; 27216c2ba93SPeter Wemm daddr_t blks; 27316c2ba93SPeter Wemm time_t act; 27416c2ba93SPeter Wemm { 27516c2ba93SPeter Wemm static time_t today; 27616c2ba93SPeter Wemm register struct user *usr; 27716c2ba93SPeter Wemm 27816c2ba93SPeter Wemm if (!today) 27916c2ba93SPeter Wemm time(&today); 28016c2ba93SPeter Wemm 28116c2ba93SPeter Wemm usr = user(uid); 28216c2ba93SPeter Wemm usr->count++; 28316c2ba93SPeter Wemm usr->space += blks; 28416c2ba93SPeter Wemm 28516c2ba93SPeter Wemm if (today - act > 90L * 24L * 60L * 60L) 28616c2ba93SPeter Wemm usr->spc90 += blks; 28716c2ba93SPeter Wemm if (today - act > 60L * 24L * 60L * 60L) 28816c2ba93SPeter Wemm usr->spc60 += blks; 28916c2ba93SPeter Wemm if (today - act > 30L * 24L * 60L * 60L) 29016c2ba93SPeter Wemm usr->spc30 += blks; 29116c2ba93SPeter Wemm } 29216c2ba93SPeter Wemm 29316c2ba93SPeter Wemm #ifdef COMPAT 29416c2ba93SPeter Wemm #define FSZCNT 500 29516c2ba93SPeter Wemm #else 29616c2ba93SPeter Wemm #define FSZCNT 512 29716c2ba93SPeter Wemm #endif 29816c2ba93SPeter Wemm struct fsizes { 29916c2ba93SPeter Wemm struct fsizes *fsz_next; 30016c2ba93SPeter Wemm daddr_t fsz_first, fsz_last; 30116c2ba93SPeter Wemm ino_t fsz_count[FSZCNT]; 30216c2ba93SPeter Wemm daddr_t fsz_sz[FSZCNT]; 30316c2ba93SPeter Wemm } *fsizes; 30416c2ba93SPeter Wemm 3056980f0ebSPhilippe Charnier static void 3066980f0ebSPhilippe Charnier initfsizes() 30716c2ba93SPeter Wemm { 30816c2ba93SPeter Wemm register struct fsizes *fp; 30916c2ba93SPeter Wemm register i; 31016c2ba93SPeter Wemm 31116c2ba93SPeter Wemm for (fp = fsizes; fp; fp = fp->fsz_next) { 31216c2ba93SPeter Wemm for (i = FSZCNT; --i >= 0;) { 31316c2ba93SPeter Wemm fp->fsz_count[i] = 0; 31416c2ba93SPeter Wemm fp->fsz_sz[i] = 0; 31516c2ba93SPeter Wemm } 31616c2ba93SPeter Wemm } 31716c2ba93SPeter Wemm } 31816c2ba93SPeter Wemm 3196980f0ebSPhilippe Charnier static void 3206980f0ebSPhilippe Charnier dofsizes(fd,super,name) 32116c2ba93SPeter Wemm struct fs *super; 32216c2ba93SPeter Wemm char *name; 32316c2ba93SPeter Wemm { 32416c2ba93SPeter Wemm ino_t inode, maxino; 32516c2ba93SPeter Wemm struct dinode *ip; 32616c2ba93SPeter Wemm daddr_t sz, ksz; 32716c2ba93SPeter Wemm struct fsizes *fp, **fsp; 32816c2ba93SPeter Wemm register i; 32916c2ba93SPeter Wemm 33016c2ba93SPeter Wemm maxino = super->fs_ncg * super->fs_ipg - 1; 33116c2ba93SPeter Wemm #ifdef COMPAT 3326980f0ebSPhilippe Charnier if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) 3336980f0ebSPhilippe Charnier errx(1, "alloc fsize structure"); 33416c2ba93SPeter Wemm #endif /* COMPAT */ 33516c2ba93SPeter Wemm for (inode = 0; inode < maxino; inode++) { 33616c2ba93SPeter Wemm errno = 0; 33716c2ba93SPeter Wemm if ((ip = get_inode(fd,super,inode)) 33816c2ba93SPeter Wemm #ifdef COMPAT 33916c2ba93SPeter Wemm && ((ip->di_mode&IFMT) == IFREG 34016c2ba93SPeter Wemm || (ip->di_mode&IFMT) == IFDIR) 34116c2ba93SPeter Wemm #else /* COMPAT */ 34216c2ba93SPeter Wemm && !isfree(ip) 34316c2ba93SPeter Wemm #endif /* COMPAT */ 34416c2ba93SPeter Wemm ) { 34516c2ba93SPeter Wemm sz = estimate ? virtualblocks(super,ip) : 34616c2ba93SPeter Wemm actualblocks(super,ip); 34716c2ba93SPeter Wemm #ifdef COMPAT 34816c2ba93SPeter Wemm if (sz >= FSZCNT) { 34916c2ba93SPeter Wemm fsizes->fsz_count[FSZCNT-1]++; 35016c2ba93SPeter Wemm fsizes->fsz_sz[FSZCNT-1] += sz; 35116c2ba93SPeter Wemm } else { 35216c2ba93SPeter Wemm fsizes->fsz_count[sz]++; 35316c2ba93SPeter Wemm fsizes->fsz_sz[sz] += sz; 35416c2ba93SPeter Wemm } 35516c2ba93SPeter Wemm #else /* COMPAT */ 35616c2ba93SPeter Wemm ksz = SIZE(sz); 3576980f0ebSPhilippe Charnier for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) { 35816c2ba93SPeter Wemm if (ksz < fp->fsz_last) 35916c2ba93SPeter Wemm break; 36016c2ba93SPeter Wemm } 36116c2ba93SPeter Wemm if (!fp || ksz < fp->fsz_first) { 36216c2ba93SPeter Wemm if (!(fp = (struct fsizes *) 3636980f0ebSPhilippe Charnier malloc(sizeof(struct fsizes)))) 3646980f0ebSPhilippe Charnier errx(1, "alloc fsize structure"); 36516c2ba93SPeter Wemm fp->fsz_next = *fsp; 36616c2ba93SPeter Wemm *fsp = fp; 36716c2ba93SPeter Wemm fp->fsz_first = (ksz / FSZCNT) * FSZCNT; 36816c2ba93SPeter Wemm fp->fsz_last = fp->fsz_first + FSZCNT; 36916c2ba93SPeter Wemm for (i = FSZCNT; --i >= 0;) { 37016c2ba93SPeter Wemm fp->fsz_count[i] = 0; 37116c2ba93SPeter Wemm fp->fsz_sz[i] = 0; 37216c2ba93SPeter Wemm } 37316c2ba93SPeter Wemm } 37416c2ba93SPeter Wemm fp->fsz_count[ksz % FSZCNT]++; 37516c2ba93SPeter Wemm fp->fsz_sz[ksz % FSZCNT] += sz; 37616c2ba93SPeter Wemm #endif /* COMPAT */ 37716c2ba93SPeter Wemm } else if (errno) { 3786980f0ebSPhilippe Charnier err(1, "%s", name); 37916c2ba93SPeter Wemm } 38016c2ba93SPeter Wemm } 38116c2ba93SPeter Wemm sz = 0; 38216c2ba93SPeter Wemm for (fp = fsizes; fp; fp = fp->fsz_next) { 38316c2ba93SPeter Wemm for (i = 0; i < FSZCNT; i++) { 38416c2ba93SPeter Wemm if (fp->fsz_count[i]) 38516c2ba93SPeter Wemm printf("%d\t%d\t%d\n",fp->fsz_first + i, 38616c2ba93SPeter Wemm fp->fsz_count[i], 38716c2ba93SPeter Wemm SIZE(sz += fp->fsz_sz[i])); 38816c2ba93SPeter Wemm } 38916c2ba93SPeter Wemm } 39016c2ba93SPeter Wemm } 39116c2ba93SPeter Wemm 3926980f0ebSPhilippe Charnier static void 3936980f0ebSPhilippe Charnier douser(fd,super,name) 39416c2ba93SPeter Wemm struct fs *super; 39516c2ba93SPeter Wemm char *name; 39616c2ba93SPeter Wemm { 39716c2ba93SPeter Wemm ino_t inode, maxino; 39816c2ba93SPeter Wemm struct user *usr, *usrs; 39916c2ba93SPeter Wemm struct dinode *ip; 40016c2ba93SPeter Wemm register n; 40116c2ba93SPeter Wemm 40216c2ba93SPeter Wemm maxino = super->fs_ncg * super->fs_ipg - 1; 40316c2ba93SPeter Wemm for (inode = 0; inode < maxino; inode++) { 40416c2ba93SPeter Wemm errno = 0; 40516c2ba93SPeter Wemm if ((ip = get_inode(fd,super,inode)) 40616c2ba93SPeter Wemm && !isfree(ip)) 40716c2ba93SPeter Wemm uses(ip->di_uid, 40816c2ba93SPeter Wemm estimate ? virtualblocks(super,ip) : 40916c2ba93SPeter Wemm actualblocks(super,ip), 41016c2ba93SPeter Wemm ip->di_atime); 41116c2ba93SPeter Wemm else if (errno) { 4126980f0ebSPhilippe Charnier err(1, "%s", name); 41316c2ba93SPeter Wemm } 41416c2ba93SPeter Wemm } 4156980f0ebSPhilippe Charnier if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) 4166980f0ebSPhilippe Charnier errx(1, "allocate users"); 41716c2ba93SPeter Wemm bcopy(users,usrs,nusers * sizeof(struct user)); 41816c2ba93SPeter Wemm sortusers(usrs); 41916c2ba93SPeter Wemm for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) { 42016c2ba93SPeter Wemm printf("%5d",SIZE(usr->space)); 42116c2ba93SPeter Wemm if (count) 42216c2ba93SPeter Wemm printf("\t%5d",usr->count); 42316c2ba93SPeter Wemm printf("\t%-8s",usr->name); 42416c2ba93SPeter Wemm if (unused) 42516c2ba93SPeter Wemm printf("\t%5d\t%5d\t%5d", 42616c2ba93SPeter Wemm SIZE(usr->spc30), 42716c2ba93SPeter Wemm SIZE(usr->spc60), 42816c2ba93SPeter Wemm SIZE(usr->spc90)); 42916c2ba93SPeter Wemm printf("\n"); 43016c2ba93SPeter Wemm } 43116c2ba93SPeter Wemm free(usrs); 43216c2ba93SPeter Wemm } 43316c2ba93SPeter Wemm 4346980f0ebSPhilippe Charnier static void 4356980f0ebSPhilippe Charnier donames(fd,super,name) 43616c2ba93SPeter Wemm struct fs *super; 43716c2ba93SPeter Wemm char *name; 43816c2ba93SPeter Wemm { 43916c2ba93SPeter Wemm int c; 44016c2ba93SPeter Wemm ino_t inode, inode1; 44116c2ba93SPeter Wemm ino_t maxino; 44216c2ba93SPeter Wemm struct dinode *ip; 44316c2ba93SPeter Wemm 44416c2ba93SPeter Wemm maxino = super->fs_ncg * super->fs_ipg - 1; 44516c2ba93SPeter Wemm /* first skip the name of the filesystem */ 44616c2ba93SPeter Wemm while ((c = getchar()) != EOF && (c < '0' || c > '9')) 44716c2ba93SPeter Wemm while ((c = getchar()) != EOF && c != '\n'); 44816c2ba93SPeter Wemm ungetc(c,stdin); 44916c2ba93SPeter Wemm inode1 = -1; 45016c2ba93SPeter Wemm while (scanf("%d",&inode) == 1) { 45116c2ba93SPeter Wemm if (inode < 0 || inode > maxino) { 4526980f0ebSPhilippe Charnier warnx("illegal inode %d",inode); 45316c2ba93SPeter Wemm return; 45416c2ba93SPeter Wemm } 45516c2ba93SPeter Wemm errno = 0; 45616c2ba93SPeter Wemm if ((ip = get_inode(fd,super,inode)) 45716c2ba93SPeter Wemm && !isfree(ip)) { 45816c2ba93SPeter Wemm printf("%s\t",user(ip->di_uid)->name); 45916c2ba93SPeter Wemm /* now skip whitespace */ 46016c2ba93SPeter Wemm while ((c = getchar()) == ' ' || c == '\t'); 46116c2ba93SPeter Wemm /* and print out the remainder of the input line */ 46216c2ba93SPeter Wemm while (c != EOF && c != '\n') { 46316c2ba93SPeter Wemm putchar(c); 46416c2ba93SPeter Wemm c = getchar(); 46516c2ba93SPeter Wemm } 46616c2ba93SPeter Wemm putchar('\n'); 46716c2ba93SPeter Wemm inode1 = inode; 46816c2ba93SPeter Wemm } else { 46916c2ba93SPeter Wemm if (errno) { 4706980f0ebSPhilippe Charnier err(1, "%s", name); 47116c2ba93SPeter Wemm } 47216c2ba93SPeter Wemm /* skip this line */ 47316c2ba93SPeter Wemm while ((c = getchar()) != EOF && c != '\n'); 47416c2ba93SPeter Wemm } 47516c2ba93SPeter Wemm if (c == EOF) 47616c2ba93SPeter Wemm break; 47716c2ba93SPeter Wemm } 47816c2ba93SPeter Wemm } 47916c2ba93SPeter Wemm 4806980f0ebSPhilippe Charnier static void 4816980f0ebSPhilippe Charnier usage() 48216c2ba93SPeter Wemm { 48316c2ba93SPeter Wemm #ifdef COMPAT 4846980f0ebSPhilippe Charnier fprintf(stderr,"usage: quot [-nfcvha] [filesystem ...]\n"); 48516c2ba93SPeter Wemm #else /* COMPAT */ 4866980f0ebSPhilippe Charnier fprintf(stderr,"usage: quot [-acfhknv] [ filesystem ... ]\n"); 48716c2ba93SPeter Wemm #endif /* COMPAT */ 48816c2ba93SPeter Wemm exit(1); 48916c2ba93SPeter Wemm } 49016c2ba93SPeter Wemm 49116c2ba93SPeter Wemm static char superblock[SBSIZE]; 49216c2ba93SPeter Wemm 4936980f0ebSPhilippe Charnier void 49416c2ba93SPeter Wemm quot(name,mp) 49516c2ba93SPeter Wemm char *name, *mp; 49616c2ba93SPeter Wemm { 49716c2ba93SPeter Wemm int fd; 49816c2ba93SPeter Wemm 49916c2ba93SPeter Wemm get_inode(-1); /* flush cache */ 50016c2ba93SPeter Wemm inituser(); 50116c2ba93SPeter Wemm initfsizes(); 50216c2ba93SPeter Wemm if ((fd = open(name,0)) < 0 50316c2ba93SPeter Wemm || lseek(fd,SBOFF,0) != SBOFF 50416c2ba93SPeter Wemm || read(fd,superblock,SBSIZE) != SBSIZE) { 5056980f0ebSPhilippe Charnier warn("%s", name); 50616c2ba93SPeter Wemm close(fd); 50716c2ba93SPeter Wemm return; 50816c2ba93SPeter Wemm } 50916c2ba93SPeter Wemm if (((struct fs *)superblock)->fs_magic != FS_MAGIC) { 5106980f0ebSPhilippe Charnier warnx("%s: not a BSD filesystem",name); 51116c2ba93SPeter Wemm close(fd); 51216c2ba93SPeter Wemm return; 51316c2ba93SPeter Wemm } 51416c2ba93SPeter Wemm printf("%s:",name); 51516c2ba93SPeter Wemm if (mp) 51616c2ba93SPeter Wemm printf(" (%s)",mp); 51716c2ba93SPeter Wemm putchar('\n'); 51816c2ba93SPeter Wemm (*func)(fd,superblock,name); 51916c2ba93SPeter Wemm close(fd); 52016c2ba93SPeter Wemm } 52116c2ba93SPeter Wemm 5226980f0ebSPhilippe Charnier int 5236980f0ebSPhilippe Charnier main(argc,argv) 52416c2ba93SPeter Wemm char **argv; 52516c2ba93SPeter Wemm { 52616c2ba93SPeter Wemm char all = 0; 52716c2ba93SPeter Wemm struct statfs *mp; 52816c2ba93SPeter Wemm char dev[MNAMELEN + 1]; 52916c2ba93SPeter Wemm char *nm; 53016c2ba93SPeter Wemm int cnt; 53116c2ba93SPeter Wemm 53216c2ba93SPeter Wemm func = douser; 53316c2ba93SPeter Wemm #ifndef COMPAT 53416c2ba93SPeter Wemm header = getbsize(&headerlen,&blocksize); 53516c2ba93SPeter Wemm #endif 53616c2ba93SPeter Wemm while (--argc > 0 && **++argv == '-') { 53716c2ba93SPeter Wemm while (*++*argv) { 53816c2ba93SPeter Wemm switch (**argv) { 53916c2ba93SPeter Wemm case 'n': 54016c2ba93SPeter Wemm func = donames; 54116c2ba93SPeter Wemm break; 54216c2ba93SPeter Wemm case 'c': 54316c2ba93SPeter Wemm func = dofsizes; 54416c2ba93SPeter Wemm break; 54516c2ba93SPeter Wemm case 'a': 54616c2ba93SPeter Wemm all = 1; 54716c2ba93SPeter Wemm break; 54816c2ba93SPeter Wemm case 'f': 54916c2ba93SPeter Wemm count = 1; 55016c2ba93SPeter Wemm break; 55116c2ba93SPeter Wemm case 'h': 55216c2ba93SPeter Wemm estimate = 1; 55316c2ba93SPeter Wemm break; 55416c2ba93SPeter Wemm #ifndef COMPAT 55516c2ba93SPeter Wemm case 'k': 55616c2ba93SPeter Wemm blocksize = 1024; 55716c2ba93SPeter Wemm break; 55816c2ba93SPeter Wemm #endif /* COMPAT */ 55916c2ba93SPeter Wemm case 'v': 56016c2ba93SPeter Wemm unused = 1; 56116c2ba93SPeter Wemm break; 56216c2ba93SPeter Wemm default: 56316c2ba93SPeter Wemm usage(); 56416c2ba93SPeter Wemm } 56516c2ba93SPeter Wemm } 56616c2ba93SPeter Wemm } 56716c2ba93SPeter Wemm if (all) { 56816c2ba93SPeter Wemm cnt = getmntinfo(&mp,MNT_NOWAIT); 56916c2ba93SPeter Wemm for (; --cnt >= 0; mp++) { 570b49d184bSBruce Evans if (!strncmp(mp->f_fstypename, "ufs", MFSNAMELEN)) { 5716980f0ebSPhilippe Charnier if ((nm = strrchr(mp->f_mntfromname,'/'))) { 57216c2ba93SPeter Wemm sprintf(dev,"/dev/r%s",nm + 1); 57316c2ba93SPeter Wemm nm = dev; 57416c2ba93SPeter Wemm } else 57516c2ba93SPeter Wemm nm = mp->f_mntfromname; 57616c2ba93SPeter Wemm quot(nm,mp->f_mntonname); 57716c2ba93SPeter Wemm } 57816c2ba93SPeter Wemm } 57916c2ba93SPeter Wemm } 58016c2ba93SPeter Wemm while (--argc >= 0) 58116c2ba93SPeter Wemm quot(*argv++,0); 58216c2ba93SPeter Wemm return 0; 58316c2ba93SPeter Wemm } 584