|
|
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.