|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)quotacheck.c 4.4 (Berkeley, Melbourne) 6/22/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Fix up / report on disc quotas & usage ! 7: */ ! 8: #include <stdio.h> ! 9: #include <ctype.h> ! 10: #include <signal.h> ! 11: #include <sys/param.h> ! 12: #include <sys/inode.h> ! 13: #include <sys/fs.h> ! 14: #include <sys/quota.h> ! 15: #include <sys/stat.h> ! 16: #include <fstab.h> ! 17: #include <pwd.h> ! 18: ! 19: union { ! 20: struct fs sblk; ! 21: char dummy[MAXBSIZE]; ! 22: } un; ! 23: #define sblock un.sblk ! 24: ! 25: #define ITABSZ 256 ! 26: struct dinode itab[ITABSZ]; ! 27: struct dinode *dp; ! 28: long blocks; ! 29: dev_t dev; ! 30: ! 31: #define LOGINNAMESIZE 8 ! 32: struct fileusage { ! 33: struct fileusage *fu_next; ! 34: struct dqusage fu_usage; ! 35: u_short fu_uid; ! 36: char fu_name[LOGINNAMESIZE + 1]; ! 37: }; ! 38: #define FUHASH 997 ! 39: struct fileusage *fuhead[FUHASH]; ! 40: struct fileusage *lookup(); ! 41: struct fileusage *adduid(); ! 42: int highuid; ! 43: ! 44: int fi; ! 45: ino_t ino; ! 46: long done; ! 47: struct passwd *getpwent(); ! 48: struct dinode *ginode(); ! 49: char *malloc(), *makerawname(); ! 50: ! 51: int vflag; /* verbose */ ! 52: int aflag; /* all file systems */ ! 53: ! 54: char *qfname = "quotas"; ! 55: char quotafile[MAXPATHLEN + 1]; ! 56: struct dqblk zerodqbuf; ! 57: ! 58: main(argc, argv) ! 59: int argc; ! 60: char **argv; ! 61: { ! 62: register struct fstab *fs; ! 63: register struct fileusage *fup; ! 64: register struct passwd *pw; ! 65: int i, errs = 0; ! 66: ! 67: again: ! 68: argc--, argv++; ! 69: if (argc > 0 && strcmp(*argv, "-v") == 0) { ! 70: vflag++; ! 71: goto again; ! 72: } ! 73: if (argc > 0 && strcmp(*argv, "-a") == 0) { ! 74: aflag++; ! 75: goto again; ! 76: } ! 77: if (argc <= 0 && !aflag) { ! 78: fprintf(stderr, "Usage:\n\t%s\n\t%s\n", ! 79: "quotacheck [-v] -a", ! 80: "quotacheck [-v] filesys ..."); ! 81: exit(1); ! 82: } ! 83: if (vflag) { ! 84: setpwent(); ! 85: while ((pw = getpwent()) != 0) { ! 86: fup = lookup(pw->pw_uid); ! 87: if (fup == 0) ! 88: fup = adduid(pw->pw_uid); ! 89: strncpy(fup->fu_name, pw->pw_name, ! 90: sizeof(fup->fu_name)); ! 91: } ! 92: endpwent(); ! 93: } ! 94: setfsent(); ! 95: while ((fs = getfsent()) != NULL) { ! 96: if (aflag && ! 97: (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0)) ! 98: continue; ! 99: if (!aflag && ! 100: !(oneof(fs->fs_file, argv, argc) || ! 101: oneof(fs->fs_spec, argv, argc))) ! 102: continue; ! 103: (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname); ! 104: errs += chkquota(fs->fs_spec, quotafile); ! 105: } ! 106: endfsent(); ! 107: for (i = 0; i < argc; i++) ! 108: if ((done & (1 << i)) == 0) ! 109: fprintf(stderr, "%s not found in /etc/fstab\n", ! 110: argv[i]); ! 111: exit(errs); ! 112: } ! 113: ! 114: chkquota(fsdev, qffile) ! 115: char *fsdev; ! 116: char *qffile; ! 117: { ! 118: register struct fileusage *fup; ! 119: dev_t quotadev; ! 120: FILE *qf; ! 121: u_short uid; ! 122: int cg, i; ! 123: char *rawdisk; ! 124: struct stat statb; ! 125: struct dqblk dqbuf; ! 126: ! 127: rawdisk = makerawname(fsdev); ! 128: if (vflag) ! 129: fprintf(stdout, "*** Check quotas for %s\n", rawdisk); ! 130: fi = open(rawdisk, 0); ! 131: if (fi < 0) { ! 132: perror(rawdisk); ! 133: return (1); ! 134: } ! 135: qf = fopen(qffile, "r+"); ! 136: if (qf == NULL) { ! 137: perror(qffile); ! 138: return (1); ! 139: } ! 140: if (fstat(fileno(qf), &statb) < 0) { ! 141: perror(qffile); ! 142: return (1); ! 143: } ! 144: quotadev = statb.st_dev; ! 145: if (stat(fsdev, &statb) < 0) { ! 146: perror(fsdev); ! 147: return (1); ! 148: } ! 149: if (quotadev != statb.st_rdev) { ! 150: fprintf(stderr, "%s dev (0x%x) mismatch %s dev (0x%x)\n", ! 151: qffile, quotadev, fsdev, statb.st_rdev); ! 152: return (1); ! 153: } ! 154: quota(Q_SYNC, 0, quotadev, 0); ! 155: sync(); ! 156: bread(SBLOCK, (char *)&sblock, SBSIZE); ! 157: ino = 0; ! 158: for (cg = 0; cg < sblock.fs_ncg; cg++) { ! 159: dp = NULL; ! 160: for (i = 0; i < sblock.fs_ipg; i++) ! 161: acct(ginode()); ! 162: } ! 163: for (uid = 0; uid <= highuid; uid++) { ! 164: fup = lookup(uid); ! 165: if (fup == 0) ! 166: continue; ! 167: fseek(qf, uid * sizeof(struct dqblk), 0); ! 168: i = fread(&dqbuf, sizeof(struct dqblk), 1, qf); ! 169: if (i == 0) ! 170: dqbuf = zerodqbuf; ! 171: if (dqbuf.dqb_curinodes == fup->fu_usage.du_curinodes && ! 172: dqbuf.dqb_curblocks == fup->fu_usage.du_curblocks) { ! 173: fup->fu_usage.du_curinodes = 0; ! 174: fup->fu_usage.du_curblocks = 0; ! 175: continue; ! 176: } ! 177: if (vflag) { ! 178: if (fup->fu_name[0] != '\0') ! 179: printf("%-10s fixed:", fup->fu_name); ! 180: else ! 181: printf("#%-9d fixed:", uid); ! 182: fprintf(stdout, " inodes (old %d, new %d)", ! 183: dqbuf.dqb_curinodes, fup->fu_usage.du_curinodes); ! 184: fprintf(stdout, " blocks (old %d, new %d)\n", ! 185: dqbuf.dqb_curblocks, fup->fu_usage.du_curblocks); ! 186: } ! 187: dqbuf.dqb_curinodes = fup->fu_usage.du_curinodes; ! 188: dqbuf.dqb_curblocks = fup->fu_usage.du_curblocks; ! 189: fseek(qf, uid * sizeof(struct dqblk), 0); ! 190: fwrite(&dqbuf, sizeof(struct dqblk), 1, qf); ! 191: quota(Q_SETDUSE, uid, quotadev, &fup->fu_usage); ! 192: fup->fu_usage.du_curinodes = 0; ! 193: fup->fu_usage.du_curblocks = 0; ! 194: } ! 195: return (0); ! 196: } ! 197: ! 198: acct(ip) ! 199: register struct dinode *ip; ! 200: { ! 201: register n; ! 202: register struct fileusage *fup; ! 203: ! 204: if (ip == NULL) ! 205: return; ! 206: if (ip->di_mode == 0) ! 207: return; ! 208: fup = lookup(ip->di_uid); ! 209: if (fup == 0) ! 210: fup = adduid(ip->di_uid); ! 211: fup->fu_usage.du_curinodes++; ! 212: if ((ip->di_mode & IFMT) == IFCHR || (ip->di_mode & IFMT) == IFBLK) ! 213: return; ! 214: fup->fu_usage.du_curblocks += ip->di_blocks; ! 215: } ! 216: ! 217: oneof(target, list, n) ! 218: char *target, *list[]; ! 219: register int n; ! 220: { ! 221: register int i; ! 222: ! 223: for (i = 0; i < n; i++) ! 224: if (strcmp(target, list[i]) == 0) { ! 225: done |= 1 << i; ! 226: return (1); ! 227: } ! 228: return (0); ! 229: } ! 230: ! 231: struct dinode * ! 232: ginode() ! 233: { ! 234: register unsigned long iblk; ! 235: ! 236: if (dp == NULL || ++dp >= &itab[ITABSZ]) { ! 237: iblk = itod(&sblock, ino); ! 238: bread(fsbtodb(&sblock, iblk), (char *)itab, sizeof itab); ! 239: dp = &itab[ino % INOPB(&sblock)]; ! 240: } ! 241: if (ino++ < ROOTINO) ! 242: return(NULL); ! 243: return(dp); ! 244: } ! 245: ! 246: bread(bno, buf, cnt) ! 247: long unsigned bno; ! 248: char *buf; ! 249: { ! 250: ! 251: lseek(fi, (long)dbtob(bno), 0); ! 252: if (read(fi, buf, cnt) != cnt) { ! 253: printf("read error %u\n", bno); ! 254: exit(1); ! 255: } ! 256: } ! 257: ! 258: struct fileusage * ! 259: lookup(uid) ! 260: u_short uid; ! 261: { ! 262: register struct fileusage *fup; ! 263: ! 264: for (fup = fuhead[uid % FUHASH]; fup != 0; fup = fup->fu_next) ! 265: if (fup->fu_uid == uid) ! 266: return (fup); ! 267: return ((struct fileusage *)0); ! 268: } ! 269: ! 270: struct fileusage * ! 271: adduid(uid) ! 272: u_short uid; ! 273: { ! 274: struct fileusage *fup, **fhp; ! 275: ! 276: fup = lookup(uid); ! 277: if (fup != 0) ! 278: return (fup); ! 279: fup = (struct fileusage *)calloc(1, sizeof(struct fileusage)); ! 280: if (fup == 0) { ! 281: fprintf(stderr, "out of memory for fileusage structures\n"); ! 282: exit(1); ! 283: } ! 284: fhp = &fuhead[uid % FUHASH]; ! 285: fup->fu_next = *fhp; ! 286: *fhp = fup; ! 287: fup->fu_uid = uid; ! 288: if (uid > highuid) ! 289: highuid = uid; ! 290: return (fup); ! 291: } ! 292: ! 293: char * ! 294: makerawname(name) ! 295: char *name; ! 296: { ! 297: register char *cp; ! 298: char tmp, ch, *rindex(); ! 299: static char rawname[MAXPATHLEN]; ! 300: ! 301: strcpy(rawname, name); ! 302: cp = rindex(rawname, '/') + 1; ! 303: if (cp == (char *)1 || *cp == 'r') ! 304: return (name); ! 305: for (ch = 'r'; *cp != '\0'; ) { ! 306: tmp = *cp; ! 307: *cp++ = ch; ! 308: ch = tmp; ! 309: } ! 310: *cp++ = ch; ! 311: *cp = '\0'; ! 312: return (rawname); ! 313: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.