Annotation of researchv9/cmd/du.c, revision 1.1.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.