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