added depend label
[unix-history] / usr / src / usr.bin / quota / quota.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
304d49a2 13#ifndef lint
509d661f 14static char sccsid[] = "@(#)quota.c 5.4 (Berkeley) %G%";
2a18434a 15#endif not lint
304d49a2
KM
16
17/*
18 * Disk quota reporting program.
19 */
20#include <stdio.h>
21#include <fstab.h>
22#include <ctype.h>
23#include <pwd.h>
879c30d3 24#include <errno.h>
304d49a2
KM
25
26#include <sys/param.h>
304d49a2
KM
27#include <sys/quota.h>
28#include <sys/file.h>
29#include <sys/stat.h>
30
31int qflag;
32int vflag;
33int done;
34int morethanone;
a233b96c 35char *qfname = "quotas";
304d49a2
KM
36
37main(argc, argv)
38 char *argv[];
39{
40 register char *cp;
879c30d3 41 extern int errno;
304d49a2 42
509d661f 43 if (quota(Q_SYNC, 0, 0, (caddr_t)0) < 0 && errno == EINVAL) {
879c30d3
KM
44 fprintf(stderr, "There are no quotas on this system\n");
45 exit(0);
46 }
304d49a2
KM
47 argc--,argv++;
48 while (argc > 0) {
49 if (argv[0][0] == '-')
50 for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
51
52 case 'v':
53 vflag++;
54 break;
55
56 case 'q':
57 qflag++;
58 break;
59
60 default:
61 fprintf(stderr, "quota: %c: unknown option\n",
62 *cp);
63 exit(1);
64 }
65 else
66 break;
67 argc--, argv++;
68 }
69 morethanone = argc > 1;
70 if (argc == 0) {
71 showuid(getuid());
72 exit(0);
73 }
74 for (; argc > 0; argc--, argv++) {
75 if (alldigits(*argv))
76 showuid(atoi(*argv));
77 else
78 showname(*argv);
79 }
80}
81
82showuid(uid)
83 int uid;
84{
85 struct passwd *pwd = getpwuid(uid);
86
87 if (pwd == NULL)
88 showquotas(uid, "(no account)");
89 else
90 showquotas(uid, pwd->pw_name);
91}
92
93showname(name)
94 char *name;
95{
96 struct passwd *pwd = getpwnam(name);
97
98 if (pwd == NULL) {
99 fprintf(stderr, "quota: %s: unknown user\n", name);
100 return;
101 }
102 showquotas(pwd->pw_uid, name);
103}
104
105showquotas(uid, name)
106 int uid;
107 char *name;
108{
304d49a2 109 register struct fstab *fs;
509d661f 110 register char *msgi, *msgb;
879c30d3
KM
111 register enab = 1;
112 dev_t fsdev;
113 struct stat statb;
114 struct dqblk dqblk;
115 int myuid, fd;
116 char qfilename[MAXPATHLEN + 1], iwarn[8], dwarn[8];
304d49a2
KM
117
118 myuid = getuid();
119 if (uid != myuid && myuid != 0) {
120 printf("quota: %s (uid %d): permission denied\n", name, uid);
121 return;
122 }
123 done = 0;
509d661f 124 (void) setfsent();
304d49a2 125 while (fs = getfsent()) {
304d49a2
KM
126 if (stat(fs->fs_spec, &statb) < 0)
127 continue;
509d661f 128 msgi = msgb = (char *) 0;
304d49a2 129 fsdev = statb.st_rdev;
a233b96c
KM
130 (void) sprintf(qfilename, "%s/%s", fs->fs_file, qfname);
131 if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev)
304d49a2 132 continue;
509d661f 133 if (quota(Q_GETDLIM, uid, fsdev, (caddr_t)&dqblk) != 0) {
879c30d3 134 fd = open(qfilename, O_RDONLY);
304d49a2
KM
135 if (fd < 0)
136 continue;
509d661f
JL
137 (void) lseek(fd, (off_t)(uid * sizeof (dqblk)), L_SET);
138 switch (read(fd, (char *)&dqblk, sizeof dqblk)) {
605f81f3
S
139 case 0: /* EOF */
140 /*
141 * Convert implicit 0 quota (EOF)
142 * into an explicit one (zero'ed dqblk).
143 */
144 bzero((caddr_t)&dqblk, sizeof dqblk);
145 break;
146
147 case sizeof dqblk: /* OK */
148 break;
149
150 default: /* ERROR */
151 fprintf(stderr, "quota: read error in ");
152 perror(qfilename);
509d661f 153 (void) close(fd);
304d49a2
KM
154 continue;
155 }
509d661f 156 (void) close(fd);
605f81f3 157 if (!vflag && dqblk.dqb_isoftlimit == 0 &&
304d49a2
KM
158 dqblk.dqb_bsoftlimit == 0)
159 continue;
160 enab = 0;
161 }
162 if (dqblk.dqb_ihardlimit &&
163 dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit)
164 msgi = "File count limit reached on %s";
165 else if (enab && dqblk.dqb_iwarn == 0)
166 msgi = "Out of inode warnings on %s";
167 else if (dqblk.dqb_isoftlimit &&
168 dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit)
169 msgi = "Too many files on %s";
170 if (dqblk.dqb_bhardlimit &&
171 dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit)
172 msgb = "Block limit reached on %s";
173 else if (enab && dqblk.dqb_bwarn == 0)
174 msgb = "Out of block warnings on %s";
175 else if (dqblk.dqb_bsoftlimit &&
176 dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit)
177 msgb = "Over disc quota on %s";
178 if (dqblk.dqb_iwarn < MAX_IQ_WARN)
509d661f 179 (void) sprintf(iwarn, "%d", dqblk.dqb_iwarn);
304d49a2
KM
180 else
181 iwarn[0] = '\0';
182 if (dqblk.dqb_bwarn < MAX_DQ_WARN)
509d661f 183 (void) sprintf(dwarn, "%d", dqblk.dqb_bwarn);
304d49a2
KM
184 else
185 dwarn[0] = '\0';
186 if (qflag) {
187 if (msgi != (char *)0 || msgb != (char *)0)
188 heading(uid, name);
189 if (msgi != (char *)0)
190 xprintf(msgi, fs->fs_file);
191 if (msgb != (char *)0)
192 xprintf(msgb, fs->fs_file);
193 continue;
194 }
195 if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) {
196 heading(uid, name);
c085c6e0 197 printf("%10s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n"
304d49a2 198 , fs->fs_file
285a6d40 199 , dbtob(dqblk.dqb_curblocks) / 1024
304d49a2 200 , (msgb == (char *)0) ? ' ' : '*'
285a6d40
JB
201 , dbtob(dqblk.dqb_bsoftlimit) / 1024
202 , dbtob(dqblk.dqb_bhardlimit) / 1024
304d49a2
KM
203 , dwarn
204 , dqblk.dqb_curinodes
205 , (msgi == (char *)0) ? ' ' : '*'
206 , dqblk.dqb_isoftlimit
96b539f0 207 , dqblk.dqb_ihardlimit
304d49a2
KM
208 , iwarn
209 );
210 }
211 }
509d661f 212 (void) endfsent();
304d49a2
KM
213 if (!done && !qflag) {
214 if (morethanone)
509d661f 215 (void) putchar('\n');
304d49a2
KM
216 xprintf("Disc quotas for %s (uid %d):", name, uid);
217 xprintf("none.");
218 }
605f81f3 219 xprintf((char *)0);
304d49a2
KM
220}
221
222heading(uid, name)
223 int uid;
224 char *name;
225{
226
227 if (done++)
228 return;
605f81f3 229 xprintf((char *)0);
304d49a2
KM
230 if (qflag) {
231 if (!morethanone)
232 return;
233 xprintf("User %s (uid %d):", name, uid);
605f81f3 234 xprintf((char *)0);
304d49a2
KM
235 return;
236 }
509d661f 237 (void) putchar('\n');
304d49a2 238 xprintf("Disc quotas for %s (uid %d):", name, uid);
605f81f3 239 xprintf((char *)0);
c085c6e0 240 printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n"
304d49a2
KM
241 , "Filsys"
242 , "current"
243 , "quota"
244 , "limit"
245 , "#warns"
246 , "files"
247 , "quota"
248 , "limit"
249 , "#warns"
250 );
251}
252
605f81f3 253/*VARARGS1*/
304d49a2
KM
254xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6)
255 char *fmt;
256{
257 char buf[100];
258 static int column;
259
260 if (fmt == 0 && column || column >= 40) {
509d661f 261 (void) putchar('\n');
304d49a2
KM
262 column = 0;
263 }
264 if (fmt == 0)
265 return;
509d661f 266 (void) sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6);
304d49a2
KM
267 if (column != 0 && strlen(buf) < 39)
268 while (column++ < 40)
509d661f 269 (void) putchar(' ');
304d49a2 270 else if (column) {
509d661f 271 (void) putchar('\n');
304d49a2
KM
272 column = 0;
273 }
274 printf("%s", buf);
275 column += strlen(buf);
276}
277
278alldigits(s)
279 register char *s;
280{
281 register c;
282
283 c = *s++;
284 do {
285 if (!isdigit(c))
286 return (0);
287 } while (c = *s++);
288 return (1);
289}