|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Chris Newcomb. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif /* not lint */ ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)du.c 5.6 (Berkeley) 6/1/90"; ! 31: #endif /* not lint */ ! 32: ! 33: #include <sys/param.h> ! 34: #include <sys/stat.h> ! 35: #include <dirent.h> ! 36: #include <string.h> ! 37: #include <stdio.h> ! 38: ! 39: typedef struct _ID { ! 40: dev_t dev; ! 41: ino_t inode; ! 42: } ID; ! 43: ! 44: ID *files; ! 45: dev_t device; ! 46: int crossmounts, kvalue, listdirs, listfiles, maxfiles, numfiles; ! 47: char path[MAXPATHLEN + 1]; ! 48: ! 49: main(argc, argv) ! 50: int argc; ! 51: char **argv; ! 52: { ! 53: extern int optind, errno; ! 54: int ch; ! 55: char *malloc(), top[MAXPATHLEN + 1]; ! 56: ! 57: listdirs = crossmounts = 1; ! 58: while ((ch = getopt(argc, argv, "aksx")) != EOF) ! 59: switch(ch) { ! 60: case 'a': ! 61: listfiles = 1; ! 62: break; ! 63: case 'k': ! 64: kvalue = 1; ! 65: break; ! 66: case 's': ! 67: listfiles = listdirs = 0; ! 68: break; ! 69: case 'x': ! 70: crossmounts = 0; ! 71: break; ! 72: case '?': ! 73: default: ! 74: (void)fprintf(stderr, ! 75: "usage: du [-aksx] [name ...]\n"); ! 76: exit(1); ! 77: } ! 78: argv += optind; ! 79: ! 80: files = (ID *)malloc((u_int)(sizeof(ID) * (maxfiles = 128))); ! 81: ! 82: if (!*argv) ! 83: du("."); ! 84: else { ! 85: if (argv[1]) ! 86: (void)getwd(top); ! 87: for (;;) { ! 88: du(*argv); ! 89: if (!*++argv) ! 90: break; ! 91: if (chdir(top)) { ! 92: (void)fprintf(stderr, "du: %s: %s\n", ! 93: top, strerror(errno)); ! 94: exit(1); ! 95: } ! 96: } ! 97: } ! 98: exit(0); ! 99: } ! 100: ! 101: struct stat info; ! 102: ! 103: du(arg) ! 104: register char *arg; ! 105: { ! 106: extern int errno; ! 107: u_long total, descend(); ! 108: ! 109: if (lstat(arg, &info)) { ! 110: (void)fprintf(stderr, "du: %s: %s\n", arg, strerror(errno)); ! 111: return; ! 112: } ! 113: if ((info.st_mode&S_IFMT) != S_IFDIR) { ! 114: (void)printf("%ld\t%s\n", kvalue ? ! 115: howmany(info.st_blocks, 2) : info.st_blocks, arg); ! 116: return; ! 117: } ! 118: device = info.st_dev; ! 119: (void)strcpy(path, arg); ! 120: total = descend(path); ! 121: if (!listfiles && !listdirs) ! 122: (void)printf("%lu\t%s\n", ! 123: kvalue ? howmany(total, 2) : total, path); ! 124: } ! 125: ! 126: u_long ! 127: descend(endp) ! 128: register char *endp; ! 129: { ! 130: extern int errno; ! 131: register DIR *dir; ! 132: register ID *fp; ! 133: register struct dirent *dp; ! 134: u_long total; ! 135: char *realloc(); ! 136: ! 137: if (info.st_nlink > 1) { ! 138: for (fp = files + numfiles - 1; fp >= files; --fp) ! 139: if (info.st_ino == fp->inode && ! 140: info.st_dev == fp->dev) ! 141: return(0L); ! 142: if (numfiles == maxfiles) ! 143: files = (ID *)realloc((char *)files, ! 144: (u_int)(sizeof(ID) * (maxfiles += 128))); ! 145: files[numfiles].inode = info.st_ino; ! 146: files[numfiles].dev = info.st_dev; ! 147: ++numfiles; ! 148: } ! 149: total = info.st_blocks; ! 150: if ((info.st_mode&S_IFMT) == S_IFDIR) { ! 151: if (info.st_dev != device && !crossmounts) ! 152: return(0L); ! 153: if (chdir(endp) || !(dir = opendir("."))) { ! 154: (void)fprintf(stderr, "du: %s: %s\n", ! 155: path, strerror(errno)); ! 156: return(total); ! 157: } ! 158: for (; *endp; ++endp); ! 159: if (endp[-1] != '/') ! 160: *endp++ = '/'; ! 161: while (dp = readdir(dir)) { ! 162: if (dp->d_name[0] == '.' && (!dp->d_name[1] || ! 163: dp->d_name[1] == '.' && !dp->d_name[2])) ! 164: continue; ! 165: bcopy(dp->d_name, endp, dp->d_namlen + 1); ! 166: if (lstat(dp->d_name, &info)) { ! 167: (void)fprintf(stderr, "du: %s: %s\n", path, ! 168: strerror(errno)); ! 169: continue; ! 170: } ! 171: total += descend(endp); ! 172: } ! 173: closedir(dir); ! 174: if (chdir("..")) { ! 175: (void)fprintf(stderr, "du: ..: %s\n", strerror(errno)); ! 176: exit(1); ! 177: } ! 178: *--endp = '\0'; ! 179: if (listdirs) ! 180: (void)printf("%lu\t%s\n", ! 181: kvalue ? howmany(total, 2) : total, path); ! 182: } ! 183: else if (listfiles) ! 184: (void)printf("%lu\t%s\n", ! 185: kvalue ? howmany(total, 2) : total, path); ! 186: return(total); ! 187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.