From owner-freebsd-arch Wed Dec 13 17:49:13 2000 From owner-freebsd-arch@FreeBSD.ORG Wed Dec 13 17:49:08 2000 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from ringworld.nanolink.com (unknown [195.24.48.13]) by hub.freebsd.org (Postfix) with SMTP id D688037B402 for ; Wed, 13 Dec 2000 17:48:57 -0800 (PST) Received: (qmail 3870 invoked by uid 1000); 14 Dec 2000 01:48:04 -0000 Date: Thu, 14 Dec 2000 03:48:04 +0200 From: Peter Pentchev To: arch@FreeBSD.org Subject: add -I ignoremask option to du(1) Message-ID: <20001214034803.C575@ringworld.oblivion.bg> Mail-Followup-To: arch@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-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hi, Is there a reason no one has done this yet? :) I find it particularly nice for e.g. excluding CVS/ subdirs from du output. And yes, I know this can be done with a bit of find(1) hackery, but the attached patch seems almost good enough to me (modulo the **ignmasks storage; maybe a list would be in order there, but I think there would very rarely be many more than 2 or 3 ignore masks). Comments? Flames? "Shut-up-already"'s? :) G'luck, Peter -- This sentence would be seven words long if it were six words shorter. 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 2000/12/14 01:38:10 @@ -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 2000/12/14 01:38:10 @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -88,10 +89,16 @@ int unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA }; +char ** ignmasks = NULL; +int igncount = 0; + int linkchk __P((FTSENT *)); static void usage __P((void)); void prthumanval __P((double)); unit_t unit_adjust __P((double *)); +void ignoreadd __P((char *)); +void ignoreclean __P((void)); +int ignorep __P((FTSENT *)); int main(argc, argv) @@ -113,11 +120,14 @@ ftsoptions = 0; depth = INT_MAX; - 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 +234,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 +264,9 @@ rval = 1; break; default: + if (ignorep(p)) + break; + if (p->fts_statp->st_nlink > 1 && linkchk(p)) break; @@ -281,6 +299,7 @@ } } + ignoreclean(); exit(rval); } @@ -368,4 +387,47 @@ (void)fprintf(stderr, "usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h | -k] [-x] [file ...]\n"); exit(EX_USAGE); +} + +void +ignoreadd(mask) + char *mask; +{ + char *newmask, **newign; + unsigned l; + + l = strlen(mask) + 1; + if (newmask = (char *) malloc(l + 1), newmask == NULL) + err(1, "can't allocate memory"); + strlcpy(newmask, mask, l+1); /* strcpy? playing it safe.. */ + if (newign = realloc(ignmasks, (igncount + 1) * sizeof(*ignmasks)), + newign == NULL) + err(1, "can't allocate memory"); + newign[igncount++] = newmask; + ignmasks = newign; +} + +void +ignoreclean() +{ + int i; + + for(i = 0; i < igncount; i++) + free(ignmasks[i]); + memset(ignmasks, 0, igncount * sizeof(*ignmasks)); + free(ignmasks); +} + +int +ignorep(ent) + FTSENT *ent; +{ + int i; + + if (igncount == 0) + return 0; + for(i = 0; i < igncount; i++) + if (fnmatch(ignmasks[i], ent->fts_name, 0) != FNM_NOMATCH) + return 1; + return 0; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message