excludes.c revision 302408
1145522Sdarrenr/*
2145522Sdarrenr * Copyright 2000 Massachusetts Institute of Technology
353642Sguido *
4145522Sdarrenr * Permission to use, copy, modify, and distribute this software and
553642Sguido * its documentation for any purpose and without fee is hereby
680482Sdarrenr * granted, provided that both the above copyright notice and this
753642Sguido * permission notice appear in all copies, that both the above
8145522Sdarrenr * copyright notice and this permission notice appear in all
9145522Sdarrenr * supporting documentation, and that the name of M.I.T. not be used
10145522Sdarrenr * in advertising or publicity pertaining to distribution of the
11145522Sdarrenr * software without specific, written prior permission.  M.I.T. makes
12145522Sdarrenr * no representations about the suitability of this software for any
1353642Sguido * purpose.  It is provided "as is" without express or implied
1453642Sguido * warranty.
1553642Sguido *
1653642Sguido * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
1753642Sguido * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
1853642Sguido * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19153876Sguido * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
20153876Sguido * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21153876Sguido * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22145522Sdarrenr * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2353642Sguido * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2453642Sguido * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2553642Sguido * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26145522Sdarrenr * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27145522Sdarrenr * SUCH DAMAGE.
28145522Sdarrenr */
29145522Sdarrenr
30145522Sdarrenr#include <sys/cdefs.h>
31145522Sdarrenr__FBSDID("$FreeBSD: stable/11/usr.sbin/fmtree/excludes.c 298028 2016-04-15 03:38:58Z araujo $");
32145522Sdarrenr
3353642Sguido#include <sys/types.h>
34145522Sdarrenr#include <sys/time.h>		/* XXX for mtree.h */
3553642Sguido#include <sys/queue.h>
3653642Sguido
3753642Sguido#include <err.h>
3853642Sguido#include <fnmatch.h>
39145522Sdarrenr#include <fts.h>
40153876Sguido#include <stdio.h>
41153876Sguido#include <stdlib.h>
42145522Sdarrenr
4353642Sguido#include "mtree.h"		/* XXX for extern.h */
44145522Sdarrenr#include "extern.h"
45145522Sdarrenr
4653642Sguido/*
4753642Sguido * We're assuming that there won't be a whole lot of excludes,
48145522Sdarrenr * so it's OK to use a stupid algorithm.
49145522Sdarrenr */
50145522Sdarrenrstruct exclude {
51145522Sdarrenr	LIST_ENTRY(exclude) link;
52145522Sdarrenr	const char *glob;
53145522Sdarrenr	int pathname;
54145522Sdarrenr};
5553642Sguidostatic LIST_HEAD(, exclude) excludes;
56145522Sdarrenr
57145522Sdarrenrvoid
58145522Sdarrenrinit_excludes(void)
5953642Sguido{
6053642Sguido	LIST_INIT(&excludes);
6153642Sguido}
6253642Sguido
6353642Sguidovoid
6453642Sguidoread_excludes_file(const char *name)
6553642Sguido{
66227957Srmh	FILE *fp;
6753642Sguido	char *line, *str;
6853642Sguido	struct exclude *e;
6953642Sguido	size_t len;
7053642Sguido
7153642Sguido	fp = fopen(name, "r");
7253642Sguido	if (fp == NULL)
7353642Sguido		err(1, "%s", name);
7453642Sguido
7553642Sguido	while ((line = fgetln(fp, &len)) != NULL) {
7653642Sguido		if (line[len - 1] == '\n')
7753642Sguido			len--;
7853642Sguido		if (len == 0)
7953642Sguido			continue;
8053642Sguido
8153642Sguido		str = malloc(len + 1);
8253642Sguido		e = malloc(sizeof *e);
8353642Sguido		if (str == NULL || e == NULL)
8453642Sguido			errx(1, "memory allocation error");
8553642Sguido		e->glob = str;
8653642Sguido		memcpy(str, line, len);
8753642Sguido		str[len] = '\0';
8892685Sdarrenr		if (strchr(str, '/'))
8953642Sguido			e->pathname = 1;
9053642Sguido		else
9153642Sguido			e->pathname = 0;
9253642Sguido		LIST_INSERT_HEAD(&excludes, e, link);
93145522Sdarrenr	}
94145522Sdarrenr	fclose(fp);
95145522Sdarrenr}
96145522Sdarrenr
97145522Sdarrenrint
98145522Sdarrenrcheck_excludes(const char *fname, const char *path)
99145522Sdarrenr{
10080482Sdarrenr	struct exclude *e;
101145522Sdarrenr
102145522Sdarrenr	/* fnmatch(3) has a funny return value convention... */
10353642Sguido#define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0)
104145522Sdarrenr
105145522Sdarrenr	LIST_FOREACH(e, &excludes, link) {
106145522Sdarrenr		if ((e->pathname && MATCH(e->glob, path))
107172776Sdarrenr		    || MATCH(e->glob, fname))
10892685Sdarrenr			return 1;
10980482Sdarrenr	}
11053642Sguido	return 0;
11153642Sguido}
11253642Sguido