From owner-freebsd-audit Sat Apr 28 9:44:56 2001 Delivered-To: freebsd-audit@freebsd.org Received: from ringworld.nanolink.com (ringworld.nanolink.com [195.24.48.13]) by hub.freebsd.org (Postfix) with SMTP id A654C37B423 for ; Sat, 28 Apr 2001 09:44:49 -0700 (PDT) (envelope-from roam@ringworld.nanolink.com) Received: (qmail 33019 invoked by uid 1000); 28 Apr 2001 16:42:59 -0000 Date: Sat, 28 Apr 2001 19:42:59 +0300 From: Peter Pentchev To: audit@FreeBSD.org Subject: du(1) -I option to ignore files/dirs Message-ID: <20010428194259.J415@ringworld.oblivion.bg> Mail-Followup-To: audit@FreeBSD.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hi, And just when -arch thought they'd gotten rid of me and my du(1) patches.. ;) Well, since no one had any real objections to adding the -I flag, other than 'no one else is doing that' (so why can't we?), and as several people agreed that there was no easy (or moderately hard) way to do this with other utils, here's an updated patch that properly uses slist's instead of the constant- sized arrays in the previous version. G'luck, Peter -- I am jealous of the first word in this sentence. Index: src/usr.bin/du/du.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/du/du.1,v retrieving revision 1.18 diff -u -r1.18 du.1 --- src/usr.bin/du/du.1 2000/11/20 19:20:41 1.18 +++ src/usr.bin/du/du.1 2001/04/28 16:42:25 @@ -41,6 +41,7 @@ .Sh SYNOPSIS .Nm .Op Fl P | Fl H | Fl L +.Op Fl I Ar mask .Op Fl a | s | d Ar depth .Op Fl c .Op Fl h | k @@ -72,6 +73,9 @@ 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 a Display an entry for each file in a file hierarchy. .It Fl h Index: src/usr.bin/du/du.c =================================================================== RCS file: /home/ncvs/src/usr.bin/du/du.c,v retrieving revision 1.19 diff -u -r1.19 du.c --- src/usr.bin/du/du.c 2000/03/26 14:21:57 1.19 +++ src/usr.bin/du/du.c 2001/04/28 16:42:26 @@ -50,10 +50,12 @@ #include +#include #include #include #include +#include #include #include #include @@ -88,10 +90,19 @@ 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 @@ 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 @@ 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 @@ rval = 1; break; default: + if (ignorep(p)) + break; + if (p->fts_statp->st_nlink > 1 && linkchk(p)) break; @@ -281,6 +304,7 @@ } } + ignoreclean(); exit(rval); } @@ -366,6 +390,48 @@ 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; + + if (SLIST_EMPTY(&ignores)) + return 0; + SLIST_FOREACH(ign, &ignores, next) + if (fnmatch(ign->mask, ent->fts_name, 0) != FNM_NOMATCH) + return 1; + return 0; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message