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