Commit | Line | Data |
---|---|---|
fe35ac74 | 1 | #ifndef lint |
6c299bfc | 2 | static char sccsid[] = "@(#)repquota.c 4.2 (Berkeley, from Melbourne) %G%"; |
fe35ac74 KM |
3 | #endif |
4 | ||
5 | /* | |
6 | * Quota report | |
7 | */ | |
8 | #include <stdio.h> | |
fe35ac74 | 9 | #include <sys/param.h> |
fe35ac74 | 10 | #include <sys/quota.h> |
6c299bfc KM |
11 | #include <sys/stat.h> |
12 | #include <fstab.h> | |
13 | #include <pwd.h> | |
fe35ac74 | 14 | |
6c299bfc KM |
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; | |
fe35ac74 | 27 | |
6c299bfc KM |
28 | long done; |
29 | struct passwd *getpwent(); | |
fe35ac74 | 30 | |
6c299bfc KM |
31 | int vflag; /* verbose */ |
32 | int aflag; /* all file systems */ | |
33 | ||
34 | char *qfname = "quotas"; | |
35 | char quotafile[MAXPATHLEN + 1]; | |
36 | struct dqblk zerodqblk; | |
fe35ac74 KM |
37 | |
38 | main(argc, argv) | |
6c299bfc | 39 | int argc; |
fe35ac74 KM |
40 | char **argv; |
41 | { | |
6c299bfc KM |
42 | register struct fstab *fs; |
43 | register struct passwd *pw; | |
44 | register struct fileusage *fup; | |
45 | char quotafile[MAXPATHLEN]; | |
46 | int i, errs = 0; | |
fe35ac74 | 47 | |
6c299bfc KM |
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 ..."); | |
fe35ac74 KM |
62 | exit(1); |
63 | } | |
6c299bfc KM |
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)) | |
fe35ac74 | 76 | continue; |
6c299bfc KM |
77 | if (!aflag && |
78 | !(oneof(fs->fs_file, argv, argc) || | |
79 | oneof(fs->fs_spec, argv, argc))) | |
fe35ac74 | 80 | continue; |
6c299bfc KM |
81 | (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname); |
82 | errs += repquota(fs->fs_spec, quotafile); | |
fe35ac74 | 83 | } |
6c299bfc KM |
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 | } | |
fe35ac74 | 91 | |
6c299bfc KM |
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; | |
fe35ac74 | 101 | |
6c299bfc KM |
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) | |
fe35ac74 | 133 | continue; |
6c299bfc KM |
134 | if (fup->fu_name[0] != '\0') |
135 | printf("%-10s", fup->fu_name); | |
fe35ac74 | 136 | else |
6c299bfc KM |
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; | |
fe35ac74 | 154 | } |
6c299bfc KM |
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); | |
fe35ac74 KM |
170 | } |
171 | ||
6c299bfc KM |
172 | struct fileusage * |
173 | lookup(uid) | |
174 | u_short uid; | |
fe35ac74 | 175 | { |
6c299bfc | 176 | register struct fileusage *fup; |
fe35ac74 | 177 | |
6c299bfc KM |
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); | |
fe35ac74 | 205 | } |