excludes.c revision 60418
160418Swollman/*
260418Swollman * Copyright 2000 Massachusetts Institute of Technology
360418Swollman *
460418Swollman * Permission to use, copy, modify, and distribute this software and
560418Swollman * its documentation for any purpose and without fee is hereby
660418Swollman * granted, provided that both the above copyright notice and this
760418Swollman * permission notice appear in all copies, that both the above
860418Swollman * copyright notice and this permission notice appear in all
960418Swollman * supporting documentation, and that the name of M.I.T. not be used
1060418Swollman * in advertising or publicity pertaining to distribution of the
1160418Swollman * software without specific, written prior permission.  M.I.T. makes
1260418Swollman * no representations about the suitability of this software for any
1360418Swollman * purpose.  It is provided "as is" without express or implied
1460418Swollman * warranty.
1560418Swollman *
1660418Swollman * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
1760418Swollman * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
1860418Swollman * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1960418Swollman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
2060418Swollman * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2160418Swollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2260418Swollman * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2360418Swollman * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2460418Swollman * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2560418Swollman * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2660418Swollman * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2760418Swollman * SUCH DAMAGE.
2860418Swollman */
2960418Swollman
3060418Swollmanstatic const char rcsid[] =
3160418Swollman  "$FreeBSD: head/usr.sbin/mtree/excludes.c 60418 2000-05-12 03:03:00Z wollman $";
3260418Swollman
3360418Swollman#include <sys/types.h>
3460418Swollman#include <sys/queue.h>
3560418Swollman
3660418Swollman#include <err.h>
3760418Swollman#include <fnmatch.h>
3860418Swollman#include <fts.h>
3960418Swollman#include <stdio.h>
4060418Swollman#include <stdlib.h>
4160418Swollman
4260418Swollman/*
4360418Swollman * We're assuming that there won't be a whole lot of excludes,
4460418Swollman * so it's OK to use a stupid algorithm.
4560418Swollman */
4660418Swollmanstruct exclude {
4760418Swollman	LIST_ENTRY(exclude) link;
4860418Swollman	const char *glob;
4960418Swollman	int pathname;
5060418Swollman};
5160418Swollmanstatic LIST_HEAD(, exclude) excludes;
5260418Swollman
5360418Swollmanvoid
5460418Swollmaninit_excludes(void)
5560418Swollman{
5660418Swollman	LIST_INIT(&excludes);
5760418Swollman}
5860418Swollman
5960418Swollmanvoid
6060418Swollmanread_excludes_file(const char *name)
6160418Swollman{
6260418Swollman	FILE *fp;
6360418Swollman	char *line, *str;
6460418Swollman	struct exclude *e;
6560418Swollman	size_t len;
6660418Swollman
6760418Swollman	fp = fopen(name, "r");
6860418Swollman	if (fp == 0)
6960418Swollman		err(1, "%s", name);
7060418Swollman
7160418Swollman	while ((line = fgetln(fp, &len)) != 0) {
7260418Swollman		if (line[len - 1] == '\n')
7360418Swollman			len--;
7460418Swollman		if (len == 0)
7560418Swollman			continue;
7660418Swollman
7760418Swollman		str = malloc(len + 1);
7860418Swollman		e = malloc(sizeof *e);
7960418Swollman		if (str == 0 || e == 0)
8060418Swollman			errx(1, "memory allocation error");
8160418Swollman		e->glob = str;
8260418Swollman		memcpy(str, line, len);
8360418Swollman		str[len] = '\0';
8460418Swollman		if (strchr(str, '/'))
8560418Swollman			e->pathname = 1;
8660418Swollman		else
8760418Swollman			e->pathname = 0;
8860418Swollman		LIST_INSERT_HEAD(&excludes, e, link);
8960418Swollman	}
9060418Swollman	fclose(fp);
9160418Swollman}
9260418Swollman
9360418Swollmanint
9460418Swollmancheck_excludes(const char *fname, const char *path)
9560418Swollman{
9660418Swollman	struct exclude *e;
9760418Swollman
9860418Swollman	/* fnmatch(3) has a funny return value convention... */
9960418Swollman#define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0)
10060418Swollman
10160418Swollman	for (e = excludes.lh_first; e != 0; e = e->link.le_next) {
10260418Swollman		if (e->pathname && MATCH(e->glob, path)
10360418Swollman		    || MATCH(e->glob, fname))
10460418Swollman			return 1;
10560418Swollman	}
10660418Swollman	return 0;
10760418Swollman}
108