|
|
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[] = "@(#)repquota.c 5.4 (Berkeley) 3/5/86";
15: #endif not lint
16:
17: /*
18: * Quota report
19: */
20: #include <stdio.h>
21: #include <errno.h>
22: #include <sys/param.h>
23: #include <sys/quota.h>
24: #include <sys/stat.h>
25: #include <fstab.h>
26: #include <pwd.h>
27:
28: #define LOGINNAMESIZE 8
29: struct fileusage {
30: struct fileusage *fu_next;
31: struct dqblk fu_dqblk;
32: u_short fu_uid;
33: char fu_name[LOGINNAMESIZE + 1];
34: };
35: #define FUHASH 997
36: struct fileusage *fuhead[FUHASH];
37: struct fileusage *lookup();
38: struct fileusage *adduid();
39: int highuid;
40:
41: long done;
42: struct passwd *getpwent();
43:
44: int vflag; /* verbose */
45: int aflag; /* all file systems */
46:
47: char *qfname = "quotas";
48: struct dqblk zerodqblk;
49:
50: main(argc, argv)
51: int argc;
52: char **argv;
53: {
54: register struct fstab *fs;
55: register struct passwd *pw;
56: register struct fileusage *fup;
57: char quotafile[MAXPATHLEN];
58: int i, errs = 0;
59:
60: again:
61: argc--, argv++;
62: if (argc > 0 && strcmp(*argv, "-v") == 0) {
63: vflag++;
64: goto again;
65: }
66: if (argc > 0 && strcmp(*argv, "-a") == 0) {
67: aflag++;
68: goto again;
69: }
70: if (argc <= 0 && !aflag) {
71: fprintf(stderr, "Usage:\n\t%s\n\t%s\n",
72: "repquota [-v] -a",
73: "repquota [-v] filesys ...");
74: exit(1);
75: }
76: setpwent();
77: while ((pw = getpwent()) != 0) {
78: fup = lookup(pw->pw_uid);
79: if (fup == 0) {
80: fup = adduid(pw->pw_uid);
81: strncpy(fup->fu_name, pw->pw_name, sizeof(fup->fu_name));
82: }
83: }
84: endpwent();
85: setfsent();
86: while ((fs = getfsent()) != NULL) {
87: if (aflag &&
88: (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
89: continue;
90: if (!aflag &&
91: !(oneof(fs->fs_file, argv, argc) ||
92: oneof(fs->fs_spec, argv, argc)))
93: continue;
94: (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
95: errs += repquota(fs->fs_spec, fs->fs_file, quotafile);
96: }
97: endfsent();
98: for (i = 0; i < argc; i++)
99: if ((done & (1 << i)) == 0)
100: fprintf(stderr, "%s not found in /etc/fstab\n",
101: argv[i]);
102: exit(errs);
103: }
104:
105: repquota(fsdev, fsfile, qffile)
106: char *fsdev;
107: char *fsfile;
108: char *qffile;
109: {
110: register struct fileusage *fup;
111: FILE *qf;
112: u_short uid;
113: struct dqblk dqbuf;
114: struct stat statb;
115: static int warned = 0;
116: extern int errno;
117:
118: if (vflag)
119: fprintf(stdout, "*** Quota report for %s (%s)\n", fsdev, fsfile);
120: qf = fopen(qffile, "r");
121: if (qf == NULL) {
122: perror(qffile);
123: return (1);
124: }
125: if (fstat(fileno(qf), &statb) < 0) {
126: perror(qffile);
127: fclose(qf);
128: return (1);
129: }
130: if (quota(Q_SYNC, 0, statb.st_dev, 0) < 0 &&
131: errno == EINVAL && !warned && vflag) {
132: warned++;
133: fprintf(stdout,
134: "*** Warning: Quotas are not compiled into this kernel\n");
135: }
136: for (uid = 0; ; uid++) {
137: fread(&dqbuf, sizeof(struct dqblk), 1, qf);
138: if (feof(qf))
139: break;
140: fup = lookup(uid);
141: if ((fup == 0 || fup->fu_name[0] == 0) &&
142: dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0)
143: continue;
144: if (fup == 0)
145: fup = adduid(uid);
146: fup->fu_dqblk = dqbuf;
147: }
148: printf(" Block limits File limits\n");
149: printf("User used soft hard warn used soft hard warn\n");
150: for (uid = 0; uid <= highuid; uid++) {
151: fup = lookup(uid);
152: if (fup == 0)
153: continue;
154: if (fup->fu_dqblk.dqb_curinodes == 0 &&
155: fup->fu_dqblk.dqb_curblocks == 0)
156: continue;
157: if (fup->fu_name[0] != '\0')
158: printf("%-10s", fup->fu_name);
159: else
160: printf("#%-9d", uid);
161: printf("%c%c%8d%8d%8d %5d %5d %5d %5d %5d\n",
162: fup->fu_dqblk.dqb_bsoftlimit &&
163: fup->fu_dqblk.dqb_curblocks >=
164: fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-',
165: fup->fu_dqblk.dqb_isoftlimit &&
166: fup->fu_dqblk.dqb_curinodes >=
167: fup->fu_dqblk.dqb_isoftlimit ? '+' : '-',
168: dbtob(fup->fu_dqblk.dqb_curblocks) / 1024,
169: dbtob(fup->fu_dqblk.dqb_bsoftlimit) / 1024,
170: dbtob(fup->fu_dqblk.dqb_bhardlimit) / 1024,
171: fup->fu_dqblk.dqb_bwarn,
172: fup->fu_dqblk.dqb_curinodes,
173: fup->fu_dqblk.dqb_isoftlimit,
174: fup->fu_dqblk.dqb_ihardlimit,
175: fup->fu_dqblk.dqb_iwarn);
176: fup->fu_dqblk = zerodqblk;
177: }
178: fclose(qf);
179: return (0);
180: }
181:
182: oneof(target, list, n)
183: char *target, *list[];
184: register int n;
185: {
186: register int i;
187:
188: for (i = 0; i < n; i++)
189: if (strcmp(target, list[i]) == 0) {
190: done |= 1 << i;
191: return (1);
192: }
193: return (0);
194: }
195:
196: struct fileusage *
197: lookup(uid)
198: u_short uid;
199: {
200: register struct fileusage *fup;
201:
202: for (fup = fuhead[uid % FUHASH]; fup != 0; fup = fup->fu_next)
203: if (fup->fu_uid == uid)
204: return (fup);
205: return ((struct fileusage *)0);
206: }
207:
208: struct fileusage *
209: adduid(uid)
210: u_short uid;
211: {
212: struct fileusage *fup, **fhp;
213: extern char *calloc();
214:
215: fup = lookup(uid);
216: if (fup != 0)
217: return (fup);
218: fup = (struct fileusage *)calloc(1, sizeof(struct fileusage));
219: if (fup == 0) {
220: fprintf(stderr, "out of memory for fileusage structures\n");
221: exit(1);
222: }
223: fhp = &fuhead[uid % FUHASH];
224: fup->fu_next = *fhp;
225: *fhp = fup;
226: fup->fu_uid = uid;
227: if (uid > highuid)
228: highuid = uid;
229: return (fup);
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.