|
|
1.1 root 1: /*
2: * Disk usage by user
3: */
4:
5: char *dargv[] = {
6: "/dev/usr",
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: #include <sys/stat.h>
18:
19: #define YEAR (24L*60L*60L*365L) /* a year in seconds */
20: #define ITABSZ 256
21: #define ISIZ(dev) (BSIZE(dev)/sizeof(struct dinode))
22: #define NUID 10000
23: struct filsys sblock;
24: struct dinode itab[ITABSZ];
25: struct du {
26: long blocks;
27: long nfiles;
28: double byteyears;
29: int uid;
30: char *name;
31: } du[NUID];
32: #define TSIZE 500
33: int sizes[TSIZE];
34: long overflow;
35: struct stat stb;
36: int dev;
37: long now;
38:
39: int nflg;
40: int fflg;
41: int cflg;
42: int bflg;
43:
44: int fi;
45: unsigned ino;
46: unsigned nfiles;
47:
48: struct passwd *getpwent();
49: char *malloc();
50: char *copy();
51:
52: main(argc, argv)
53: char **argv;
54: {
55: register int n;
56: register struct passwd *lp;
57: register char **p;
58:
59: for(n=0; n<NUID; n++)
60: du[n].uid = n;
61: while((lp=getpwent()) != 0) {
62: n = lp->pw_uid;
63: if (n>NUID)
64: continue;
65: if(du[n].name)
66: continue;
67: du[n].name = copy(lp->pw_name);
68: }
69: now = time((long *) NULL);
70: if (argc == 1) {
71: for (p = dargv; *p;)
72: check(*p++);
73: report();
74: return(0);
75: }
76: while (--argc) {
77: argv++;
78: if (argv[0][0]=='-') {
79: if (argv[0][1]=='n')
80: nflg++;
81: else if (argv[0][1]=='f')
82: fflg++;
83: else if (argv[0][1]=='c')
84: cflg++;
85: else if (argv[0][1] == 'b')
86: bflg++;
87: } else
88: check(*argv);
89: }
90: report();
91: return(0);
92: }
93:
94: check(file)
95: char *file;
96: {
97: register unsigned i, j;
98: register c;
99:
100: fi = open(file, 0);
101: if (fi < 0) {
102: fprintf(stderr, "quot: cannot open %s\n", file);
103: return;
104: }
105: fstat(fi, &stb);
106: dev = stb.st_rdev;
107: printf("%s:\n", file);
108: sync();
109: bread(1, (char *)&sblock, sizeof sblock);
110: nfiles = (sblock.s_isize-2)*(BSIZE(dev)/sizeof(struct dinode));
111: ino = 0;
112: if (nflg) {
113: if (isdigit(c = getchar()))
114: ungetc(c, stdin);
115: else while (c!='\n' && c != EOF)
116: c = getchar();
117: }
118: for(i=2; ino<nfiles; i += ITABSZ/ISIZ(dev)) {
119: bread(i, (char *)itab, sizeof itab);
120: for (j=0; j<ITABSZ && ino<nfiles; j++) {
121: ino++;
122: acct(&itab[j]);
123: }
124: }
125: close(fi);
126: }
127:
128: acct(ip)
129: register struct dinode *ip;
130: {
131: register n;
132: register char *np;
133: static fino;
134:
135: if ((ip->di_mode&IFMT) == 0)
136: return;
137: n = ((ip->di_size+BSIZE(dev)-1)/BSIZE(dev)) * (BSIZE(dev)/1024);
138: if (cflg) {
139: if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG)
140: return;
141: if (n >= TSIZE) {
142: overflow += n;
143: n = TSIZE-1;
144: }
145: sizes[n]++;
146: return;
147: }
148: if (ip->di_uid >= NUID || ip->di_uid<0)
149: return;
150: du[ip->di_uid].blocks += n;
151: du[ip->di_uid].nfiles++;
152: du[ip->di_uid].byteyears += (double) n * (double) (now - ip->di_mtime) / YEAR;
153: if (nflg) {
154: tryagain:
155: if (fino==0)
156: if (scanf("%d", &fino)<=0)
157: return;
158: if (fino > ino)
159: return;
160: if (fino<ino) {
161: while ((n=getchar())!='\n' && n!=EOF)
162: ;
163: fino = 0;
164: goto tryagain;
165: }
166: if (np = du[ip->di_uid].name)
167: printf("%.7s ", np);
168: else
169: printf("%d ", ip->di_uid);
170: while ((n = getchar())==' ' || n=='\t')
171: ;
172: putchar(n);
173: while (n!=EOF && n!='\n') {
174: n = getchar();
175: putchar(n);
176: }
177: fino = 0;
178: }
179: }
180:
181: bread(bno, buf, cnt)
182: unsigned bno;
183: char *buf;
184: {
185:
186: lseek(fi, (long)bno*BSIZE(dev), 0);
187: if (read(fi, buf, cnt) != cnt) {
188: printf("read error %u\n", bno);
189: exit(1);
190: }
191: }
192:
193: qcmp(p1, p2)
194: register struct du *p1, *p2;
195: {
196: if (p1->blocks > p2->blocks)
197: return(-1);
198: if (p1->blocks < p2->blocks)
199: return(1);
200: return(strcmp(p1->name, p2->name));
201: }
202:
203: report()
204: {
205: register i;
206:
207: if (nflg)
208: return;
209: if (cflg) {
210: long t = 0;
211: for (i=0; i<TSIZE-1; i++)
212: if (sizes[i]) {
213: t += i*sizes[i];
214: printf("%d %d %ld\n", i, sizes[i], t);
215: }
216: printf("%d %d %ld\n", TSIZE-1, sizes[TSIZE-1], overflow+t);
217: return;
218: }
219: qsort(du, NUID, sizeof(du[0]), qcmp);
220: for (i=0; i<NUID; i++) {
221: if (du[i].blocks==0)
222: return;
223: printf("%6ld\t", du[i].blocks);
224: if (fflg)
225: printf("%5ld\t", du[i].nfiles);
226: if (bflg)
227: printf("%15.2f\t", du[i].byteyears);
228: if (du[i].name)
229: printf("%s\n", du[i].name);
230: else
231: printf("#%d\n", du[i].uid);
232: }
233: }
234:
235: char *
236: copy(s)
237: char *s;
238: {
239: register char *p;
240: register n;
241:
242: for(n=0; s[n]; n++)
243: ;
244: p = malloc((unsigned)n+1);
245: for(n=0; p[n] = s[n]; n++)
246: ;
247: return(p);
248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.