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. 15121300Sphk * 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 30114601Sobrien#include <sys/cdefs.h> 31114601Sobrien__FBSDID("$FreeBSD: releng/11.0/usr.sbin/fmtree/excludes.c 298028 2016-04-15 03:38:58Z araujo $"); 3260418Swollman 3360418Swollman#include <sys/types.h> 3460647Swollman#include <sys/time.h> /* XXX for mtree.h */ 3560418Swollman#include <sys/queue.h> 3660418Swollman 3760418Swollman#include <err.h> 3860418Swollman#include <fnmatch.h> 3960418Swollman#include <fts.h> 4060418Swollman#include <stdio.h> 4160418Swollman#include <stdlib.h> 4260418Swollman 4360647Swollman#include "mtree.h" /* XXX for extern.h */ 4460647Swollman#include "extern.h" 4560647Swollman 4660418Swollman/* 47121300Sphk * We're assuming that there won't be a whole lot of excludes, 4860418Swollman * so it's OK to use a stupid algorithm. 4960418Swollman */ 5060418Swollmanstruct exclude { 5160938Sjake LIST_ENTRY(exclude) link; 5260418Swollman const char *glob; 5360418Swollman int pathname; 5460418Swollman}; 5560938Sjakestatic LIST_HEAD(, exclude) excludes; 5660418Swollman 5760418Swollmanvoid 5860418Swollmaninit_excludes(void) 5960418Swollman{ 6060418Swollman LIST_INIT(&excludes); 6160418Swollman} 6260418Swollman 6360418Swollmanvoid 6460418Swollmanread_excludes_file(const char *name) 6560418Swollman{ 6660418Swollman FILE *fp; 6760418Swollman char *line, *str; 6860418Swollman struct exclude *e; 6960418Swollman size_t len; 7060418Swollman 7160418Swollman fp = fopen(name, "r"); 72298028Saraujo if (fp == NULL) 7360418Swollman err(1, "%s", name); 7460418Swollman 75298028Saraujo while ((line = fgetln(fp, &len)) != NULL) { 7660418Swollman if (line[len - 1] == '\n') 7760418Swollman len--; 7860418Swollman if (len == 0) 7960418Swollman continue; 8060418Swollman 8160418Swollman str = malloc(len + 1); 8260418Swollman e = malloc(sizeof *e); 83298028Saraujo if (str == NULL || e == NULL) 8460418Swollman errx(1, "memory allocation error"); 8560418Swollman e->glob = str; 8660418Swollman memcpy(str, line, len); 8760418Swollman str[len] = '\0'; 8860418Swollman if (strchr(str, '/')) 8960418Swollman e->pathname = 1; 9060418Swollman else 9160418Swollman e->pathname = 0; 9260418Swollman LIST_INSERT_HEAD(&excludes, e, link); 9360418Swollman } 9460418Swollman fclose(fp); 9560418Swollman} 9660418Swollman 9760418Swollmanint 9860418Swollmancheck_excludes(const char *fname, const char *path) 9960418Swollman{ 10060418Swollman struct exclude *e; 10160418Swollman 10260418Swollman /* fnmatch(3) has a funny return value convention... */ 10360418Swollman#define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0) 10460418Swollman 10570486Sben LIST_FOREACH(e, &excludes, link) { 106121300Sphk if ((e->pathname && MATCH(e->glob, path)) 10760418Swollman || MATCH(e->glob, fname)) 10860418Swollman return 1; 10960418Swollman } 11060418Swollman return 0; 11160418Swollman} 112