Bell 32V release
[unix-history] / usr / src / cmd / quot.c
CommitLineData
36e2e948
TL
1/*
2 * Disk usage by user
3 */
4
5char *dargv[] = {
6 "/dev/rrp3",
7 0
8};
9
10#include <stdio.h>
11#include <ctype.h>
12#include <pwd.h>
13#include <sys/param.h>
14#include <sys/ino.h>
15#include <sys/inode.h>
16#include <sys/filsys.h>
17
18#define ITABSZ 256
19#define ISIZ (BSIZE/sizeof(struct dinode))
20#define NUID 300
21struct filsys sblock;
22struct dinode itab[ITABSZ];
23struct du
24{
25 long blocks;
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;
37
38int fi;
39unsigned ino;
40unsigned nfiles;
41
42struct passwd *getpwent();
43char *malloc();
44char *copy();
45
46main(argc, argv)
47char **argv;
48{
49 register int n;
50 register struct passwd *lp;
51 register char **p;
52
53 for(n=0; n<NUID; n++)
54 du[n].uid = n;
55 while((lp=getpwent()) != 0) {
56 n = lp->pw_uid;
57 if (n>NUID)
58 continue;
59 if(du[n].name)
60 continue;
61 du[n].name = copy(lp->pw_name);
62 }
63 if (argc == 1) {
64 for (p = dargv; *p;) {
65 check(*p++);
66 report();
67 }
68 return(0);
69 }
70 while (--argc) {
71 argv++;
72 if (argv[0][0]=='-') {
73 if (argv[0][1]=='n')
74 nflg++;
75 else if (argv[0][1]=='f')
76 fflg++;
77 else if (argv[0][1]=='c')
78 cflg++;
79 } else {
80 check(*argv);
81 report();
82 }
83 }
84 return(0);
85}
86
87check(file)
88char *file;
89{
90 register unsigned i, j;
91 register c;
92
93 fi = open(file, 0);
94 if (fi < 0) {
95 printf("cannot open %s\n", file);
96 return;
97 }
98 printf("%s:\n", file);
99 sync();
100 bread(1, (char *)&sblock, sizeof sblock);
101 nfiles = (sblock.s_isize-2)*(BSIZE/sizeof(struct dinode));
102 ino = 0;
103 if (nflg) {
104 if (isdigit(c = getchar()))
105 ungetc(c, stdin);
106 else while (c!='\n' && c != EOF)
107 c = getchar();
108 }
109 for(i=2; ino<nfiles; i += ITABSZ/ISIZ) {
110 bread(i, (char *)itab, sizeof itab);
111 for (j=0; j<ITABSZ && ino<nfiles; j++) {
112 ino++;
113 acct(&itab[j]);
114 }
115 }
116}
117
118acct(ip)
119register struct dinode *ip;
120{
121 register n;
122 register char *np;
123 static fino;
124
125 if ((ip->di_mode&IFMT) == 0)
126 return;
127 if (cflg) {
128 if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG)
129 return;
130 n = (ip->di_size+BSIZE-1)/BSIZE;
131 if (n >= TSIZE) {
132 overflow += n;
133 n = TSIZE-1;
134 }
135 sizes[n]++;
136 return;
137 }
138 if (ip->di_uid >= NUID)
139 return;
140 du[ip->di_uid].blocks += (ip->di_size+BSIZE-1)/BSIZE;
141 du[ip->di_uid].nfiles++;
142 if (nflg) {
143 tryagain:
144 if (fino==0)
145 if (scanf("%d", &fino)<=0)
146 return;
147 if (fino > ino)
148 return;
149 if (fino<ino) {
150 while ((n=getchar())!='\n' && n!=EOF)
151 ;
152 fino = 0;
153 goto tryagain;
154 }
155 if (np = du[ip->di_uid].name)
156 printf("%.7s ", np);
157 else
158 printf("%d ", ip->di_uid);
159 while ((n = getchar())==' ' || n=='\t')
160 ;
161 putchar(n);
162 while (n!=EOF && n!='\n') {
163 n = getchar();
164 putchar(n);
165 }
166 fino = 0;
167 }
168}
169
170bread(bno, buf, cnt)
171unsigned bno;
172char *buf;
173{
174
175 lseek(fi, (long)bno*BSIZE, 0);
176 if (read(fi, buf, cnt) != cnt) {
177 printf("read error %u\n", bno);
178 exit(1);
179 }
180}
181
182qcmp(p1, p2)
183register struct du *p1, *p2;
184{
185 if (p1->blocks > p2->blocks)
186 return(-1);
187 if (p1->blocks < p2->blocks)
188 return(1);
189 return(strcmp(p1->name, p2->name));
190}
191
192report()
193{
194 register i;
195
196 if (nflg)
197 return;
198 if (cflg) {
199 long t = 0;
200 for (i=0; i<TSIZE-1; i++)
201 if (sizes[i]) {
202 t += i*sizes[i];
203 printf("%d %d %D\n", i, sizes[i], t);
204 }
205 printf("%d %d %D\n", TSIZE-1, sizes[TSIZE-1], overflow+t);
206 return;
207 }
208 qsort(du, NUID, sizeof(du[0]), qcmp);
209 for (i=0; i<NUID; i++) {
210 if (du[i].blocks==0)
211 return;
212 printf("%5D\t", du[i].blocks);
213 if (fflg)
214 printf("%5D\t", du[i].nfiles);
215 if (du[i].name)
216 printf("%s\n", du[i].name);
217 else
218 printf("#%d\n", du[i].uid);
219 }
220}
221
222char *
223copy(s)
224char *s;
225{
226 register char *p;
227 register n;
228
229 for(n=0; s[n]; n++)
230 ;
231 p = malloc((unsigned)n+1);
232 for(n=0; p[n] = s[n]; n++)
233 ;
234 return(p);
235}