summaryrefslogtreecommitdiffstats
path: root/usr.bin/du/du.c
diff options
context:
space:
mode:
authorroam <roam@FreeBSD.org>2001-06-13 06:38:58 +0000
committerroam <roam@FreeBSD.org>2001-06-13 06:38:58 +0000
commiteaaabb7358692b5cc1f4f2871a4ea614517d80bf (patch)
tree1eba634df965a192a32cf342cc68d946cc193bdd /usr.bin/du/du.c
parent4d938abe903d007d3ca4d3f5d677bc66699457af (diff)
downloadFreeBSD-src-eaaabb7358692b5cc1f4f2871a4ea614517d80bf.zip
FreeBSD-src-eaaabb7358692b5cc1f4f2871a4ea614517d80bf.tar.gz
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
Diffstat (limited to 'usr.bin/du/du.c')
-rw-r--r--usr.bin/du/du.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/usr.bin/du/du.c b/usr.bin/du/du.c
index f2f7ad4..c53665b 100644
--- a/usr.bin/du/du.c
+++ b/usr.bin/du/du.c
@@ -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;
+}
OpenPOWER on IntegriCloud