1244541Sbrooks/*	$NetBSD: excludes.c,v 1.13 2004/06/20 22:20:18 jmc Exp $	*/
2244541Sbrooks
3244541Sbrooks/*
4244541Sbrooks * Copyright 2000 Massachusetts Institute of Technology
5244541Sbrooks *
6244541Sbrooks * Permission to use, copy, modify, and distribute this software and
7244541Sbrooks * its documentation for any purpose and without fee is hereby
8244541Sbrooks * granted, provided that both the above copyright notice and this
9244541Sbrooks * permission notice appear in all copies, that both the above
10244541Sbrooks * copyright notice and this permission notice appear in all
11244541Sbrooks * supporting documentation, and that the name of M.I.T. not be used
12244541Sbrooks * in advertising or publicity pertaining to distribution of the
13244541Sbrooks * software without specific, written prior permission.  M.I.T. makes
14244541Sbrooks * no representations about the suitability of this software for any
15244541Sbrooks * purpose.  It is provided "as is" without express or implied
16244541Sbrooks * warranty.
17244541Sbrooks *
18244541Sbrooks * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
19244541Sbrooks * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
20244541Sbrooks * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21244541Sbrooks * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
22244541Sbrooks * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23244541Sbrooks * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24244541Sbrooks * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25244541Sbrooks * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26244541Sbrooks * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27244541Sbrooks * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28244541Sbrooks * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29244541Sbrooks * SUCH DAMAGE.
30244541Sbrooks */
31244541Sbrooks
32244541Sbrooks#if HAVE_NBTOOL_CONFIG_H
33244541Sbrooks#include "nbtool_config.h"
34244541Sbrooks#endif
35244541Sbrooks
36244541Sbrooks#include <sys/cdefs.h>
37244541Sbrooks
38244541Sbrooks#if defined(__RCSID) && !defined(lint)
39244541Sbrooks__RCSID("$NetBSD: excludes.c,v 1.13 2004/06/20 22:20:18 jmc Exp $");
40244541Sbrooks#endif
41244541Sbrooks
42244541Sbrooks#include <sys/types.h>
43244541Sbrooks#include <sys/queue.h>
44244541Sbrooks
45244541Sbrooks#include <fnmatch.h>
46244541Sbrooks#include <stdio.h>
47244541Sbrooks#include <stdlib.h>
48244541Sbrooks#include <string.h>
49244541Sbrooks#include <time.h>
50244541Sbrooks#include <util.h>
51244541Sbrooks
52244541Sbrooks#include "extern.h"
53244541Sbrooks
54244541Sbrooks
55244541Sbrooks/*
56244541Sbrooks * We're assuming that there won't be a whole lot of excludes,
57244541Sbrooks * so it's OK to use a stupid algorithm.
58244541Sbrooks */
59244541Sbrooksstruct exclude {
60244541Sbrooks	LIST_ENTRY(exclude) link;
61244541Sbrooks	const char *glob;
62244541Sbrooks	int pathname;
63244541Sbrooks};
64244541Sbrooksstatic LIST_HEAD(, exclude) excludes;
65244541Sbrooks
66244541Sbrooks
67244541Sbrooksvoid
68244541Sbrooksinit_excludes(void)
69244541Sbrooks{
70244541Sbrooks
71244541Sbrooks	LIST_INIT(&excludes);
72244541Sbrooks}
73244541Sbrooks
74244541Sbrooksvoid
75244541Sbrooksread_excludes_file(const char *name)
76244541Sbrooks{
77244541Sbrooks	FILE *fp;
78244541Sbrooks	char *line;
79244541Sbrooks	struct exclude *e;
80244541Sbrooks
81244541Sbrooks	fp = fopen(name, "r");
82244541Sbrooks	if (fp == 0)
83244541Sbrooks		err(1, "%s", name);
84244541Sbrooks
85244541Sbrooks	while ((line = fparseln(fp, NULL, NULL, NULL,
86244541Sbrooks	    FPARSELN_UNESCCOMM | FPARSELN_UNESCCONT | FPARSELN_UNESCESC))
87244541Sbrooks	    != NULL) {
88244541Sbrooks		if (line[0] == '\0')
89244541Sbrooks			continue;
90244541Sbrooks
91244541Sbrooks		if ((e = malloc(sizeof *e)) == NULL)
92244541Sbrooks			mtree_err("memory allocation error");
93244541Sbrooks
94244541Sbrooks		e->glob = line;
95244541Sbrooks		if (strchr(e->glob, '/') != NULL)
96244541Sbrooks			e->pathname = 1;
97244541Sbrooks		else
98244541Sbrooks			e->pathname = 0;
99244541Sbrooks		LIST_INSERT_HEAD(&excludes, e, link);
100244541Sbrooks	}
101244541Sbrooks	fclose(fp);
102244541Sbrooks}
103244541Sbrooks
104244541Sbrooksint
105244541Sbrookscheck_excludes(const char *fname, const char *path)
106244541Sbrooks{
107244541Sbrooks	struct exclude *e;
108244541Sbrooks
109244541Sbrooks	/* fnmatch(3) has a funny return value convention... */
110244541Sbrooks#define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0)
111244541Sbrooks
112244541Sbrooks	e = LIST_FIRST(&excludes);
113244541Sbrooks	while (e) {
114244541Sbrooks		if ((e->pathname && MATCH(e->glob, path))
115244541Sbrooks		    || MATCH(e->glob, fname)) {
116244541Sbrooks			return (1);
117244541Sbrooks		}
118244541Sbrooks		e = LIST_NEXT(e, link);
119244541Sbrooks	}
120244541Sbrooks	return (0);
121244541Sbrooks}
122