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[256], name[256]; 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: fprintf(stderr, "cannot chdir()\n"); 47: exit(1); 48: } 49: } else 50: np = path; 51: blocks = descend(path, *np? np: "."); 52: if(Sflag) 53: printf("%ld %s\n", blocks, path); 54: } while(++i < argc); 55: 56: exit(0); 57: } 58: 59: long 60: descend(np, fname) 61: char *np, *fname; 62: { 63: int dir = 0, /* open directory */ 64: offset, 65: dsize, 66: entries, 67: dirsize; 68: 69: struct direct dentry[32]; 70: register struct direct *dp; 71: register char *c1, *c2; 72: int i; 73: char *endofname; 74: long blocks = 0; 75: 76: if(stat(fname,&Statb)<0) { 77: fprintf(stderr, "--bad status < %s >\n", name); 78: return 0L; 79: } 80: if(Statb.st_nlink > 1 && (Statb.st_mode&S_IFMT)!=S_IFDIR) { 81: static linked = 0; 82: 83: for(i = 0; i <= linked; ++i) { 84: if(ml[i].ino==Statb.st_ino && ml[i].dev==Statb.st_dev) 85: return 0; 86: } 87: if (linked < ML) { 88: ml[linked].dev = Statb.st_dev; 89: ml[linked].ino = Statb.st_ino; 90: ++linked; 91: } 92: } 93: blocks = (Statb.st_size + BSIZE-1) >> BSHIFT; 94: 95: if((Statb.st_mode&S_IFMT)!=S_IFDIR) { 96: if(Aflag) 97: printf("%ld %s\n", blocks, np); 98: return(blocks); 99: } 100: 101: for(c1 = np; *c1; ++c1); 102: if(*(c1-1) == '/') 103: --c1; 104: endofname = c1; 105: dirsize = Statb.st_size; 106: if(chdir(fname) == -1) 107: return 0; 108: for(offset=0; offset < dirsize; offset += 512) { /* each block */ 109: dsize = 512<(dirsize-offset)? 512: (dirsize-offset); 110: if(!dir) { 111: if((dir=open(".",0))<0) { 112: fprintf(stderr, "--cannot open < %s >\n", 113: np); 114: goto ret; 115: } 116: if(offset) lseek(dir, (long)offset, 0); 117: if(read(dir, (char *)dentry, dsize)<0) { 118: fprintf(stderr, "--cannot read < %s >\n", 119: np); 120: goto ret; 121: } 122: if(dir > 10) { 123: close(dir); 124: dir = 0; 125: } 126: } else 127: if(read(dir, (char *)dentry, dsize)<0) { 128: fprintf(stderr, "--cannot read < %s >\n", 129: np); 130: goto ret; 131: } 132: for(dp=dentry, entries=dsize>>4; entries; --entries, ++dp) { 133: /* each directory entry */ 134: if(dp->d_ino==0 135: || EQ(dp->d_name, ".") 136: || EQ(dp->d_name, "..")) 137: continue; 138: c1 = endofname; 139: *c1++ = '/'; 140: c2 = dp->d_name; 141: for(i=0; i<DIRSIZ; ++i) 142: if(*c2) 143: *c1++ = *c2++; 144: else 145: break; 146: *c1 = '\0'; 147: if(c1 == endofname) /* ?? */ 148: return 0L; 149: blocks += descend(np, endofname+1); 150: } 151: } 152: *endofname = '\0'; 153: if(!Sflag) 154: printf("%ld %s\n", blocks, np); 155: ret: 156: if(dir) 157: close(dir); 158: if(chdir("..") == -1) { 159: *endofname = '\0'; 160: fprintf(stderr, "Bad directory <%s>\n", np); 161: while(*--endofname != '/'); 162: *endofname = '\0'; 163: if(chdir(np) == -1) 164: exit(1); 165: } 166: return(blocks); 167: }