version 1.6, 2000/04/16 04:21:34 |
version 1.7, 2001/02/23 19:14:21 |
|
|
#include <err.h> |
#include <err.h> |
#include <errno.h> |
#include <errno.h> |
#include <fts.h> |
#include <fts.h> |
|
#include <math.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
int linkchk __P((FTSENT *)); |
int linkchk __P((FTSENT *)); |
|
void prtout __P((quad_t, char *, int)); |
void usage __P((void)); |
void usage __P((void)); |
|
|
int |
int |
|
|
{ |
{ |
FTS *fts; |
FTS *fts; |
FTSENT *p; |
FTSENT *p; |
long blocksize, totalblocks; |
long blocksize; |
|
quad_t totalblocks; |
int ftsoptions, listdirs, listfiles; |
int ftsoptions, listdirs, listfiles; |
int Hflag, Lflag, Pflag, aflag, ch, cflag, kflag, notused, rval, sflag; |
int Hflag, Lflag, Pflag, aflag, cflag, hflag, kflag, sflag; |
|
int ch, notused, rval; |
char **save; |
char **save; |
|
|
save = argv; |
save = argv; |
Hflag = Lflag = Pflag = aflag = cflag = kflag = sflag = 0; |
Hflag = Lflag = Pflag = aflag = cflag = hflag = kflag = sflag = 0; |
totalblocks = 0; |
totalblocks = 0; |
ftsoptions = FTS_PHYSICAL; |
ftsoptions = FTS_PHYSICAL; |
while ((ch = getopt(argc, argv, "HLPacksxr")) != -1) |
while ((ch = getopt(argc, argv, "HLPachksxr")) != -1) |
switch (ch) { |
switch (ch) { |
case 'H': |
case 'H': |
Hflag = 1; |
Hflag = 1; |
|
|
case 'c': |
case 'c': |
cflag = 1; |
cflag = 1; |
break; |
break; |
|
case 'h': |
|
hflag = 1; |
|
break; |
case 'k': |
case 'k': |
blocksize = 1024; |
blocksize = 1024; |
kflag = 1; |
kflag = 1; |
|
|
argv[1] = NULL; |
argv[1] = NULL; |
} |
} |
|
|
if (!kflag) |
if (!kflag || hflag) |
(void)getbsize(¬used, &blocksize); |
(void)getbsize(¬used, &blocksize); |
blocksize /= 512; |
blocksize /= 512; |
|
|
|
|
* root of a traversal, display the total. |
* root of a traversal, display the total. |
*/ |
*/ |
if (listdirs || (!listfiles && !p->fts_level)) |
if (listdirs || (!listfiles && !p->fts_level)) |
(void)printf("%ld\t%s\n", |
prtout((quad_t)howmany(p->fts_number, blocksize), |
howmany(p->fts_number, blocksize), |
p->fts_path, hflag); |
p->fts_path); |
|
break; |
break; |
case FTS_DC: /* Ignore. */ |
case FTS_DC: /* Ignore. */ |
break; |
break; |
|
|
* the root of a traversal, display the total. |
* the root of a traversal, display the total. |
*/ |
*/ |
if (listfiles || !p->fts_level) |
if (listfiles || !p->fts_level) |
(void)printf("%qd\t%s\n", |
prtout(howmany(p->fts_statp->st_blocks, blocksize), |
howmany(p->fts_statp->st_blocks, blocksize), |
p->fts_path, hflag); |
p->fts_path); |
|
p->fts_parent->fts_number += p->fts_statp->st_blocks; |
p->fts_parent->fts_number += p->fts_statp->st_blocks; |
if (cflag) |
if (cflag) |
totalblocks += p->fts_statp->st_blocks; |
totalblocks += p->fts_statp->st_blocks; |
} |
} |
if (errno) |
if (errno) |
err(1, "fts_read"); |
err(1, "fts_read"); |
if (cflag) |
if (cflag) { |
(void)printf("%ld\ttotal\n", |
prtout((quad_t)howmany(totalblocks, blocksize), "total", hflag); |
howmany(totalblocks, blocksize)); |
} |
exit(rval); |
exit(rval); |
} |
} |
|
|
|
|
return (0); |
return (0); |
} |
} |
|
|
|
/* |
|
* "human-readable" output: use 3 digits max.--put unit suffixes at |
|
* the end. Makes output compact and easy-to-read. |
|
*/ |
|
|
|
typedef enum { NONE = 0, KILO, MEGA, GIGA, TERA, PETA /* , EXA */ } unit_t; |
|
|
|
unit_t |
|
unit_adjust(val) |
|
double *val; |
|
{ |
|
double abval; |
|
unit_t unit; |
|
|
|
abval = fabs(*val); |
|
if (abval < 1024) |
|
unit = NONE; |
|
else if (abval < 1048576ULL) { |
|
unit = KILO; |
|
*val /= 1024; |
|
} else if (abval < 1073741824ULL) { |
|
unit = MEGA; |
|
*val /= 1048576; |
|
} else if (abval < 1099511627776ULL) { |
|
unit = GIGA; |
|
*val /= 1073741824ULL; |
|
} else if (abval < 1125899906842624ULL) { |
|
unit = TERA; |
|
*val /= 1099511627776ULL; |
|
} else /* if (abval < 1152921504606846976ULL) */ { |
|
unit = PETA; |
|
*val /= 1125899906842624ULL; |
|
} |
|
return (unit); |
|
} |
|
|
void |
void |
|
prtout(size, path, hflag) |
|
quad_t size; |
|
char *path; |
|
int hflag; |
|
{ |
|
unit_t unit; |
|
double bytes; |
|
|
|
if (!hflag) |
|
(void)printf("%qd\t%s\n", size, path); |
|
else { |
|
bytes = (double)size * 512.0; |
|
unit = unit_adjust(&bytes); |
|
|
|
if (bytes == 0) |
|
(void)printf(" 0B\t%s\n", path); |
|
else if (bytes > 10) |
|
(void)printf("%.0f%c\t%s\n", bytes, "BKMGTPE"[unit], path); |
|
else |
|
(void)printf("%.1f%c\t%s\n", bytes, "BKMGTPE"[unit], path); |
|
} |
|
} |
|
|
|
void |
usage() |
usage() |
{ |
{ |
|
|
(void)fprintf(stderr, |
(void)fprintf(stderr, |
"usage: du [-H | -L | -P] [-a | -s] [-ckrx] [file ...]\n"); |
"usage: du [-H | -L | -P] [-a | -s] [-chkrx] [file ...]\n"); |
exit(1); |
exit(1); |
} |
} |