added multiple copy control by printcap
[unix-history] / usr / src / usr.sbin / repquota / repquota.c
CommitLineData
fe35ac74 1#ifndef lint
6c299bfc 2static 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
16struct 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
23struct fileusage *fuhead[FUHASH];
24struct fileusage *lookup();
25struct fileusage *adduid();
26int highuid;
fe35ac74 27
6c299bfc
KM
28long done;
29struct passwd *getpwent();
fe35ac74 30
6c299bfc
KM
31int vflag; /* verbose */
32int aflag; /* all file systems */
33
34char *qfname = "quotas";
35char quotafile[MAXPATHLEN + 1];
36struct dqblk zerodqblk;
fe35ac74
KM
37
38main(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
48again:
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
92repquota(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
158oneof(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
172struct fileusage *
173lookup(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
184struct fileusage *
185adduid(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}