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