Annotation of researchv9/cmd/du.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <sys/param.h>
        !             3: #include <sys/stat.h>
        !             4: #include <sys/dir.h>
        !             5: #define EQ(x,y)        (strcmp(x,y)==0)
        !             6: #define ML     1000
        !             7: 
        !             8: struct stat Statb;
        !             9: char   path[BUFSIZE], name[BUFSIZE];
        !            10: int    Aflag = 0,
        !            11:        Sflag = 0,
        !            12:        Noarg = 0;
        !            13: struct {
        !            14:        int     dev,
        !            15:                ino;
        !            16: } ml[ML];
        !            17: long   descend();
        !            18: char   *rindex();
        !            19: char   *strcpy();
        !            20: 
        !            21: main(argc, argv)
        !            22: char **argv;
        !            23: {
        !            24:        register        i = 1;
        !            25:        long    blocks = 0;
        !            26:        register char   *np;
        !            27: 
        !            28:        if (argc>1) {
        !            29:                if(EQ(argv[i], "-s")) {
        !            30:                        ++i;
        !            31:                        ++Sflag;
        !            32:                } else if(EQ(argv[i], "-a")) {
        !            33:                        ++i;
        !            34:                        ++Aflag;
        !            35:                }
        !            36:        }
        !            37:        if(i == argc)
        !            38:                ++Noarg;
        !            39: 
        !            40:        do {
        !            41:                strcpy(path, Noarg? ".": argv[i]);
        !            42:                strcpy(name, path);
        !            43:                if(np = rindex(name, '/')) {
        !            44:                        *np++ = '\0';
        !            45:                        if(chdir(*name? name: "/") == -1) {
        !            46:                                perror(*name? name: "/");
        !            47:                                exit(1);
        !            48:                        }
        !            49:                } else
        !            50:                        np = path;
        !            51:                blocks = descend(path, *np? np: ".", 0);
        !            52:                if(Sflag)
        !            53:                        printf("%ld\t%s\n", blocks, path);
        !            54:        } while(++i < argc);
        !            55: 
        !            56:        exit(0);
        !            57: }
        !            58: 
        !            59: long
        !            60: descend(np, fname, depth)
        !            61: char *np, *fname;
        !            62: {
        !            63:        int dir = 0, /* open directory */
        !            64:                offset,
        !            65:                dsize,
        !            66:                entries,
        !            67:                dirsize;
        !            68: 
        !            69:        struct direct dentry[BUFSIZE/sizeof(struct direct)];
        !            70:        register  struct direct *dp;
        !            71:        register char *c1, *c2;
        !            72:        int i;
        !            73:        char *endofname;
        !            74:        long blocks = 0;
        !            75: 
        !            76:        if(lstat(fname,&Statb)<0) {
        !            77:                perror(name);
        !            78:                fprintf(stderr, "--bad status < %s %s >\n", fname, name);
        !            79:                return 0L;
        !            80:        }
        !            81:        if(Statb.st_nlink > 1 && (Statb.st_mode&S_IFMT)!=S_IFDIR) {
        !            82:                static linked = 0;
        !            83: 
        !            84:                for(i = 0; i <= linked; ++i) {
        !            85:                        if(ml[i].ino==Statb.st_ino && ml[i].dev==Statb.st_dev)
        !            86:                                return 0;
        !            87:                }
        !            88:                if (linked < ML) {
        !            89:                        ml[linked].dev = Statb.st_dev;
        !            90:                        ml[linked].ino = Statb.st_ino;
        !            91:                        ++linked;
        !            92:                }
        !            93:        }
        !            94:        blocks = ((Statb.st_size+BSIZE(Statb.st_dev)-1)>>BSHIFT(Statb.st_dev)) *
        !            95:                 (BSIZE(Statb.st_dev)/BSIZE(0));
        !            96: 
        !            97:        if((Statb.st_mode&S_IFMT)!=S_IFDIR) {
        !            98:                if(Aflag)
        !            99:                        printf("%ld\t%s\n", blocks, np);
        !           100:                return(blocks);
        !           101:        }
        !           102: 
        !           103:        if(Aflag)
        !           104:                printf("%ld\t%s/\n", blocks, np);
        !           105:        for(c1 = np; *c1; ++c1);
        !           106:        if(*(c1-1) == '/')
        !           107:                --c1;
        !           108:        endofname = c1;
        !           109:        dirsize = Statb.st_size;
        !           110:        if(chdir(fname) == -1)
        !           111:                return 0;
        !           112:        for(offset=0; offset < dirsize; offset += BUFSIZE) { /* each block */
        !           113:                dsize = BUFSIZE<(dirsize-offset)? BUFSIZE: (dirsize-offset);
        !           114:                if(!dir) {
        !           115:                        if((dir=open(".",0))<0) {
        !           116:                                perror(".");
        !           117:                                fprintf(stderr, "--cannot open < %s >\n",
        !           118:                                        np);
        !           119:                                goto ret;
        !           120:                        }
        !           121:                        if(offset) lseek(dir, (long)offset, 0);
        !           122:                        if(read(dir, (char *)dentry, dsize)<0) {
        !           123:                                perror("read");
        !           124:                                fprintf(stderr, "--cannot read < %s >\n",
        !           125:                                        np);
        !           126:                                goto ret;
        !           127:                        }
        !           128:                        if(dir > 15) {
        !           129:                                close(dir);
        !           130:                                dir = 0;
        !           131:                        }
        !           132:                } else 
        !           133:                        if(read(dir, (char *)dentry, dsize)<0) {
        !           134:                                perror("read");
        !           135:                                fprintf(stderr, "--cannot read < %s >\n", np);
        !           136:                                goto ret;
        !           137:                        }
        !           138:                entries = dsize / sizeof(struct direct);
        !           139:                for(dp=dentry; entries; --entries, ++dp) {
        !           140:                        /* each directory entry */
        !           141:                        if(dp->d_ino==0 || EQ(dp->d_name, ".") || EQ(dp->d_name, ".."))
        !           142:                                continue;
        !           143:                        c1 = endofname;
        !           144:                        *c1++ = '/';
        !           145:                        c2 = dp->d_name;
        !           146:                        for(i=0; i<DIRSIZ; ++i)
        !           147:                                if(*c2)
        !           148:                                        *c1++ = *c2++;
        !           149:                                else
        !           150:                                        break;
        !           151:                        *c1 = '\0';
        !           152:                        if(c1 == endofname) /* ?? */
        !           153:                                return 0L;
        !           154:                        blocks += descend(np, endofname+1, depth+1);
        !           155:                }
        !           156:        }
        !           157:        *endofname = '\0';
        !           158:        if(!Sflag)
        !           159:                printf("%ld\t%s\n", blocks, np);
        !           160: ret:
        !           161:        if(dir)
        !           162:                close(dir);
        !           163:        if(chdir("..") == -1) {
        !           164:                *endofname = '\0';
        !           165:                perror("..");
        !           166:                fprintf(stderr, "Bad directory <%s>\n", np);
        !           167:                while(*--endofname != '/');
        !           168:                *endofname = '\0';
        !           169:                if(chdir(np) == -1)
        !           170:                        exit(1);
        !           171:        }
        !           172:        return(blocks);
        !           173: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.