int main(int argc, char *argv[]) { FTS *fts; FTSENT *p; long blocksize; quad_t totalblocks; int ftsoptions, listdirs, listfiles; int Hflag, Lflag, aflag, cflag, hflag, kflag, sflag; int ch, notused, rval; char **save; save = argv; Hflag = Lflag = aflag = cflag = hflag = kflag = sflag = 0; totalblocks = 0; ftsoptions = FTS_PHYSICAL; while ((ch = getopt(argc, argv, "HLPachksxr")) != -1) switch (ch) { case 'H': Hflag = 1; Lflag = 0; break; case 'L': Lflag = 1; Hflag = 0; break; case 'P': Hflag = Lflag = 0; break; case 'a': aflag = 1; break; case 'c': cflag = 1; break; case 'h': hflag = 1; kflag = 0; break; case 'k': kflag = 1; hflag = 0; break; case 's': sflag = 1; break; case 'r': break; case 'x': ftsoptions |= FTS_XDEV; break; case '?': default: usage(); } argc -= optind; argv += optind; /* * XXX * Because of the way that fts(3) works, logical walks will not count * the blocks actually used by symbolic links. We rationalize this by * noting that users computing logical sizes are likely to do logical * copies, so not counting the links is correct. The real reason is * that we'd have to re-implement the kernel's symbolic link traversing * algorithm to get this right. If, for example, you have relative * symbolic links referencing other relative symbolic links, it gets * very nasty, very fast. The bottom line is that it's documented in * the man page, so it's a feature. */ if (Hflag) ftsoptions |= FTS_COMFOLLOW; if (Lflag) { ftsoptions &= ~FTS_PHYSICAL; ftsoptions |= FTS_LOGICAL; } if (aflag) { if (sflag) usage(); listdirs = listfiles = 1; } else if (sflag) listdirs = listfiles = 0; else { listfiles = 0; listdirs = 1; } if (!*argv) { argv = save; argv[0] = "."; argv[1] = NULL; } if (hflag) blocksize = 512; else if (kflag) blocksize = 1024; else (void)getbsize(¬used, &blocksize); blocksize /= 512; if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL) err(1, "fts_open"); for (rval = 0; (p = fts_read(fts)) != NULL;) switch (p->fts_info) { case FTS_D: /* Ignore. */ break; case FTS_DP: p->fts_parent->fts_number += p->fts_number += p->fts_statp->st_blocks; if (cflag) totalblocks += p->fts_statp->st_blocks; /* * If listing each directory, or not listing files * or directories and this is post-order of the * root of a traversal, display the total. */ if (listdirs || (!listfiles && p->fts_level == FTS_ROOTLEVEL)) { prtout((quad_t)howmany(p->fts_number, (unsigned long)blocksize), p->fts_path, hflag); } break; case FTS_DC: /* Ignore. */ break; case FTS_DNR: /* Warn, continue. */ case FTS_ERR: case FTS_NS: warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; default: if (p->fts_statp->st_nlink > 1 && linkchk(p)) break; /* * If listing each file, or a non-directory file was * the root of a traversal, display the total. */ if (listfiles || p->fts_level == FTS_ROOTLEVEL) prtout(howmany(p->fts_statp->st_blocks, blocksize), p->fts_path, hflag); p->fts_parent->fts_number += p->fts_statp->st_blocks; if (cflag) totalblocks += p->fts_statp->st_blocks; } if (errno) err(1, "fts_read"); if (cflag) { prtout((quad_t)howmany(totalblocks, blocksize), "total", hflag); } exit(rval); }
int main(int argc, char *argv[]) { FTS *fts; FTSENT *p; off_t savednumber = 0; long blocksize; int ftsoptions; int listall; int depth; int Hflag, Lflag, Pflag, aflag, sflag, dflag, cflag, hflag, ch, notused, rval; char **save; static char dot[] = "."; off_t *ftsnum, *ftsparnum; setlocale(LC_ALL, ""); Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag = 0; save = argv; ftsoptions = FTS_NOCHDIR; depth = INT_MAX; SLIST_INIT(&ignores); while ((ch = getopt(argc, argv, "HI:LPasd:cghkmrx")) != -1) switch (ch) { case 'H': Lflag = Pflag = 0; Hflag = 1; break; case 'I': ignoreadd(optarg); break; case 'L': Hflag = Pflag = 0; Lflag = 1; break; case 'P': Hflag = Lflag = 0; Pflag = 1; break; case 'a': aflag = 1; break; case 's': sflag = 1; break; case 'd': dflag = 1; errno = 0; depth = atoi(optarg); if (errno == ERANGE || depth < 0) { warnx("invalid argument to option d: %s", optarg); usage(); } break; case 'c': cflag = 1; break; case 'h': putenv("BLOCKSIZE=512"); hflag = 1; valp = vals_base2; break; case 'k': hflag = 0; putenv("BLOCKSIZE=1024"); break; case 'm': hflag = 0; putenv("BLOCKSIZE=1048576"); break; case 'g': hflag = 0; putenv("BLOCKSIZE=1g"); break; case 'r': /* Compatibility. */ break; case 'x': ftsoptions |= FTS_XDEV; break; case '?': default: usage(); } // argc -= optind; argv += optind; /* * XXX * Because of the way that fts(3) works, logical walks will not count * the blocks actually used by symbolic links. We rationalize this by * noting that users computing logical sizes are likely to do logical * copies, so not counting the links is correct. The real reason is * that we'd have to re-implement the kernel's symbolic link traversing * algorithm to get this right. If, for example, you have relative * symbolic links referencing other relative symbolic links, it gets * very nasty, very fast. The bottom line is that it's documented in * the man page, so it's a feature. */ if (Hflag + Lflag + Pflag > 1) usage(); if (Hflag + Lflag + Pflag == 0) Pflag = 1; /* -P (physical) is default */ if (Hflag) ftsoptions |= FTS_COMFOLLOW; if (Lflag) ftsoptions |= FTS_LOGICAL; if (Pflag) ftsoptions |= FTS_PHYSICAL; listall = 0; if (aflag) { if (sflag || dflag) usage(); listall = 1; } else if (sflag) { if (dflag) usage(); depth = 0; } if (!*argv) { argv = save; argv[0] = dot; argv[1] = NULL; } (void) getbsize(¬used, &blocksize); blocksize /= 512; rval = 0; if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL) err(1, "fts_open"); while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_D: if (ignorep(p) || dirlinkchk(p)) fts_set(fts, p, FTS_SKIP); break; case FTS_DP: if (ignorep(p)) break; ftsparnum = (off_t *)&p->fts_parent->fts_number; ftsnum = (off_t *)&p->fts_number; if (p->fts_statp->st_size < TWO_TB) { ftsparnum[0] += ftsnum[0] += p->fts_statp->st_blocks; } else { ftsparnum[0] += ftsnum[0] += howmany(p->fts_statp->st_size, 512LL); } if (p->fts_level <= depth) { if (hflag) { (void) prthumanval(howmany(*ftsnum, blocksize)); (void) printf("\t%s\n", p->fts_path); } else { (void) printf("%jd\t%s\n", (intmax_t)howmany(*ftsnum, blocksize), p->fts_path); } } break; case FTS_DC: /* Ignore. */ if (COMPAT_MODE("bin/du", "unix2003")) { errx(1, "Can't follow symlink cycle from %s to %s", p->fts_path, p->fts_cycle->fts_path); } break; case FTS_DNR: /* Warn, continue. */ case FTS_ERR: case FTS_NS: warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; case FTS_SLNONE: if (COMPAT_MODE("bin/du", "unix2003")) { struct stat sb; int rc = stat(p->fts_path, &sb); if (rc < 0 && errno == ELOOP) { errx(1, "Too many symlinks at %s", p->fts_path); } } default: if (ignorep(p)) break; if (p->fts_statp->st_nlink > 1 && linkchk(p)) break; if (listall || p->fts_level == 0) { if (hflag) { if (p->fts_statp->st_size < TWO_TB) { (void) prthumanval(howmany(p->fts_statp->st_blocks, blocksize)); } else { (void) prthumanval(howmany(howmany(p->fts_statp->st_size, 512LL), blocksize)); } (void) printf("\t%s\n", p->fts_path); } else { if (p->fts_statp->st_size < TWO_TB) { (void) printf("%jd\t%s\n", (intmax_t)howmany(p->fts_statp->st_blocks, blocksize), p->fts_path); } else { (void) printf("%jd\t%s\n", (intmax_t)howmany(howmany(p->fts_statp->st_size, 512LL), blocksize), p->fts_path); } } } ftsparnum = (off_t *)&p->fts_parent->fts_number; if (p->fts_statp->st_size < TWO_TB) { ftsparnum[0] += p->fts_statp->st_blocks; } else { ftsparnum[0] += p->fts_statp->st_size / 512LL; } } savednumber = ((off_t *)&p->fts_parent->fts_number)[0]; } if (errno) err(1, "fts_read"); if (cflag) { if (hflag) { (void) prthumanval(howmany(savednumber, blocksize)); (void) printf("\ttotal\n"); } else { (void) printf("%jd\ttotal\n", (intmax_t)howmany(savednumber, blocksize)); } } ignoreclean(); exit(rval); }
int main(int argc, char *argv[]) { FTS *fts; FTSENT *p; off_t savednumber, curblocks; off_t threshold, threshold_sign; int ftsoptions; int listall; int depth; int Hflag, Lflag, Pflag, aflag, sflag, dflag, cflag; int hflag, lflag, ch, notused, rval; char **save; static char dot[] = "."; setlocale(LC_ALL, ""); Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag = lflag = Aflag = 0; save = argv; ftsoptions = 0; savednumber = 0; threshold = 0; threshold_sign = 1; cblocksize = DEV_BSIZE; blocksize = 0; depth = INT_MAX; SLIST_INIT(&ignores); while ((ch = getopt(argc, argv, "AB:HI:LPasd:chklmnrt:x")) != -1) switch (ch) { case 'A': Aflag = 1; break; case 'B': errno = 0; cblocksize = atoi(optarg); if (errno == ERANGE || cblocksize <= 0) { warnx("invalid argument to option B: %s", optarg); usage(); } break; case 'H': Hflag = 1; break; case 'I': ignoreadd(optarg); break; case 'L': if (Pflag) usage(); Lflag = 1; break; case 'P': if (Lflag) usage(); Pflag = 1; break; case 'a': aflag = 1; break; case 's': sflag = 1; break; case 'd': dflag = 1; errno = 0; depth = atoi(optarg); if (errno == ERANGE || depth < 0) { warnx("invalid argument to option d: %s", optarg); usage(); } break; case 'c': cflag = 1; break; case 'h': hflag = 1; break; case 'k': hflag = 0; blocksize = 1024; break; case 'l': lflag = 1; break; case 'm': hflag = 0; blocksize = 1048576; break; case 'n': nodumpflag = 1; break; case 'r': /* Compatibility. */ break; case 't' : if (expand_number(optarg, &threshold) != 0 || threshold == 0) { warnx("invalid threshold: %s", optarg); usage(); } else if (threshold < 0) threshold_sign = -1; break; case 'x': ftsoptions |= FTS_XDEV; break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; /* * XXX * Because of the way that fts(3) works, logical walks will not count * the blocks actually used by symbolic links. We rationalize this by * noting that users computing logical sizes are likely to do logical * copies, so not counting the links is correct. The real reason is * that we'd have to re-implement the kernel's symbolic link traversing * algorithm to get this right. If, for example, you have relative * symbolic links referencing other relative symbolic links, it gets * very nasty, very fast. The bottom line is that it's documented in * the man page, so it's a feature. */ if (Hflag + Lflag + Pflag > 1) usage(); if (Hflag + Lflag + Pflag == 0) Pflag = 1; /* -P (physical) is default */ if (Hflag) ftsoptions |= FTS_COMFOLLOW; if (Lflag) ftsoptions |= FTS_LOGICAL; if (Pflag) ftsoptions |= FTS_PHYSICAL; if (!Aflag && (cblocksize % DEV_BSIZE) != 0) cblocksize = howmany(cblocksize, DEV_BSIZE) * DEV_BSIZE; listall = 0; if (aflag) { if (sflag || dflag) usage(); listall = 1; } else if (sflag) { if (dflag) usage(); depth = 0; } if (!*argv) { argv = save; argv[0] = dot; argv[1] = NULL; } if (blocksize == 0) (void)getbsize(¬used, &blocksize); if (!Aflag) { cblocksize /= DEV_BSIZE; blocksize /= DEV_BSIZE; } if (threshold != 0) threshold = howmany(threshold / DEV_BSIZE * cblocksize, blocksize); rval = 0; (void)signal(SIGINFO, siginfo); if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL) err(1, "fts_open"); while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_D: /* Ignore. */ if (ignorep(p)) fts_set(fts, p, FTS_SKIP); break; case FTS_DP: if (ignorep(p)) break; curblocks = Aflag ? howmany(p->fts_statp->st_size, cblocksize) : howmany(p->fts_statp->st_blocks, cblocksize); p->fts_parent->fts_bignum += p->fts_bignum += curblocks; if (p->fts_level <= depth && threshold <= threshold_sign * howmany(p->fts_bignum * cblocksize, blocksize)) { if (hflag) { prthumanval(p->fts_bignum); (void)printf("\t%s\n", p->fts_path); } else { (void)printf("%jd\t%s\n", (intmax_t)howmany(p->fts_bignum * cblocksize, blocksize), p->fts_path); } } if (info) { info = 0; (void)printf("\t%s\n", p->fts_path); } break; case FTS_DC: /* Ignore. */ break; case FTS_DNR: /* Warn, continue. */ case FTS_ERR: case FTS_NS: warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; default: if (ignorep(p)) break; if (lflag == 0 && p->fts_statp->st_nlink > 1 && linkchk(p)) break; curblocks = Aflag ? howmany(p->fts_statp->st_size, cblocksize) : howmany(p->fts_statp->st_blocks, cblocksize); if (listall || p->fts_level == 0) { if (hflag) { prthumanval(curblocks); (void)printf("\t%s\n", p->fts_path); } else { (void)printf("%jd\t%s\n", (intmax_t)howmany(curblocks * cblocksize, blocksize), p->fts_path); } } p->fts_parent->fts_bignum += curblocks; } savednumber = p->fts_parent->fts_bignum; } if (errno) err(1, "fts_read"); if (cflag) { if (hflag) { prthumanval(savednumber); (void)printf("\ttotal\n"); } else { (void)printf("%jd\ttotal\n", (intmax_t)howmany( savednumber * cblocksize, blocksize)); } } ignoreclean(); exit(rval); }