|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.