Commit | Line | Data |
---|---|---|
2a18434a KM |
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 | ||
fe35ac74 | 13 | #ifndef lint |
3e5a0658 | 14 | static char sccsid[] = "@(#)repquota.c 5.4 (Berkeley) %G%"; |
2a18434a | 15 | #endif not lint |
fe35ac74 KM |
16 | |
17 | /* | |
18 | * Quota report | |
19 | */ | |
20 | #include <stdio.h> | |
824e2e71 | 21 | #include <errno.h> |
fe35ac74 | 22 | #include <sys/param.h> |
fe35ac74 | 23 | #include <sys/quota.h> |
6c299bfc KM |
24 | #include <sys/stat.h> |
25 | #include <fstab.h> | |
26 | #include <pwd.h> | |
fe35ac74 | 27 | |
6c299bfc KM |
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; | |
fe35ac74 | 40 | |
6c299bfc KM |
41 | long done; |
42 | struct passwd *getpwent(); | |
fe35ac74 | 43 | |
6c299bfc KM |
44 | int vflag; /* verbose */ |
45 | int aflag; /* all file systems */ | |
46 | ||
47 | char *qfname = "quotas"; | |
6c299bfc | 48 | struct dqblk zerodqblk; |
fe35ac74 KM |
49 | |
50 | main(argc, argv) | |
6c299bfc | 51 | int argc; |
fe35ac74 KM |
52 | char **argv; |
53 | { | |
6c299bfc KM |
54 | register struct fstab *fs; |
55 | register struct passwd *pw; | |
56 | register struct fileusage *fup; | |
57 | char quotafile[MAXPATHLEN]; | |
58 | int i, errs = 0; | |
fe35ac74 | 59 | |
6c299bfc KM |
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 ..."); | |
fe35ac74 KM |
74 | exit(1); |
75 | } | |
6c299bfc KM |
76 | setpwent(); |
77 | while ((pw = getpwent()) != 0) { | |
78 | fup = lookup(pw->pw_uid); | |
27cff295 | 79 | if (fup == 0) { |
6c299bfc | 80 | fup = adduid(pw->pw_uid); |
27cff295 JL |
81 | strncpy(fup->fu_name, pw->pw_name, sizeof(fup->fu_name)); |
82 | } | |
6c299bfc KM |
83 | } |
84 | endpwent(); | |
85 | setfsent(); | |
86 | while ((fs = getfsent()) != NULL) { | |
87 | if (aflag && | |
88 | (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0)) | |
fe35ac74 | 89 | continue; |
6c299bfc KM |
90 | if (!aflag && |
91 | !(oneof(fs->fs_file, argv, argc) || | |
92 | oneof(fs->fs_spec, argv, argc))) | |
fe35ac74 | 93 | continue; |
6c299bfc | 94 | (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname); |
2dd469d2 | 95 | errs += repquota(fs->fs_spec, fs->fs_file, quotafile); |
fe35ac74 | 96 | } |
6c299bfc KM |
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 | } | |
fe35ac74 | 104 | |
2dd469d2 | 105 | repquota(fsdev, fsfile, qffile) |
6c299bfc | 106 | char *fsdev; |
2dd469d2 | 107 | char *fsfile; |
6c299bfc KM |
108 | char *qffile; |
109 | { | |
110 | register struct fileusage *fup; | |
111 | FILE *qf; | |
112 | u_short uid; | |
113 | struct dqblk dqbuf; | |
114 | struct stat statb; | |
824e2e71 KM |
115 | static int warned = 0; |
116 | extern int errno; | |
fe35ac74 | 117 | |
6c299bfc | 118 | if (vflag) |
2dd469d2 | 119 | fprintf(stdout, "*** Quota report for %s (%s)\n", fsdev, fsfile); |
6c299bfc KM |
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); | |
2dd469d2 | 127 | fclose(qf); |
6c299bfc KM |
128 | return (1); |
129 | } | |
824e2e71 KM |
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 | } | |
6c299bfc KM |
136 | for (uid = 0; ; uid++) { |
137 | fread(&dqbuf, sizeof(struct dqblk), 1, qf); | |
138 | if (feof(qf)) | |
139 | break; | |
6c299bfc | 140 | fup = lookup(uid); |
2dd469d2 S |
141 | if ((fup == 0 || fup->fu_name[0] == 0) && |
142 | dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) | |
143 | continue; | |
6c299bfc KM |
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; | |
3e5a0658 | 154 | if (fup->fu_dqblk.dqb_curinodes == 0 && |
6c299bfc | 155 | fup->fu_dqblk.dqb_curblocks == 0) |
fe35ac74 | 156 | continue; |
6c299bfc KM |
157 | if (fup->fu_name[0] != '\0') |
158 | printf("%-10s", fup->fu_name); | |
fe35ac74 | 159 | else |
6c299bfc KM |
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 ? '+' : '-', | |
285a6d40 JB |
168 | dbtob(fup->fu_dqblk.dqb_curblocks) / 1024, |
169 | dbtob(fup->fu_dqblk.dqb_bsoftlimit) / 1024, | |
170 | dbtob(fup->fu_dqblk.dqb_bhardlimit) / 1024, | |
6c299bfc KM |
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; | |
fe35ac74 | 177 | } |
2dd469d2 | 178 | fclose(qf); |
6c299bfc KM |
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); | |
fe35ac74 KM |
194 | } |
195 | ||
6c299bfc KM |
196 | struct fileusage * |
197 | lookup(uid) | |
198 | u_short uid; | |
fe35ac74 | 199 | { |
6c299bfc | 200 | register struct fileusage *fup; |
fe35ac74 | 201 | |
6c299bfc KM |
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; | |
2dd469d2 | 213 | extern char *calloc(); |
6c299bfc KM |
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); | |
fe35ac74 | 230 | } |