add copyright
[unix-history] / usr / src / usr.sbin / repquota / repquota.c
CommitLineData
fe35ac74 1#ifndef lint
824e2e71 2static 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
17struct 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
24struct fileusage *fuhead[FUHASH];
25struct fileusage *lookup();
26struct fileusage *adduid();
27int highuid;
fe35ac74 28
6c299bfc
KM
29long done;
30struct passwd *getpwent();
fe35ac74 31
6c299bfc
KM
32int vflag; /* verbose */
33int aflag; /* all file systems */
34
35char *qfname = "quotas";
36char quotafile[MAXPATHLEN + 1];
37struct dqblk zerodqblk;
fe35ac74
KM
38
39main(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
49again:
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
94repquota(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
167oneof(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
181struct fileusage *
182lookup(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
193struct fileusage *
194adduid(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}