From: Kirk McKusick Date: Mon, 23 May 1983 05:52:26 +0000 (-0800) Subject: date and time created 83/05/22 14:52:26 by mckusick X-Git-Tag: BSD-4_2-Snapshot-Development~1823 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/f7830fd740eaddff612c378b99ee1a119ae042b7 date and time created 83/05/22 14:52:26 by mckusick SCCS-vsn: sbin/quotacheck/quotacheck.c 4.1 --- diff --git a/usr/src/sbin/quotacheck/quotacheck.c b/usr/src/sbin/quotacheck/quotacheck.c new file mode 100644 index 0000000000..10193ad68b --- /dev/null +++ b/usr/src/sbin/quotacheck/quotacheck.c @@ -0,0 +1,314 @@ +#ifndef lit +static char sccsid[] = "@(#)quotacheck.c 4.1 (Melbourne) %G%"; +#endif + +/* + * Fix up / report on disc quotas & usage + */ +#include +#include +#include +#include +#include +#include +#include +#define QUOTA +#include +#include + +#define ITABSZ 256 +#define NUID 3500 +union { + struct fs sblk; + char ___[MAXBSIZE]; +} un; +#define sblock un.sblk +struct dinode itab[ITABSZ]; +struct dinode *dp; +struct dqblk du[NUID]; +char *dn[NUID]; +struct dqblk zeroes; +u_short iuse[NUID]; +u_long buse[NUID]; +long blocks; +dev_t dev; + +int bflg; +int iflg; +int rflg; +int sflg; + +int fi; +unsigned ino; +unsigned nfiles; +int highuid; + +struct passwd *getpwent(); +struct dinode *ginode(); +char *malloc(); +char *copy(); + +main(argc, argv) + char **argv; +{ + register int n; + register struct passwd *lp; + register char *p; + register long unsigned i; + register c; + register cg; + FILE *qf; + struct stat statb; + + while (--argc > 0 && *(p = *++argv) == '-') + while (c = *++p) switch (c) { + + case 's': + sflg++; + break; + + case 'b': + bflg++; + break; + + case 'i': + iflg++; + break; + + case 'r': + rflg++; + break; + } + + if (argc != 2) { + fprintf(stderr, "Usage: fixquota filesys qfile\n"); + exit(1); + } + + fi = open(p, 0); + if (fi < 0) { + fprintf(stderr, "Can't open %s\n", p); + exit(1); + } + + if (iflg || bflg || rflg) { + while((lp=getpwent()) != 0) { + n = lp->pw_uid; + if (n>=NUID) + continue; + if(dn[n]) + continue; + dn[n] = copy(lp->pw_name); + } + } + + if (!(iflg || bflg)) + sflg++; + + qf = fopen(*++argv, "r"); + if (qf != NULL) { + fstat(fileno(qf), &statb); + dev = statb.st_dev; + quota(Q_SYNC, 0, dev, 0); + n = fread(du, sizeof(struct dqblk), NUID, qf); + if (n == EOF) + n = 0; + highuid = n-1; + fclose(qf); + } else { + highuid = -1; + dev = NODEV; + } +/*ZZprintf("highuid = %d\n", highuid);*/ + + for (n = 0; n <= highuid; n++) { + iuse[n] = du[n].dqb_curinodes; + buse[n] = du[n].dqb_curblocks; + du[n].dqb_curinodes = du[n].dqb_curblocks = 0; + } + + sync(); + bread(SBLOCK, (char *)&sblock, SBSIZE); + ino = 0; + for (cg = 0; cg < sblock.fs_ncg; cg++) { +/*ZZprintf("cg %d <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", cg);*/ + dp = NULL; + for (i = 0; i < sblock.fs_ipg; i++) + acct(ginode()); + } + if (sflg && highuid >= 0) { + int sig; + int ssig; + + sig = (int) signal(SIGINT, SIG_IGN); + ssig = (int) signal(SIGTSTP, SIG_IGN); + if ((qf = fopen(*argv, "a")) == NULL) { + fprintf(stderr, "Can't create %s\n", *argv); + exit(1); + } + + rewind(qf); + fwrite(du, sizeof(struct dqblk), highuid+1, qf); + fclose(qf); + signal(SIGTSTP, ssig); + sysset(); + signal(SIGINT, sig); + } + report(); +} + +acct(ip) + register struct dinode *ip; +{ + register n; + + if (ip == NULL) + return; + if (ip->di_mode == 0) +/*ZZ{printf(" unallocated\n");*/ + return; +/*ZZ}*/ + if (ip->di_uid >= NUID) +/*ZZ{printf(" uid oor\n");*/ + return; +/*ZZ}*/ + if (ip->di_uid > highuid) { + for (n = highuid+1; n <= ip->di_uid; n++) + du[n] = zeroes; + highuid = ip->di_uid; + } + du[ip->di_uid].dqb_curinodes++; + if ((ip->di_mode & IFMT) == IFCHR || (ip->di_mode & IFMT) == IFBLK) +/*ZZ{printf(" special\n");*/ + return; +/*ZZ}*/ + blocks = 0; + for (n = 0; n < NDADDR; n++) + if (ip->di_db[n]) + blocks += dblksize(&sblock, ip, n) / DEV_BSIZE; + for (n = 0; n < NIADDR; n++) + tloop(ip->di_ib[n], ip, n); + du[ip->di_uid].dqb_curblocks += blocks; + if (blocks != ip->di_blocks) + printf("Ino %d: \n", ino, blocks, ip->di_blocks); +/*ZZprintf(" %d blks\n", blocks);*/ +} + +tloop(bn, ip, f) + long bn; +{ + register i; + long iblk[MAXBSIZE/sizeof(long)]; + + if (!bn) + return; + blocks += sblock.fs_bsize / DEV_BSIZE; + bread(fsbtodb(&sblock, bn), iblk, sblock.fs_bsize); + if (f) { + for (i = 0; i < NINDIR(&sblock); i++) + tloop(iblk[i], ip, f-1); + } else { + for (i = 0; i < NINDIR(&sblock); i++) + if (iblk[i]) + blocks += sblock.fs_bsize / DEV_BSIZE; + } +} + +struct dinode * +ginode() +{ + register unsigned long iblk; + + if (dp == NULL || ++dp >= &itab[ITABSZ]) { + iblk = itod(&sblock, ino); +/*ZZprintf("dp = %x, itab=%x", dp, itab);*/ +/*ZZprintf(" Reading inodes from fs blk %d ", iblk);*/ + bread(fsbtodb(&sblock, iblk), (char *)itab, sizeof itab); + dp = &itab[ino % INOPB(&sblock)]; +/*ZZprintf("dp = %x\n", dp, itab);*/ + } +/*ZZprintf("ino %d ", ino);*/ + if (ino++ < ROOTINO) + return(NULL); + return(dp); +} + +bread(bno, buf, cnt) + long unsigned bno; + char *buf; +{ + + lseek(fi, (long)bno*DEV_BSIZE, 0); + if (read(fi, buf, cnt) != cnt) { + printf("read error %u\n", bno); + exit(1); + } +} + +sysset() +{ + struct dqusage usage; + register i; + + for (i = 0; i <= highuid; i++) { + if (du[i].dqb_curinodes != iuse[i] || du[i].dqb_curblocks != buse[i]) { + if (du[i].dqb_isoftlimit == 0 && du[i].dqb_bsoftlimit == 0) + continue; + if (rflg) { + if (dn[i]) + printf("%s", dn[i]); + else + printf("#%d", i); + printf(": i %d->%d, b %d->%d\n" + , iuse[i] + , du[i].dqb_curinodes + , buse[i] + , du[i].dqb_curblocks + ); + } + usage.du_curinodes = du[i].dqb_curinodes; + usage.du_curblocks = du[i].dqb_curblocks; + quota(Q_SETDUSE, i, dev, &usage); + } + } +} + +report() +{ + register i; + + if (iflg) + for (i = 0; i <= highuid; i++) + if (du[i].dqb_isoftlimit && du[i].dqb_curinodes >= du[i].dqb_isoftlimit) { + if (dn[i]) + printf("%-10s", dn[i]); + else + printf("#%-9d", i); + printf("%5d (iq = %d)\n", du[i].dqb_curinodes, du[i].dqb_isoftlimit); + } + + if (bflg) + for (i = 0; i <= highuid; i++) + if (du[i].dqb_bsoftlimit && du[i].dqb_curblocks >= du[i].dqb_bsoftlimit) { + if (dn[i]) + printf("%-10s", dn[i]); + else + printf("#%-9s", i); + printf("%5d (quot = %d)\n", du[i].dqb_curblocks, du[i].dqb_bsoftlimit); + } +} + +char * +copy(s) + char *s; +{ + register char *p; + register n; + + for(n=0; s[n]; n++) + ; + p = malloc((unsigned)n+1); + for(n=0; p[n] = s[n]; n++) + ; + return(p); +}