home *** CD-ROM | disk | FTP | other *** search
- /*
- * Disk usage by user
- */
-
- char *dargv[] = {
- "/dev/rrp3",
- 0
- };
-
- #include <stdio.h>
- #include <ctype.h>
- #include <pwd.h>
- #include <sys/param.h>
- #include <sys/ino.h>
- #include <sys/inode.h>
- #include <sys/filsys.h>
-
- #define ITABSZ 256
- #define ISIZ (BSIZE/sizeof(struct dinode))
- #define NUID 300
- struct filsys sblock;
- struct dinode itab[ITABSZ];
- struct du
- {
- long blocks;
- long nfiles;
- int uid;
- char *name;
- } du[NUID];
- #define TSIZE 500
- int sizes[TSIZE];
- long overflow;
-
- int nflg;
- int fflg;
- int cflg;
-
- int fi;
- unsigned ino;
- unsigned nfiles;
-
- struct passwd *getpwent();
- char *malloc();
- char *copy();
-
- main(argc, argv)
- char **argv;
- {
- register int n;
- register struct passwd *lp;
- register char **p;
-
- for(n=0; n<NUID; n++)
- du[n].uid = n;
- while((lp=getpwent()) != 0) {
- n = lp->pw_uid;
- if (n>NUID)
- continue;
- if(du[n].name)
- continue;
- du[n].name = copy(lp->pw_name);
- }
- if (argc == 1) {
- for (p = dargv; *p;) {
- check(*p++);
- report();
- }
- return(0);
- }
- while (--argc) {
- argv++;
- if (argv[0][0]=='-') {
- if (argv[0][1]=='n')
- nflg++;
- else if (argv[0][1]=='f')
- fflg++;
- else if (argv[0][1]=='c')
- cflg++;
- } else {
- check(*argv);
- report();
- }
- }
- return(0);
- }
-
- check(file)
- char *file;
- {
- register unsigned i, j;
- register c;
-
- fi = open(file, 0);
- if (fi < 0) {
- printf("cannot open %s\n", file);
- return;
- }
- printf("%s:\n", file);
- sync();
- bread(1, (char *)&sblock, sizeof sblock);
- nfiles = (sblock.s_isize-2)*(BSIZE/sizeof(struct dinode));
- ino = 0;
- if (nflg) {
- if (isdigit(c = getchar()))
- ungetc(c, stdin);
- else while (c!='\n' && c != EOF)
- c = getchar();
- }
- for(i=2; ino<nfiles; i += ITABSZ/ISIZ) {
- bread(i, (char *)itab, sizeof itab);
- for (j=0; j<ITABSZ && ino<nfiles; j++) {
- ino++;
- acct(&itab[j]);
- }
- }
- }
-
- acct(ip)
- register struct dinode *ip;
- {
- register n;
- register char *np;
- static fino;
-
- if ((ip->di_mode&IFMT) == 0)
- return;
- if (cflg) {
- if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG)
- return;
- n = (ip->di_size+BSIZE-1)/BSIZE;
- if (n >= TSIZE) {
- overflow += n;
- n = TSIZE-1;
- }
- sizes[n]++;
- return;
- }
- if (ip->di_uid >= NUID)
- return;
- du[ip->di_uid].blocks += (ip->di_size+BSIZE-1)/BSIZE;
- du[ip->di_uid].nfiles++;
- if (nflg) {
- tryagain:
- if (fino==0)
- if (scanf("%d", &fino)<=0)
- return;
- if (fino > ino)
- return;
- if (fino<ino) {
- while ((n=getchar())!='\n' && n!=EOF)
- ;
- fino = 0;
- goto tryagain;
- }
- if (np = du[ip->di_uid].name)
- printf("%.7s ", np);
- else
- printf("%d ", ip->di_uid);
- while ((n = getchar())==' ' || n=='\t')
- ;
- putchar(n);
- while (n!=EOF && n!='\n') {
- n = getchar();
- putchar(n);
- }
- fino = 0;
- }
- }
-
- bread(bno, buf, cnt)
- unsigned bno;
- char *buf;
- {
-
- lseek(fi, (long)bno*BSIZE, 0);
- if (read(fi, buf, cnt) != cnt) {
- printf("read error %u\n", bno);
- exit(1);
- }
- }
-
- qcmp(p1, p2)
- register struct du *p1, *p2;
- {
- if (p1->blocks > p2->blocks)
- return(-1);
- if (p1->blocks < p2->blocks)
- return(1);
- return(strcmp(p1->name, p2->name));
- }
-
- report()
- {
- register i;
-
- if (nflg)
- return;
- if (cflg) {
- long t = 0;
- for (i=0; i<TSIZE-1; i++)
- if (sizes[i]) {
- t += i*sizes[i];
- printf("%d %d %D\n", i, sizes[i], t);
- }
- printf("%d %d %D\n", TSIZE-1, sizes[TSIZE-1], overflow+t);
- return;
- }
- qsort(du, NUID, sizeof(du[0]), qcmp);
- for (i=0; i<NUID; i++) {
- if (du[i].blocks==0)
- return;
- printf("%5D\t", du[i].blocks);
- if (fflg)
- printf("%5D\t", du[i].nfiles);
- if (du[i].name)
- printf("%s\n", du[i].name);
- else
- printf("#%d\n", du[i].uid);
- }
- }
-
- char *
- copy(s)
- char *s;
- {
- register char *p;
- register n;
-
- for(n=0; s[n]; n++)
- ;
- p = malloc((unsigned)n+1);
- for(n=0; p[n] = s[n]; n++)
- ;
- return(p);
- }
-