|
|
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[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[BUFSIZ / 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(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: /* ! 94: blocks = (Statb.st_size + BSIZE-1) >> BSHIFT; ! 95: */ ! 96: blocks = (Statb.st_size + 511) >> 9; ! 97: ! 98: if((Statb.st_mode&S_IFMT)!=S_IFDIR) { ! 99: if(Aflag) ! 100: printf("%ld %s\n", blocks, np); ! 101: return(blocks); ! 102: } ! 103: ! 104: for(c1 = np; *c1; ++c1); ! 105: if(*(c1-1) == '/') ! 106: --c1; ! 107: endofname = c1; ! 108: dirsize = Statb.st_size; ! 109: if(chdir(fname) == -1) ! 110: return 0; ! 111: for(offset=0; offset < dirsize; offset += BUFSIZ) { /* each block */ ! 112: dsize = BUFSIZ<(dirsize-offset)? BUFSIZ: (dirsize-offset); ! 113: if(!dir) { ! 114: if((dir=open(".",0))<0) { ! 115: fprintf(stderr, "--cannot open < %s >\n", ! 116: np); ! 117: goto ret; ! 118: } ! 119: if(offset) lseek(dir, (long)offset, 0); ! 120: if(read(dir, (char *)dentry, dsize)<0) { ! 121: fprintf(stderr, "--cannot read < %s >\n", ! 122: np); ! 123: goto ret; ! 124: } ! 125: if(dir > 10) { ! 126: close(dir); ! 127: dir = 0; ! 128: } ! 129: } else ! 130: if(read(dir, (char *)dentry, dsize)<0) { ! 131: fprintf(stderr, "--cannot read < %s >\n", ! 132: np); ! 133: goto ret; ! 134: } ! 135: for(dp=dentry, entries=dsize>>4; entries; --entries, ++dp) { ! 136: /* each directory entry */ ! 137: if(dp->d_ino==0 ! 138: || EQ(dp->d_name, ".") ! 139: || EQ(dp->d_name, "..")) ! 140: continue; ! 141: c1 = endofname; ! 142: *c1++ = '/'; ! 143: c2 = dp->d_name; ! 144: for(i=0; i<DIRSIZ; ++i) ! 145: if(*c2) ! 146: *c1++ = *c2++; ! 147: else ! 148: break; ! 149: *c1 = '\0'; ! 150: if(c1 == endofname) /* ?? */ ! 151: return 0L; ! 152: blocks += descend(np, endofname+1); ! 153: } ! 154: } ! 155: *endofname = '\0'; ! 156: if(!Sflag) ! 157: printf("%ld %s\n", blocks, np); ! 158: ret: ! 159: if(dir) ! 160: close(dir); ! 161: if(chdir("..") == -1) { ! 162: *endofname = '\0'; ! 163: fprintf(stderr, "Bad directory <%s>\n", np); ! 164: while(*--endofname != '/'); ! 165: *endofname = '\0'; ! 166: if(chdir(np) == -1) ! 167: exit(1); ! 168: } ! 169: return(blocks); ! 170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.