|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)quota.c 5.4 (Berkeley) 2/24/86"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * Disk quota reporting program. ! 19: */ ! 20: #include <stdio.h> ! 21: #include <fstab.h> ! 22: #include <ctype.h> ! 23: #include <pwd.h> ! 24: #include <errno.h> ! 25: ! 26: #include <sys/param.h> ! 27: #include <sys/quota.h> ! 28: #include <sys/file.h> ! 29: #include <sys/stat.h> ! 30: ! 31: int qflag; ! 32: int vflag; ! 33: int done; ! 34: int morethanone; ! 35: char *qfname = "quotas"; ! 36: ! 37: main(argc, argv) ! 38: char *argv[]; ! 39: { ! 40: register char *cp; ! 41: extern int errno; ! 42: ! 43: if (quota(Q_SYNC, 0, 0, (caddr_t)0) < 0 && errno == EINVAL) { ! 44: fprintf(stderr, "There are no quotas on this system\n"); ! 45: exit(0); ! 46: } ! 47: argc--,argv++; ! 48: while (argc > 0) { ! 49: if (argv[0][0] == '-') ! 50: for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { ! 51: ! 52: case 'v': ! 53: vflag++; ! 54: break; ! 55: ! 56: case 'q': ! 57: qflag++; ! 58: break; ! 59: ! 60: default: ! 61: fprintf(stderr, "quota: %c: unknown option\n", ! 62: *cp); ! 63: exit(1); ! 64: } ! 65: else ! 66: break; ! 67: argc--, argv++; ! 68: } ! 69: morethanone = argc > 1; ! 70: if (argc == 0) { ! 71: showuid(getuid()); ! 72: exit(0); ! 73: } ! 74: for (; argc > 0; argc--, argv++) { ! 75: if (alldigits(*argv)) ! 76: showuid(atoi(*argv)); ! 77: else ! 78: showname(*argv); ! 79: } ! 80: } ! 81: ! 82: showuid(uid) ! 83: int uid; ! 84: { ! 85: struct passwd *pwd = getpwuid(uid); ! 86: ! 87: if (pwd == NULL) ! 88: showquotas(uid, "(no account)"); ! 89: else ! 90: showquotas(uid, pwd->pw_name); ! 91: } ! 92: ! 93: showname(name) ! 94: char *name; ! 95: { ! 96: struct passwd *pwd = getpwnam(name); ! 97: ! 98: if (pwd == NULL) { ! 99: fprintf(stderr, "quota: %s: unknown user\n", name); ! 100: return; ! 101: } ! 102: showquotas(pwd->pw_uid, name); ! 103: } ! 104: ! 105: showquotas(uid, name) ! 106: int uid; ! 107: char *name; ! 108: { ! 109: register struct fstab *fs; ! 110: register char *msgi, *msgb; ! 111: register enab = 1; ! 112: dev_t fsdev; ! 113: struct stat statb; ! 114: struct dqblk dqblk; ! 115: int myuid, fd; ! 116: char qfilename[MAXPATHLEN + 1], iwarn[8], dwarn[8]; ! 117: ! 118: myuid = getuid(); ! 119: if (uid != myuid && myuid != 0) { ! 120: printf("quota: %s (uid %d): permission denied\n", name, uid); ! 121: return; ! 122: } ! 123: done = 0; ! 124: (void) setfsent(); ! 125: while (fs = getfsent()) { ! 126: if (stat(fs->fs_spec, &statb) < 0) ! 127: continue; ! 128: msgi = msgb = (char *) 0; ! 129: fsdev = statb.st_rdev; ! 130: (void) sprintf(qfilename, "%s/%s", fs->fs_file, qfname); ! 131: if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev) ! 132: continue; ! 133: if (quota(Q_GETDLIM, uid, fsdev, (caddr_t)&dqblk) != 0) { ! 134: fd = open(qfilename, O_RDONLY); ! 135: if (fd < 0) ! 136: continue; ! 137: (void) lseek(fd, (off_t)(uid * sizeof (dqblk)), L_SET); ! 138: switch (read(fd, (char *)&dqblk, sizeof dqblk)) { ! 139: case 0: /* EOF */ ! 140: /* ! 141: * Convert implicit 0 quota (EOF) ! 142: * into an explicit one (zero'ed dqblk). ! 143: */ ! 144: bzero((caddr_t)&dqblk, sizeof dqblk); ! 145: break; ! 146: ! 147: case sizeof dqblk: /* OK */ ! 148: break; ! 149: ! 150: default: /* ERROR */ ! 151: fprintf(stderr, "quota: read error in "); ! 152: perror(qfilename); ! 153: (void) close(fd); ! 154: continue; ! 155: } ! 156: (void) close(fd); ! 157: if (!vflag && dqblk.dqb_isoftlimit == 0 && ! 158: dqblk.dqb_bsoftlimit == 0) ! 159: continue; ! 160: enab = 0; ! 161: } ! 162: if (dqblk.dqb_ihardlimit && ! 163: dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit) ! 164: msgi = "File count limit reached on %s"; ! 165: else if (enab && dqblk.dqb_iwarn == 0) ! 166: msgi = "Out of inode warnings on %s"; ! 167: else if (dqblk.dqb_isoftlimit && ! 168: dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit) ! 169: msgi = "Too many files on %s"; ! 170: if (dqblk.dqb_bhardlimit && ! 171: dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit) ! 172: msgb = "Block limit reached on %s"; ! 173: else if (enab && dqblk.dqb_bwarn == 0) ! 174: msgb = "Out of block warnings on %s"; ! 175: else if (dqblk.dqb_bsoftlimit && ! 176: dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit) ! 177: msgb = "Over disc quota on %s"; ! 178: if (dqblk.dqb_iwarn < MAX_IQ_WARN) ! 179: (void) sprintf(iwarn, "%d", dqblk.dqb_iwarn); ! 180: else ! 181: iwarn[0] = '\0'; ! 182: if (dqblk.dqb_bwarn < MAX_DQ_WARN) ! 183: (void) sprintf(dwarn, "%d", dqblk.dqb_bwarn); ! 184: else ! 185: dwarn[0] = '\0'; ! 186: if (qflag) { ! 187: if (msgi != (char *)0 || msgb != (char *)0) ! 188: heading(uid, name); ! 189: if (msgi != (char *)0) ! 190: xprintf(msgi, fs->fs_file); ! 191: if (msgb != (char *)0) ! 192: xprintf(msgb, fs->fs_file); ! 193: continue; ! 194: } ! 195: if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) { ! 196: heading(uid, name); ! 197: printf("%10s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n" ! 198: , fs->fs_file ! 199: , dbtob(dqblk.dqb_curblocks) / 1024 ! 200: , (msgb == (char *)0) ? ' ' : '*' ! 201: , dbtob(dqblk.dqb_bsoftlimit) / 1024 ! 202: , dbtob(dqblk.dqb_bhardlimit) / 1024 ! 203: , dwarn ! 204: , dqblk.dqb_curinodes ! 205: , (msgi == (char *)0) ? ' ' : '*' ! 206: , dqblk.dqb_isoftlimit ! 207: , dqblk.dqb_ihardlimit ! 208: , iwarn ! 209: ); ! 210: } ! 211: } ! 212: (void) endfsent(); ! 213: if (!done && !qflag) { ! 214: if (morethanone) ! 215: (void) putchar('\n'); ! 216: xprintf("Disc quotas for %s (uid %d):", name, uid); ! 217: xprintf("none."); ! 218: } ! 219: xprintf((char *)0); ! 220: } ! 221: ! 222: heading(uid, name) ! 223: int uid; ! 224: char *name; ! 225: { ! 226: ! 227: if (done++) ! 228: return; ! 229: xprintf((char *)0); ! 230: if (qflag) { ! 231: if (!morethanone) ! 232: return; ! 233: xprintf("User %s (uid %d):", name, uid); ! 234: xprintf((char *)0); ! 235: return; ! 236: } ! 237: (void) putchar('\n'); ! 238: xprintf("Disc quotas for %s (uid %d):", name, uid); ! 239: xprintf((char *)0); ! 240: printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n" ! 241: , "Filsys" ! 242: , "current" ! 243: , "quota" ! 244: , "limit" ! 245: , "#warns" ! 246: , "files" ! 247: , "quota" ! 248: , "limit" ! 249: , "#warns" ! 250: ); ! 251: } ! 252: ! 253: /*VARARGS1*/ ! 254: xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6) ! 255: char *fmt; ! 256: { ! 257: char buf[100]; ! 258: static int column; ! 259: ! 260: if (fmt == 0 && column || column >= 40) { ! 261: (void) putchar('\n'); ! 262: column = 0; ! 263: } ! 264: if (fmt == 0) ! 265: return; ! 266: (void) sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6); ! 267: if (column != 0 && strlen(buf) < 39) ! 268: while (column++ < 40) ! 269: (void) putchar(' '); ! 270: else if (column) { ! 271: (void) putchar('\n'); ! 272: column = 0; ! 273: } ! 274: printf("%s", buf); ! 275: column += strlen(buf); ! 276: } ! 277: ! 278: alldigits(s) ! 279: register char *s; ! 280: { ! 281: register c; ! 282: ! 283: c = *s++; ! 284: do { ! 285: if (!isdigit(c)) ! 286: return (0); ! 287: } while (c = *s++); ! 288: return (1); ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.