du.c revision 209362
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1989, 1993, 1994 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * This code is derived from software contributed to Berkeley by 61590Srgrimes * Chris Newcomb. 71590Srgrimes * 81590Srgrimes * Redistribution and use in source and binary forms, with or without 91590Srgrimes * modification, are permitted provided that the following conditions 101590Srgrimes * are met: 111590Srgrimes * 1. Redistributions of source code must retain the above copyright 121590Srgrimes * notice, this list of conditions and the following disclaimer. 131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer in the 151590Srgrimes * documentation and/or other materials provided with the distribution. 161590Srgrimes * 3. All advertising materials mentioning features or use of this software 171590Srgrimes * must display the following acknowledgement: 181590Srgrimes * This product includes software developed by the University of 191590Srgrimes * California, Berkeley and its contributors. 201590Srgrimes * 4. Neither the name of the University nor the names of its contributors 211590Srgrimes * may be used to endorse or promote products derived from this software 221590Srgrimes * without specific prior written permission. 231590Srgrimes * 241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341590Srgrimes * SUCH DAMAGE. 351590Srgrimes */ 361590Srgrimes 371590Srgrimes#ifndef lint 3841568Sarchiestatic const char copyright[] = 391590Srgrimes"@(#) Copyright (c) 1989, 1993, 1994\n\ 401590Srgrimes The Regents of the University of California. All rights reserved.\n"; 411590Srgrimes#endif /* not lint */ 421590Srgrimes 431590Srgrimes#ifndef lint 4456597Smharo#if 0 4541568Sarchiestatic const char sccsid[] = "@(#)du.c 8.5 (Berkeley) 5/4/95"; 4656597Smharo#endif 471590Srgrimes#endif /* not lint */ 4899112Sobrien#include <sys/cdefs.h> 4999112Sobrien__FBSDID("$FreeBSD: head/usr.bin/du/du.c 209362 2010-06-20 08:27:03Z brian $"); 501590Srgrimes 511590Srgrimes#include <sys/param.h> 5278158Sroam#include <sys/queue.h> 531590Srgrimes#include <sys/stat.h> 541590Srgrimes 551590Srgrimes#include <err.h> 561590Srgrimes#include <errno.h> 5778158Sroam#include <fnmatch.h> 581590Srgrimes#include <fts.h> 59129678Spjd#include <libutil.h> 60132201Stjr#include <locale.h> 61139813Spjd#include <stdint.h> 621590Srgrimes#include <stdio.h> 631590Srgrimes#include <stdlib.h> 641590Srgrimes#include <string.h> 6556597Smharo#include <sysexits.h> 6623693Speter#include <unistd.h> 671590Srgrimes 6878158SroamSLIST_HEAD(ignhead, ignentry) ignores; 6978158Sroamstruct ignentry { 7078158Sroam char *mask; 7178158Sroam SLIST_ENTRY(ignentry) next; 7278158Sroam}; 7378158Sroam 74128772Skientzlestatic int linkchk(FTSENT *); 7592920Simpstatic void usage(void); 76184656Smlaierstatic void prthumanval(int64_t); 77184656Smlaierstatic void ignoreadd(const char *); 78184656Smlaierstatic void ignoreclean(void); 79184656Smlaierstatic int ignorep(FTSENT *); 80191677Simpstatic void siginfo(int __unused); 811590Srgrimes 82184656Smlaierstatic int nodumpflag = 0; 83184733Smlaierstatic int Aflag; 84184733Smlaierstatic long blocksize, cblocksize; 85191677Simpstatic volatile sig_atomic_t info; 86158339Smaxim 871590Srgrimesint 88100822Sdwmalonemain(int argc, char *argv[]) 891590Srgrimes{ 9032097Sjkh FTS *fts; 9132097Sjkh FTSENT *p; 92184733Smlaier off_t savednumber, curblocks; 93209362Sbrian off_t threshold, threshold_sign; 9432097Sjkh int ftsoptions; 9532097Sjkh int listall; 9632097Sjkh int depth; 97176561Skeramida int Hflag, Lflag, Pflag, aflag, sflag, dflag, cflag; 98176561Skeramida int hflag, lflag, ch, notused, rval; 9932097Sjkh char **save; 10087216Smarkm static char dot[] = "."; 1011590Srgrimes 102132201Stjr setlocale(LC_ALL, ""); 103132201Stjr 104176561Skeramida Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag = 105184733Smlaier lflag = Aflag = 0; 106128772Skientzle 1071590Srgrimes save = argv; 10832097Sjkh ftsoptions = 0; 109184654Smlaier savednumber = 0; 110209362Sbrian threshold = 0; 111209362Sbrian threshold_sign = 1; 112184733Smlaier cblocksize = DEV_BSIZE; 113184733Smlaier blocksize = 0; 11419120Sscrappy depth = INT_MAX; 11578158Sroam SLIST_INIT(&ignores); 116128772Skientzle 117209362Sbrian while ((ch = getopt(argc, argv, "AB:HI:LPasd:chklmnrt:x")) != -1) 1181590Srgrimes switch (ch) { 119184733Smlaier case 'A': 120184733Smlaier Aflag = 1; 121184733Smlaier break; 122184733Smlaier case 'B': 123184733Smlaier errno = 0; 124184733Smlaier cblocksize = atoi(optarg); 125184733Smlaier if (errno == ERANGE || cblocksize <= 0) { 126184733Smlaier warnx("invalid argument to option B: %s", 127184733Smlaier optarg); 128184733Smlaier usage(); 129184733Smlaier } 130184733Smlaier break; 131184654Smlaier case 'H': 132184654Smlaier Hflag = 1; 133184654Smlaier break; 134184654Smlaier case 'I': 135184654Smlaier ignoreadd(optarg); 136184654Smlaier break; 137184654Smlaier case 'L': 138184654Smlaier if (Pflag) 13919120Sscrappy usage(); 140184654Smlaier Lflag = 1; 141184654Smlaier break; 142184654Smlaier case 'P': 143184654Smlaier if (Lflag) 144184654Smlaier usage(); 145184654Smlaier Pflag = 1; 146184654Smlaier break; 147184654Smlaier case 'a': 148184654Smlaier aflag = 1; 149184654Smlaier break; 150184654Smlaier case 's': 151184654Smlaier sflag = 1; 152184654Smlaier break; 153184654Smlaier case 'd': 154184654Smlaier dflag = 1; 155184654Smlaier errno = 0; 156184654Smlaier depth = atoi(optarg); 157184654Smlaier if (errno == ERANGE || depth < 0) { 158184654Smlaier warnx("invalid argument to option d: %s", 159184654Smlaier optarg); 160184654Smlaier usage(); 161184654Smlaier } 162184654Smlaier break; 163184654Smlaier case 'c': 164184654Smlaier cflag = 1; 165184654Smlaier break; 166184654Smlaier case 'h': 167184654Smlaier hflag = 1; 168184654Smlaier break; 169184654Smlaier case 'k': 170184654Smlaier hflag = 0; 171184733Smlaier blocksize = 1024; 172184654Smlaier break; 173184654Smlaier case 'l': 174184654Smlaier lflag = 1; 175184654Smlaier break; 176184654Smlaier case 'm': 177184654Smlaier hflag = 0; 178184733Smlaier blocksize = 1048576; 179184654Smlaier break; 180184654Smlaier case 'n': 181184654Smlaier nodumpflag = 1; 182184654Smlaier break; 183184654Smlaier case 'r': /* Compatibility. */ 184184654Smlaier break; 185209362Sbrian case 't' : 186209362Sbrian if (expand_number(optarg, &threshold) != 0 || 187209362Sbrian threshold == 0) { 188209362Sbrian warnx("invalid threshold: %s", optarg); 189209362Sbrian usage(); 190209362Sbrian } else if (threshold < 0) 191209362Sbrian threshold_sign = -1; 192209362Sbrian break; 193184654Smlaier case 'x': 194184654Smlaier ftsoptions |= FTS_XDEV; 195184654Smlaier break; 196184654Smlaier case '?': 197184654Smlaier default: 198184654Smlaier usage(); 199184654Smlaier /* NOTREACHED */ 2001590Srgrimes } 20132097Sjkh 2021590Srgrimes argc -= optind; 2031590Srgrimes argv += optind; 2041590Srgrimes 2051590Srgrimes /* 2061590Srgrimes * XXX 2071590Srgrimes * Because of the way that fts(3) works, logical walks will not count 2081590Srgrimes * the blocks actually used by symbolic links. We rationalize this by 2091590Srgrimes * noting that users computing logical sizes are likely to do logical 2101590Srgrimes * copies, so not counting the links is correct. The real reason is 2111590Srgrimes * that we'd have to re-implement the kernel's symbolic link traversing 2121590Srgrimes * algorithm to get this right. If, for example, you have relative 2131590Srgrimes * symbolic links referencing other relative symbolic links, it gets 2141590Srgrimes * very nasty, very fast. The bottom line is that it's documented in 2151590Srgrimes * the man page, so it's a feature. 2161590Srgrimes */ 21732097Sjkh 21832097Sjkh if (Hflag + Lflag + Pflag > 1) 21932097Sjkh usage(); 22032097Sjkh 22132097Sjkh if (Hflag + Lflag + Pflag == 0) 22232097Sjkh Pflag = 1; /* -P (physical) is default */ 22332097Sjkh 2241590Srgrimes if (Hflag) 2251590Srgrimes ftsoptions |= FTS_COMFOLLOW; 22632097Sjkh 22732097Sjkh if (Lflag) 2281590Srgrimes ftsoptions |= FTS_LOGICAL; 2291590Srgrimes 23032097Sjkh if (Pflag) 23132097Sjkh ftsoptions |= FTS_PHYSICAL; 23232097Sjkh 233184733Smlaier if (!Aflag && (cblocksize % DEV_BSIZE) != 0) 234184733Smlaier cblocksize = howmany(cblocksize, DEV_BSIZE) * DEV_BSIZE; 235184733Smlaier 23632097Sjkh listall = 0; 23732097Sjkh 2381590Srgrimes if (aflag) { 23919120Sscrappy if (sflag || dflag) 2401590Srgrimes usage(); 24132097Sjkh listall = 1; 24219120Sscrappy } else if (sflag) { 24319120Sscrappy if (dflag) 24419120Sscrappy usage(); 24532097Sjkh depth = 0; 2461590Srgrimes } 2471590Srgrimes 2481590Srgrimes if (!*argv) { 2491590Srgrimes argv = save; 25087216Smarkm argv[0] = dot; 2511590Srgrimes argv[1] = NULL; 2521590Srgrimes } 2531590Srgrimes 254184733Smlaier if (blocksize == 0) 255184733Smlaier (void)getbsize(¬used, &blocksize); 2561590Srgrimes 257184733Smlaier if (!Aflag) { 258184733Smlaier cblocksize /= DEV_BSIZE; 259184733Smlaier blocksize /= DEV_BSIZE; 260184733Smlaier } 261184733Smlaier 262209362Sbrian if (threshold != 0) 263209362Sbrian threshold = howmany(threshold / DEV_BSIZE * cblocksize, 264209362Sbrian blocksize); 265209362Sbrian 26632097Sjkh rval = 0; 267128772Skientzle 268191677Simp (void)signal(SIGINFO, siginfo); 269191677Simp 2701590Srgrimes if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL) 27132097Sjkh err(1, "fts_open"); 2721590Srgrimes 27332097Sjkh while ((p = fts_read(fts)) != NULL) { 2741590Srgrimes switch (p->fts_info) { 275184654Smlaier case FTS_D: /* Ignore. */ 276184654Smlaier if (ignorep(p)) 277184654Smlaier fts_set(fts, p, FTS_SKIP); 278184654Smlaier break; 279184654Smlaier case FTS_DP: 280184654Smlaier if (ignorep(p)) 2811590Srgrimes break; 28278158Sroam 283184733Smlaier curblocks = Aflag ? 284184733Smlaier howmany(p->fts_statp->st_size, cblocksize) : 285184733Smlaier howmany(p->fts_statp->st_blocks, cblocksize); 286184654Smlaier p->fts_parent->fts_bignum += p->fts_bignum += 287184733Smlaier curblocks; 288128772Skientzle 289209362Sbrian if (p->fts_level <= depth && threshold <= 290209362Sbrian threshold_sign * howmany(p->fts_bignum * 291209362Sbrian cblocksize, blocksize)) { 292184654Smlaier if (hflag) { 293184733Smlaier prthumanval(p->fts_bignum); 294184654Smlaier (void)printf("\t%s\n", p->fts_path); 295184654Smlaier } else { 296184654Smlaier (void)printf("%jd\t%s\n", 297184742Smlaier (intmax_t)howmany(p->fts_bignum * 298184742Smlaier cblocksize, blocksize), 299184742Smlaier p->fts_path); 30058601Scharnier } 301184654Smlaier } 302191677Simp if (info) { 303191677Simp info = 0; 304191677Simp (void)printf("\t%s\n", p->fts_path); 305191677Simp } 306184654Smlaier break; 307184654Smlaier case FTS_DC: /* Ignore. */ 308184654Smlaier break; 309184654Smlaier case FTS_DNR: /* Warn, continue. */ 310184654Smlaier case FTS_ERR: 311184654Smlaier case FTS_NS: 312184654Smlaier warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); 313184654Smlaier rval = 1; 314184654Smlaier break; 315184654Smlaier default: 316184654Smlaier if (ignorep(p)) 31732097Sjkh break; 318184654Smlaier 319184654Smlaier if (lflag == 0 && p->fts_statp->st_nlink > 1 && 320184654Smlaier linkchk(p)) 32132097Sjkh break; 32278158Sroam 323184733Smlaier curblocks = Aflag ? 324184733Smlaier howmany(p->fts_statp->st_size, cblocksize) : 325184733Smlaier howmany(p->fts_statp->st_blocks, cblocksize); 326184733Smlaier 327184654Smlaier if (listall || p->fts_level == 0) { 328184654Smlaier if (hflag) { 329184733Smlaier prthumanval(curblocks); 330184654Smlaier (void)printf("\t%s\n", p->fts_path); 331184654Smlaier } else { 332184654Smlaier (void)printf("%jd\t%s\n", 333184742Smlaier (intmax_t)howmany(curblocks * 334184742Smlaier cblocksize, blocksize), 335184742Smlaier p->fts_path); 33658601Scharnier } 337184654Smlaier } 33832097Sjkh 339184733Smlaier p->fts_parent->fts_bignum += curblocks; 3401590Srgrimes } 341139813Spjd savednumber = p->fts_parent->fts_bignum; 34232097Sjkh } 34332097Sjkh 3441590Srgrimes if (errno) 3451590Srgrimes err(1, "fts_read"); 34632097Sjkh 34758601Scharnier if (cflag) { 34856597Smharo if (hflag) { 349184733Smlaier prthumanval(savednumber); 350184654Smlaier (void)printf("\ttotal\n"); 35156597Smharo } else { 352184654Smlaier (void)printf("%jd\ttotal\n", (intmax_t)howmany( 353184733Smlaier savednumber * cblocksize, blocksize)); 35456597Smharo } 35558601Scharnier } 35632097Sjkh 35778158Sroam ignoreclean(); 35828891Swosch exit(rval); 3591590Srgrimes} 3601590Srgrimes 361128772Skientzlestatic int 362128772Skientzlelinkchk(FTSENT *p) 363128772Skientzle{ 364128772Skientzle struct links_entry { 365128806Skientzle struct links_entry *next; 366128806Skientzle struct links_entry *previous; 367128806Skientzle int links; 368128806Skientzle dev_t dev; 369128806Skientzle ino_t ino; 370128772Skientzle }; 371128806Skientzle static const size_t links_hash_initial_size = 8192; 372128806Skientzle static struct links_entry **buckets; 373128806Skientzle static struct links_entry *free_list; 374128806Skientzle static size_t number_buckets; 375128806Skientzle static unsigned long number_entries; 376128806Skientzle static char stop_allocating; 377128806Skientzle struct links_entry *le, **new_buckets; 378128806Skientzle struct stat *st; 379128806Skientzle size_t i, new_size; 380144840Sstefanf int hash; 38132097Sjkh 382128772Skientzle st = p->fts_statp; 38332097Sjkh 384128772Skientzle /* If necessary, initialize the hash table. */ 385128772Skientzle if (buckets == NULL) { 386128772Skientzle number_buckets = links_hash_initial_size; 387128772Skientzle buckets = malloc(number_buckets * sizeof(buckets[0])); 388128772Skientzle if (buckets == NULL) 389128834Skientzle errx(1, "No memory for hardlink detection"); 390128772Skientzle for (i = 0; i < number_buckets; i++) 391128772Skientzle buckets[i] = NULL; 392128772Skientzle } 3931590Srgrimes 394128772Skientzle /* If the hash table is getting too full, enlarge it. */ 395128772Skientzle if (number_entries > number_buckets * 10 && !stop_allocating) { 396128772Skientzle new_size = number_buckets * 2; 397128772Skientzle new_buckets = malloc(new_size * sizeof(struct links_entry *)); 398128772Skientzle 399128772Skientzle /* Try releasing the free list to see if that helps. */ 400128772Skientzle if (new_buckets == NULL && free_list != NULL) { 401128772Skientzle while (free_list != NULL) { 402128772Skientzle le = free_list; 403128772Skientzle free_list = le->next; 404128772Skientzle free(le); 405128772Skientzle } 406184654Smlaier new_buckets = malloc(new_size * 407184654Smlaier sizeof(new_buckets[0])); 408128772Skientzle } 409128772Skientzle 410128772Skientzle if (new_buckets == NULL) { 411128772Skientzle stop_allocating = 1; 412128834Skientzle warnx("No more memory for tracking hard links"); 413128772Skientzle } else { 414128772Skientzle memset(new_buckets, 0, 415128772Skientzle new_size * sizeof(struct links_entry *)); 416128772Skientzle for (i = 0; i < number_buckets; i++) { 417128772Skientzle while (buckets[i] != NULL) { 418128772Skientzle /* Remove entry from old bucket. */ 419128772Skientzle le = buckets[i]; 420128772Skientzle buckets[i] = le->next; 421128772Skientzle 422128772Skientzle /* Add entry to new bucket. */ 423128772Skientzle hash = (le->dev ^ le->ino) % new_size; 424128772Skientzle 425128772Skientzle if (new_buckets[hash] != NULL) 426128772Skientzle new_buckets[hash]->previous = 427128772Skientzle le; 428128772Skientzle le->next = new_buckets[hash]; 429128772Skientzle le->previous = NULL; 430128772Skientzle new_buckets[hash] = le; 431128772Skientzle } 432128772Skientzle } 433128772Skientzle free(buckets); 434128772Skientzle buckets = new_buckets; 435128772Skientzle number_buckets = new_size; 436128772Skientzle } 437128772Skientzle } 438128772Skientzle 439128772Skientzle /* Try to locate this entry in the hash table. */ 440128772Skientzle hash = ( st->st_dev ^ st->st_ino ) % number_buckets; 441128772Skientzle for (le = buckets[hash]; le != NULL; le = le->next) { 442128772Skientzle if (le->dev == st->st_dev && le->ino == st->st_ino) { 443128772Skientzle /* 444128772Skientzle * Save memory by releasing an entry when we've seen 445128772Skientzle * all of it's links. 446128772Skientzle */ 447128772Skientzle if (--le->links <= 0) { 448128772Skientzle if (le->previous != NULL) 449128772Skientzle le->previous->next = le->next; 450128772Skientzle if (le->next != NULL) 451128772Skientzle le->next->previous = le->previous; 452128772Skientzle if (buckets[hash] == le) 453128772Skientzle buckets[hash] = le->next; 454128772Skientzle number_entries--; 455128772Skientzle /* Recycle this node through the free list */ 456128772Skientzle if (stop_allocating) { 457128772Skientzle free(le); 458128772Skientzle } else { 459128772Skientzle le->next = free_list; 460128772Skientzle free_list = le; 461128772Skientzle } 462128772Skientzle } 463128772Skientzle return (1); 464128772Skientzle } 465128772Skientzle } 466128772Skientzle 467128772Skientzle if (stop_allocating) 468128772Skientzle return (0); 469128772Skientzle 470128772Skientzle /* Add this entry to the links cache. */ 471128772Skientzle if (free_list != NULL) { 472128772Skientzle /* Pull a node from the free list if we can. */ 473128772Skientzle le = free_list; 474128772Skientzle free_list = le->next; 475128772Skientzle } else 476128772Skientzle /* Malloc one if we have to. */ 477128772Skientzle le = malloc(sizeof(struct links_entry)); 478128772Skientzle if (le == NULL) { 479128772Skientzle stop_allocating = 1; 480128834Skientzle warnx("No more memory for tracking hard links"); 481128772Skientzle return (0); 482128772Skientzle } 483128772Skientzle le->dev = st->st_dev; 484128772Skientzle le->ino = st->st_ino; 485128772Skientzle le->links = st->st_nlink - 1; 486128772Skientzle number_entries++; 487128772Skientzle le->next = buckets[hash]; 488128772Skientzle le->previous = NULL; 489128772Skientzle if (buckets[hash] != NULL) 490128772Skientzle buckets[hash]->previous = le; 491128772Skientzle buckets[hash] = le; 4921590Srgrimes return (0); 4931590Srgrimes} 4941590Srgrimes 495184656Smlaierstatic void 496129678Spjdprthumanval(int64_t bytes) 49756597Smharo{ 498129678Spjd char buf[5]; 49956597Smharo 500184733Smlaier bytes *= cblocksize; 501184733Smlaier if (!Aflag) 502184733Smlaier bytes *= DEV_BSIZE; 50356597Smharo 504129678Spjd humanize_number(buf, sizeof(buf), bytes, "", HN_AUTOSCALE, 505129678Spjd HN_B | HN_NOSPACE | HN_DECIMAL); 50656597Smharo 507129678Spjd (void)printf("%4s", buf); 50856597Smharo} 50956597Smharo 51027099Scharnierstatic void 511100822Sdwmaloneusage(void) 5121590Srgrimes{ 5131590Srgrimes (void)fprintf(stderr, 514184733Smlaier "usage: du [-A] [-H | -L | -P] [-a | -s | -d depth] [-c] " 515184733Smlaier "[-l] [-h | -k | -m | -B bsize] [-n] [-x] [-I mask] " 516184733Smlaier "[file ...]\n"); 51756597Smharo exit(EX_USAGE); 5181590Srgrimes} 51978158Sroam 520184656Smlaierstatic void 521100822Sdwmaloneignoreadd(const char *mask) 52278158Sroam{ 52378158Sroam struct ignentry *ign; 52478158Sroam 52578158Sroam ign = calloc(1, sizeof(*ign)); 52678158Sroam if (ign == NULL) 52778158Sroam errx(1, "cannot allocate memory"); 52878158Sroam ign->mask = strdup(mask); 52978158Sroam if (ign->mask == NULL) 53078158Sroam errx(1, "cannot allocate memory"); 53178158Sroam SLIST_INSERT_HEAD(&ignores, ign, next); 53278158Sroam} 53378158Sroam 534184656Smlaierstatic void 535100822Sdwmaloneignoreclean(void) 53678158Sroam{ 53778158Sroam struct ignentry *ign; 53878158Sroam 53978158Sroam while (!SLIST_EMPTY(&ignores)) { 54078158Sroam ign = SLIST_FIRST(&ignores); 54178158Sroam SLIST_REMOVE_HEAD(&ignores, next); 54278158Sroam free(ign->mask); 54378158Sroam free(ign); 54478158Sroam } 54578158Sroam} 54678158Sroam 547184656Smlaierstatic int 548100822Sdwmaloneignorep(FTSENT *ent) 54978158Sroam{ 55078158Sroam struct ignentry *ign; 55178158Sroam 552158339Smaxim if (nodumpflag && (ent->fts_statp->st_flags & UF_NODUMP)) 553158339Smaxim return 1; 55478158Sroam SLIST_FOREACH(ign, &ignores, next) 55578158Sroam if (fnmatch(ign->mask, ent->fts_name, 0) != FNM_NOMATCH) 55678158Sroam return 1; 55778158Sroam return 0; 55878158Sroam} 559191677Simp 560191677Simpstatic void 561191677Simpsiginfo(int sig __unused) 562191677Simp{ 563191677Simp 564191677Simp info = 1; 565191677Simp} 566