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