1*12660Smckusick #ifndef lit 2*12660Smckusick static char sccsid[] = "@(#)quotacheck.c 4.1 (Melbourne) 05/22/83"; 3*12660Smckusick #endif 4*12660Smckusick 5*12660Smckusick /* 6*12660Smckusick * Fix up / report on disc quotas & usage 7*12660Smckusick */ 8*12660Smckusick #include <stdio.h> 9*12660Smckusick #include <ctype.h> 10*12660Smckusick #include <signal.h> 11*12660Smckusick #include <pwd.h> 12*12660Smckusick #include <sys/param.h> 13*12660Smckusick #include <sys/inode.h> 14*12660Smckusick #include <sys/fs.h> 15*12660Smckusick #define QUOTA 16*12660Smckusick #include <sys/quota.h> 17*12660Smckusick #include <sys/stat.h> 18*12660Smckusick 19*12660Smckusick #define ITABSZ 256 20*12660Smckusick #define NUID 3500 21*12660Smckusick union { 22*12660Smckusick struct fs sblk; 23*12660Smckusick char ___[MAXBSIZE]; 24*12660Smckusick } un; 25*12660Smckusick #define sblock un.sblk 26*12660Smckusick struct dinode itab[ITABSZ]; 27*12660Smckusick struct dinode *dp; 28*12660Smckusick struct dqblk du[NUID]; 29*12660Smckusick char *dn[NUID]; 30*12660Smckusick struct dqblk zeroes; 31*12660Smckusick u_short iuse[NUID]; 32*12660Smckusick u_long buse[NUID]; 33*12660Smckusick long blocks; 34*12660Smckusick dev_t dev; 35*12660Smckusick 36*12660Smckusick int bflg; 37*12660Smckusick int iflg; 38*12660Smckusick int rflg; 39*12660Smckusick int sflg; 40*12660Smckusick 41*12660Smckusick int fi; 42*12660Smckusick unsigned ino; 43*12660Smckusick unsigned nfiles; 44*12660Smckusick int highuid; 45*12660Smckusick 46*12660Smckusick struct passwd *getpwent(); 47*12660Smckusick struct dinode *ginode(); 48*12660Smckusick char *malloc(); 49*12660Smckusick char *copy(); 50*12660Smckusick 51*12660Smckusick main(argc, argv) 52*12660Smckusick char **argv; 53*12660Smckusick { 54*12660Smckusick register int n; 55*12660Smckusick register struct passwd *lp; 56*12660Smckusick register char *p; 57*12660Smckusick register long unsigned i; 58*12660Smckusick register c; 59*12660Smckusick register cg; 60*12660Smckusick FILE *qf; 61*12660Smckusick struct stat statb; 62*12660Smckusick 63*12660Smckusick while (--argc > 0 && *(p = *++argv) == '-') 64*12660Smckusick while (c = *++p) switch (c) { 65*12660Smckusick 66*12660Smckusick case 's': 67*12660Smckusick sflg++; 68*12660Smckusick break; 69*12660Smckusick 70*12660Smckusick case 'b': 71*12660Smckusick bflg++; 72*12660Smckusick break; 73*12660Smckusick 74*12660Smckusick case 'i': 75*12660Smckusick iflg++; 76*12660Smckusick break; 77*12660Smckusick 78*12660Smckusick case 'r': 79*12660Smckusick rflg++; 80*12660Smckusick break; 81*12660Smckusick } 82*12660Smckusick 83*12660Smckusick if (argc != 2) { 84*12660Smckusick fprintf(stderr, "Usage: fixquota filesys qfile\n"); 85*12660Smckusick exit(1); 86*12660Smckusick } 87*12660Smckusick 88*12660Smckusick fi = open(p, 0); 89*12660Smckusick if (fi < 0) { 90*12660Smckusick fprintf(stderr, "Can't open %s\n", p); 91*12660Smckusick exit(1); 92*12660Smckusick } 93*12660Smckusick 94*12660Smckusick if (iflg || bflg || rflg) { 95*12660Smckusick while((lp=getpwent()) != 0) { 96*12660Smckusick n = lp->pw_uid; 97*12660Smckusick if (n>=NUID) 98*12660Smckusick continue; 99*12660Smckusick if(dn[n]) 100*12660Smckusick continue; 101*12660Smckusick dn[n] = copy(lp->pw_name); 102*12660Smckusick } 103*12660Smckusick } 104*12660Smckusick 105*12660Smckusick if (!(iflg || bflg)) 106*12660Smckusick sflg++; 107*12660Smckusick 108*12660Smckusick qf = fopen(*++argv, "r"); 109*12660Smckusick if (qf != NULL) { 110*12660Smckusick fstat(fileno(qf), &statb); 111*12660Smckusick dev = statb.st_dev; 112*12660Smckusick quota(Q_SYNC, 0, dev, 0); 113*12660Smckusick n = fread(du, sizeof(struct dqblk), NUID, qf); 114*12660Smckusick if (n == EOF) 115*12660Smckusick n = 0; 116*12660Smckusick highuid = n-1; 117*12660Smckusick fclose(qf); 118*12660Smckusick } else { 119*12660Smckusick highuid = -1; 120*12660Smckusick dev = NODEV; 121*12660Smckusick } 122*12660Smckusick /*ZZprintf("highuid = %d\n", highuid);*/ 123*12660Smckusick 124*12660Smckusick for (n = 0; n <= highuid; n++) { 125*12660Smckusick iuse[n] = du[n].dqb_curinodes; 126*12660Smckusick buse[n] = du[n].dqb_curblocks; 127*12660Smckusick du[n].dqb_curinodes = du[n].dqb_curblocks = 0; 128*12660Smckusick } 129*12660Smckusick 130*12660Smckusick sync(); 131*12660Smckusick bread(SBLOCK, (char *)&sblock, SBSIZE); 132*12660Smckusick ino = 0; 133*12660Smckusick for (cg = 0; cg < sblock.fs_ncg; cg++) { 134*12660Smckusick /*ZZprintf("cg %d <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", cg);*/ 135*12660Smckusick dp = NULL; 136*12660Smckusick for (i = 0; i < sblock.fs_ipg; i++) 137*12660Smckusick acct(ginode()); 138*12660Smckusick } 139*12660Smckusick if (sflg && highuid >= 0) { 140*12660Smckusick int sig; 141*12660Smckusick int ssig; 142*12660Smckusick 143*12660Smckusick sig = (int) signal(SIGINT, SIG_IGN); 144*12660Smckusick ssig = (int) signal(SIGTSTP, SIG_IGN); 145*12660Smckusick if ((qf = fopen(*argv, "a")) == NULL) { 146*12660Smckusick fprintf(stderr, "Can't create %s\n", *argv); 147*12660Smckusick exit(1); 148*12660Smckusick } 149*12660Smckusick 150*12660Smckusick rewind(qf); 151*12660Smckusick fwrite(du, sizeof(struct dqblk), highuid+1, qf); 152*12660Smckusick fclose(qf); 153*12660Smckusick signal(SIGTSTP, ssig); 154*12660Smckusick sysset(); 155*12660Smckusick signal(SIGINT, sig); 156*12660Smckusick } 157*12660Smckusick report(); 158*12660Smckusick } 159*12660Smckusick 160*12660Smckusick acct(ip) 161*12660Smckusick register struct dinode *ip; 162*12660Smckusick { 163*12660Smckusick register n; 164*12660Smckusick 165*12660Smckusick if (ip == NULL) 166*12660Smckusick return; 167*12660Smckusick if (ip->di_mode == 0) 168*12660Smckusick /*ZZ{printf(" unallocated\n");*/ 169*12660Smckusick return; 170*12660Smckusick /*ZZ}*/ 171*12660Smckusick if (ip->di_uid >= NUID) 172*12660Smckusick /*ZZ{printf(" uid oor\n");*/ 173*12660Smckusick return; 174*12660Smckusick /*ZZ}*/ 175*12660Smckusick if (ip->di_uid > highuid) { 176*12660Smckusick for (n = highuid+1; n <= ip->di_uid; n++) 177*12660Smckusick du[n] = zeroes; 178*12660Smckusick highuid = ip->di_uid; 179*12660Smckusick } 180*12660Smckusick du[ip->di_uid].dqb_curinodes++; 181*12660Smckusick if ((ip->di_mode & IFMT) == IFCHR || (ip->di_mode & IFMT) == IFBLK) 182*12660Smckusick /*ZZ{printf(" special\n");*/ 183*12660Smckusick return; 184*12660Smckusick /*ZZ}*/ 185*12660Smckusick blocks = 0; 186*12660Smckusick for (n = 0; n < NDADDR; n++) 187*12660Smckusick if (ip->di_db[n]) 188*12660Smckusick blocks += dblksize(&sblock, ip, n) / DEV_BSIZE; 189*12660Smckusick for (n = 0; n < NIADDR; n++) 190*12660Smckusick tloop(ip->di_ib[n], ip, n); 191*12660Smckusick du[ip->di_uid].dqb_curblocks += blocks; 192*12660Smckusick if (blocks != ip->di_blocks) 193*12660Smckusick printf("Ino %d: <calc %d, recorded %d>\n", ino, blocks, ip->di_blocks); 194*12660Smckusick /*ZZprintf(" %d blks\n", blocks);*/ 195*12660Smckusick } 196*12660Smckusick 197*12660Smckusick tloop(bn, ip, f) 198*12660Smckusick long bn; 199*12660Smckusick { 200*12660Smckusick register i; 201*12660Smckusick long iblk[MAXBSIZE/sizeof(long)]; 202*12660Smckusick 203*12660Smckusick if (!bn) 204*12660Smckusick return; 205*12660Smckusick blocks += sblock.fs_bsize / DEV_BSIZE; 206*12660Smckusick bread(fsbtodb(&sblock, bn), iblk, sblock.fs_bsize); 207*12660Smckusick if (f) { 208*12660Smckusick for (i = 0; i < NINDIR(&sblock); i++) 209*12660Smckusick tloop(iblk[i], ip, f-1); 210*12660Smckusick } else { 211*12660Smckusick for (i = 0; i < NINDIR(&sblock); i++) 212*12660Smckusick if (iblk[i]) 213*12660Smckusick blocks += sblock.fs_bsize / DEV_BSIZE; 214*12660Smckusick } 215*12660Smckusick } 216*12660Smckusick 217*12660Smckusick struct dinode * 218*12660Smckusick ginode() 219*12660Smckusick { 220*12660Smckusick register unsigned long iblk; 221*12660Smckusick 222*12660Smckusick if (dp == NULL || ++dp >= &itab[ITABSZ]) { 223*12660Smckusick iblk = itod(&sblock, ino); 224*12660Smckusick /*ZZprintf("dp = %x, itab=%x", dp, itab);*/ 225*12660Smckusick /*ZZprintf(" Reading inodes from fs blk %d ", iblk);*/ 226*12660Smckusick bread(fsbtodb(&sblock, iblk), (char *)itab, sizeof itab); 227*12660Smckusick dp = &itab[ino % INOPB(&sblock)]; 228*12660Smckusick /*ZZprintf("dp = %x\n", dp, itab);*/ 229*12660Smckusick } 230*12660Smckusick /*ZZprintf("ino %d ", ino);*/ 231*12660Smckusick if (ino++ < ROOTINO) 232*12660Smckusick return(NULL); 233*12660Smckusick return(dp); 234*12660Smckusick } 235*12660Smckusick 236*12660Smckusick bread(bno, buf, cnt) 237*12660Smckusick long unsigned bno; 238*12660Smckusick char *buf; 239*12660Smckusick { 240*12660Smckusick 241*12660Smckusick lseek(fi, (long)bno*DEV_BSIZE, 0); 242*12660Smckusick if (read(fi, buf, cnt) != cnt) { 243*12660Smckusick printf("read error %u\n", bno); 244*12660Smckusick exit(1); 245*12660Smckusick } 246*12660Smckusick } 247*12660Smckusick 248*12660Smckusick sysset() 249*12660Smckusick { 250*12660Smckusick struct dqusage usage; 251*12660Smckusick register i; 252*12660Smckusick 253*12660Smckusick for (i = 0; i <= highuid; i++) { 254*12660Smckusick if (du[i].dqb_curinodes != iuse[i] || du[i].dqb_curblocks != buse[i]) { 255*12660Smckusick if (du[i].dqb_isoftlimit == 0 && du[i].dqb_bsoftlimit == 0) 256*12660Smckusick continue; 257*12660Smckusick if (rflg) { 258*12660Smckusick if (dn[i]) 259*12660Smckusick printf("%s", dn[i]); 260*12660Smckusick else 261*12660Smckusick printf("#%d", i); 262*12660Smckusick printf(": i %d->%d, b %d->%d\n" 263*12660Smckusick , iuse[i] 264*12660Smckusick , du[i].dqb_curinodes 265*12660Smckusick , buse[i] 266*12660Smckusick , du[i].dqb_curblocks 267*12660Smckusick ); 268*12660Smckusick } 269*12660Smckusick usage.du_curinodes = du[i].dqb_curinodes; 270*12660Smckusick usage.du_curblocks = du[i].dqb_curblocks; 271*12660Smckusick quota(Q_SETDUSE, i, dev, &usage); 272*12660Smckusick } 273*12660Smckusick } 274*12660Smckusick } 275*12660Smckusick 276*12660Smckusick report() 277*12660Smckusick { 278*12660Smckusick register i; 279*12660Smckusick 280*12660Smckusick if (iflg) 281*12660Smckusick for (i = 0; i <= highuid; i++) 282*12660Smckusick if (du[i].dqb_isoftlimit && du[i].dqb_curinodes >= du[i].dqb_isoftlimit) { 283*12660Smckusick if (dn[i]) 284*12660Smckusick printf("%-10s", dn[i]); 285*12660Smckusick else 286*12660Smckusick printf("#%-9d", i); 287*12660Smckusick printf("%5d (iq = %d)\n", du[i].dqb_curinodes, du[i].dqb_isoftlimit); 288*12660Smckusick } 289*12660Smckusick 290*12660Smckusick if (bflg) 291*12660Smckusick for (i = 0; i <= highuid; i++) 292*12660Smckusick if (du[i].dqb_bsoftlimit && du[i].dqb_curblocks >= du[i].dqb_bsoftlimit) { 293*12660Smckusick if (dn[i]) 294*12660Smckusick printf("%-10s", dn[i]); 295*12660Smckusick else 296*12660Smckusick printf("#%-9s", i); 297*12660Smckusick printf("%5d (quot = %d)\n", du[i].dqb_curblocks, du[i].dqb_bsoftlimit); 298*12660Smckusick } 299*12660Smckusick } 300*12660Smckusick 301*12660Smckusick char * 302*12660Smckusick copy(s) 303*12660Smckusick char *s; 304*12660Smckusick { 305*12660Smckusick register char *p; 306*12660Smckusick register n; 307*12660Smckusick 308*12660Smckusick for(n=0; s[n]; n++) 309*12660Smckusick ; 310*12660Smckusick p = malloc((unsigned)n+1); 311*12660Smckusick for(n=0; p[n] = s[n]; n++) 312*12660Smckusick ; 313*12660Smckusick return(p); 314*12660Smckusick } 315