use getpwuid in addition to getlogin to get user name, and some cleanup
[unix-history] / usr / src / usr.sbin / repquota / repquota.c
CommitLineData
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
8char 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 14static 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
29struct 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
36struct fileusage *fuhead[FUHASH];
37struct fileusage *lookup();
38struct fileusage *adduid();
39int highuid;
fe35ac74 40
6c299bfc
KM
41long done;
42struct passwd *getpwent();
fe35ac74 43
6c299bfc
KM
44int vflag; /* verbose */
45int aflag; /* all file systems */
46
47char *qfname = "quotas";
6c299bfc 48struct dqblk zerodqblk;
fe35ac74
KM
49
50main(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
60again:
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 105repquota(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
182oneof(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
196struct fileusage *
197lookup(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
208struct fileusage *
209adduid(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}