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