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