date and time created 83/03/09 16:57:50 by ralph
[unix-history] / usr / src / usr.sbin / quot / quot.c
CommitLineData
f6910205 1static char *sccsid = "@(#)quot.c 4.3 (Berkeley) 82/10/24";
6430f2d0 2
bea492ce 3/*
6430f2d0 4 * quot
bea492ce
BJ
5 */
6
bea492ce
BJ
7#include <stdio.h>
8#include <ctype.h>
9#include <pwd.h>
10#include <sys/param.h>
bea492ce 11#include <sys/inode.h>
f6910205 12#include <sys/fs.h>
bea492ce 13
f6910205 14#define ISIZ (MAXBSIZE/sizeof(struct dinode))
bea492ce 15#define NUID 1000
f6910205
KM
16union {
17 struct fs u_sblock;
18 char dummy[SBSIZE];
19} sb_un;
20#define sblock sb_un.u_sblock
21struct dinode itab[MAXBSIZE/sizeof(struct dinode)];
bea492ce
BJ
22struct du
23{
24 long blocks;
6430f2d0 25 long blocks30,blocks60,blocks90;
bea492ce
BJ
26 long nfiles;
27 int uid;
28 char *name;
29} du[NUID];
30#define TSIZE 500
31int sizes[TSIZE];
32long overflow;
33
34int nflg;
35int fflg;
36int cflg;
6430f2d0 37int vflg;
f6910205 38int hflg;
6430f2d0 39long now;
bea492ce
BJ
40
41int fi;
42unsigned ino;
43unsigned nfiles;
44
45struct passwd *getpwent();
46char *malloc();
47char *copy();
48
49main(argc, argv)
50char **argv;
51{
52 register int n;
53 register struct passwd *lp;
54 register char **p;
55
6430f2d0 56 now = time(0);
bea492ce
BJ
57 for(n=0; n<NUID; n++)
58 du[n].uid = n;
59 while((lp=getpwent()) != 0) {
60 n = lp->pw_uid;
61 if (n>NUID)
62 continue;
63 if(du[n].name)
64 continue;
65 du[n].name = copy(lp->pw_name);
66 }
67 if (argc == 1) {
6430f2d0
BJ
68 fprintf(stderr, "usage: df device ...\n");
69 exit(1);
bea492ce
BJ
70 }
71 while (--argc) {
72 argv++;
73 if (argv[0][0]=='-') {
74 if (argv[0][1]=='n')
75 nflg++;
76 else if (argv[0][1]=='f')
77 fflg++;
78 else if (argv[0][1]=='c')
79 cflg++;
6430f2d0
BJ
80 else if (argv[0][1]=='v')
81 vflg++;
f6910205
KM
82 else if (argv[0][1]=='h')
83 hflg++;
bea492ce
BJ
84 } else {
85 check(*argv);
86 report();
87 }
88 }
89 return(0);
90}
91
92check(file)
93char *file;
94{
95 register unsigned i, j;
f6910205
KM
96 daddr_t iblk;
97 int c;
bea492ce
BJ
98
99 fi = open(file, 0);
100 if (fi < 0) {
101 printf("cannot open %s\n", file);
102 return;
103 }
104 printf("%s:\n", file);
105 sync();
f6910205 106 bread(SBLOCK, (char *)&sblock, SBSIZE);
bea492ce
BJ
107 if (nflg) {
108 if (isdigit(c = getchar()))
109 ungetc(c, stdin);
110 else while (c!='\n' && c != EOF)
111 c = getchar();
112 }
f6910205
KM
113 nfiles = sblock.fs_ipg * sblock.fs_ncg;
114 for (ino = 0; ino < nfiles; ) {
115 iblk = fsbtodb(&sblock, itod(&sblock, ino));
116 bread(iblk, (char *)itab, sblock.fs_bsize);
117 for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++) {
118 if (ino++ < ROOTINO)
119 continue;
bea492ce
BJ
120 acct(&itab[j]);
121 }
122 }
123}
124
125acct(ip)
f6910205 126 register struct dinode *ip;
bea492ce 127{
bea492ce 128 register char *np;
f6910205
KM
129 long blks, frags, size;
130 char n;
bea492ce
BJ
131 static fino;
132
133 if ((ip->di_mode&IFMT) == 0)
134 return;
f6910205
KM
135 if (!hflg) {
136 /*
137 * Assume that there are no holes in files.
138 */
139 blks = lblkno(&sblock, ip->di_size);
140 frags = blks * sblock.fs_frag +
141 numfrags(&sblock, dblksize(&sblock, ip, blks));
142 } else {
143 /*
144 * Actually go out and count the number of allocated blocks.
145 */
146 printf("Sorry, hard way not implemented yet...\n");
147 exit(1);
148 }
149 size = frags * sblock.fs_fsize / 1024;
bea492ce
BJ
150 if (cflg) {
151 if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG)
152 return;
f6910205
KM
153 if (size >= TSIZE) {
154 overflow += size;
155 size = TSIZE-1;
bea492ce 156 }
f6910205 157 sizes[size]++;
bea492ce
BJ
158 return;
159 }
160 if (ip->di_uid >= NUID)
161 return;
f6910205 162 du[ip->di_uid].blocks += size;
6430f2d0
BJ
163#define DAY (60 * 60 * 24) /* seconds per day */
164 if (now - ip->di_atime > 30 * DAY)
f6910205 165 du[ip->di_uid].blocks30 += size;
6430f2d0 166 if (now - ip->di_atime > 60 * DAY)
f6910205 167 du[ip->di_uid].blocks60 += size;
6430f2d0 168 if (now - ip->di_atime > 90 * DAY)
f6910205 169 du[ip->di_uid].blocks90 += size;
bea492ce
BJ
170 du[ip->di_uid].nfiles++;
171 if (nflg) {
172 tryagain:
173 if (fino==0)
174 if (scanf("%d", &fino)<=0)
175 return;
176 if (fino > ino)
177 return;
178 if (fino<ino) {
179 while ((n=getchar())!='\n' && n!=EOF)
180 ;
181 fino = 0;
182 goto tryagain;
183 }
184 if (np = du[ip->di_uid].name)
185 printf("%.7s ", np);
186 else
187 printf("%d ", ip->di_uid);
188 while ((n = getchar())==' ' || n=='\t')
189 ;
190 putchar(n);
191 while (n!=EOF && n!='\n') {
192 n = getchar();
193 putchar(n);
194 }
195 fino = 0;
196 }
197}
198
199bread(bno, buf, cnt)
200unsigned bno;
201char *buf;
202{
203
f6910205 204 lseek(fi, (long)bno*DEV_BSIZE, 0);
bea492ce
BJ
205 if (read(fi, buf, cnt) != cnt) {
206 printf("read error %u\n", bno);
207 exit(1);
208 }
209}
210
211qcmp(p1, p2)
212register struct du *p1, *p2;
213{
214 if (p1->blocks > p2->blocks)
215 return(-1);
216 if (p1->blocks < p2->blocks)
217 return(1);
218 return(strcmp(p1->name, p2->name));
219}
220
221report()
222{
223 register i;
224
225 if (nflg)
226 return;
227 if (cflg) {
228 long t = 0;
229 for (i=0; i<TSIZE-1; i++)
230 if (sizes[i]) {
231 t += i*sizes[i];
232 printf("%d %d %D\n", i, sizes[i], t);
233 }
234 printf("%d %d %D\n", TSIZE-1, sizes[TSIZE-1], overflow+t);
235 return;
236 }
237 qsort(du, NUID, sizeof(du[0]), qcmp);
238 for (i=0; i<NUID; i++) {
239 if (du[i].blocks==0)
240 return;
241 printf("%5D\t", du[i].blocks);
242 if (fflg)
243 printf("%5D\t", du[i].nfiles);
244 if (du[i].name)
6430f2d0 245 printf("%-8.8s", du[i].name);
bea492ce 246 else
6430f2d0
BJ
247 printf("#%-8d", du[i].uid);
248 if (vflg)
249 printf("\t%5D\t%5D\t%5D",
250 du[i].blocks30, du[i].blocks60, du[i].blocks90);
251 printf("\n");
bea492ce
BJ
252 }
253}
254
255char *
256copy(s)
257char *s;
258{
259 register char *p;
260 register n;
261
262 for(n=0; s[n]; n++)
263 ;
264 p = malloc((unsigned)n+1);
265 for(n=0; p[n] = s[n]; n++)
266 ;
267 return(p);
268}