Add '-I mask' cmdline flag to ignore/skip files and subdirectories
matching a specified shell-glob mask. Reviewed by: no serious objections on -arch and -audit over the last few months MFC after: 1 month
This commit is contained in:
parent
8b9959ada8
commit
4bb69e3542
@ -41,6 +41,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl H | L | P
|
||||
.Op Fl I Ar mask
|
||||
.Op Fl a | s | d Ar depth
|
||||
.Op Fl c
|
||||
.Op Fl h | k
|
||||
@ -69,6 +70,9 @@ Symbolic links on the command line are followed, symbolic links in file
|
||||
hierarchies are not followed.
|
||||
.It Fl L
|
||||
Symbolic links on the command line and in file hierarchies are followed.
|
||||
.It Fl I Ar mask
|
||||
Ignore files and directories matching the specified
|
||||
.Ar mask .
|
||||
.It Fl P
|
||||
No symbolic links are followed.
|
||||
This is the default.
|
||||
|
@ -50,10 +50,12 @@ static const char rcsid[] =
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <fts.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
@ -88,10 +90,19 @@ typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t;
|
||||
|
||||
int unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA };
|
||||
|
||||
SLIST_HEAD(ignhead, ignentry) ignores;
|
||||
struct ignentry {
|
||||
char *mask;
|
||||
SLIST_ENTRY(ignentry) next;
|
||||
};
|
||||
|
||||
int linkchk __P((FTSENT *));
|
||||
static void usage __P((void));
|
||||
void prthumanval __P((double));
|
||||
unit_t unit_adjust __P((double *));
|
||||
void ignoreadd __P((const char *));
|
||||
void ignoreclean __P((void));
|
||||
int ignorep __P((FTSENT *));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -112,12 +123,16 @@ main(argc, argv)
|
||||
save = argv;
|
||||
ftsoptions = 0;
|
||||
depth = INT_MAX;
|
||||
SLIST_INIT(&ignores);
|
||||
|
||||
while ((ch = getopt(argc, argv, "HLPasd:chkrx")) != -1)
|
||||
while ((ch = getopt(argc, argv, "HI:LPasd:chkrx")) != -1)
|
||||
switch (ch) {
|
||||
case 'H':
|
||||
Hflag = 1;
|
||||
break;
|
||||
case 'I':
|
||||
ignoreadd(optarg);
|
||||
break;
|
||||
case 'L':
|
||||
if (Pflag)
|
||||
usage();
|
||||
@ -224,8 +239,13 @@ main(argc, argv)
|
||||
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;
|
||||
|
||||
p->fts_parent->fts_number +=
|
||||
p->fts_number += p->fts_statp->st_blocks;
|
||||
|
||||
@ -249,6 +269,9 @@ main(argc, argv)
|
||||
rval = 1;
|
||||
break;
|
||||
default:
|
||||
if (ignorep(p))
|
||||
break;
|
||||
|
||||
if (p->fts_statp->st_nlink > 1 && linkchk(p))
|
||||
break;
|
||||
|
||||
@ -281,6 +304,7 @@ main(argc, argv)
|
||||
}
|
||||
}
|
||||
|
||||
ignoreclean();
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
@ -366,6 +390,46 @@ static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h | -k] [-x] [file ...]\n");
|
||||
"usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h | -k] [-x] [-I mask] [file ...]\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
void
|
||||
ignoreadd(mask)
|
||||
const char *mask;
|
||||
{
|
||||
struct ignentry *ign;
|
||||
|
||||
ign = calloc(1, sizeof(*ign));
|
||||
if (ign == NULL)
|
||||
errx(1, "cannot allocate memory");
|
||||
ign->mask = strdup(mask);
|
||||
if (ign->mask == NULL)
|
||||
errx(1, "cannot allocate memory");
|
||||
SLIST_INSERT_HEAD(&ignores, ign, next);
|
||||
}
|
||||
|
||||
void
|
||||
ignoreclean()
|
||||
{
|
||||
struct ignentry *ign;
|
||||
|
||||
while (!SLIST_EMPTY(&ignores)) {
|
||||
ign = SLIST_FIRST(&ignores);
|
||||
SLIST_REMOVE_HEAD(&ignores, next);
|
||||
free(ign->mask);
|
||||
free(ign);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ignorep(ent)
|
||||
FTSENT *ent;
|
||||
{
|
||||
struct ignentry *ign;
|
||||
|
||||
SLIST_FOREACH(ign, &ignores, next)
|
||||
if (fnmatch(ign->mask, ent->fts_name, 0) != FNM_NOMATCH)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user