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