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