diff --git a/compat/mtree/extern.h b/compat/mtree/extern.h deleted file mode 100644 index 85115d44319..00000000000 --- a/compat/mtree/extern.h +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: extern.h,v 1.28 2003/10/27 00:12:44 lukem Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)extern.h 8.1 (Berkeley) 6/6/93 - */ - -#include "mtree.h" - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#else -#define HAVE_STRUCT_STAT_ST_FLAGS 1 -#endif - -#include -#include - -#if HAVE_NETDB_H -/* For MAXHOSTNAMELEN on some platforms. */ -#include -#endif - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -void addtag(slist_t *, char *); -int check_excludes(const char *, const char *); -int compare(NODE *, FTSENT *); -int crc(int, u_int32_t *, u_int32_t *); -void cwalk(void); -void dump_nodes(const char *, NODE *, int); -void init_excludes(void); -int matchtags(NODE *); -void mtree_err(const char *, ...) - __attribute__((__format__(__printf__, 1, 2))); -const char *nodetype(u_int); -u_int parsekey(const char *, int *); -void parsetags(slist_t *, char *); -u_int parsetype(const char *); -void read_excludes_file(const char *); -const char *rlink(const char *); -int verify(void); - -extern int dflag, eflag, iflag, lflag, mflag, rflag, sflag, tflag, uflag; -extern int Wflag; -extern size_t mtree_lineno; -extern u_int32_t crc_total; -extern int ftsoptions, keys; -extern char fullpath[]; -extern slist_t includetags, excludetags; - - -#include "stat_flags.h" diff --git a/compat/mtree/misc.c b/compat/mtree/misc.c deleted file mode 100644 index 1f3e850e1a6..00000000000 --- a/compat/mtree/misc.c +++ /dev/null @@ -1,295 +0,0 @@ -/* $NetBSD: misc.c,v 1.25 2004/06/20 22:20:18 jmc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)misc.c 8.1 (Berkeley) 6/6/93 - */ - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: misc.c,v 1.25 2004/06/20 22:20:18 jmc Exp $"); -#endif /* not lint */ - -#include -#include - -#include -#include -#include -#include - -#include "extern.h" - -typedef struct _key { - const char *name; /* key name */ - u_int val; /* value */ - -#define NEEDVALUE 0x01 - u_int flags; -} KEY; - -/* NB: the following tables must be sorted lexically. */ -static KEY keylist[] = { - {"cksum", F_CKSUM, NEEDVALUE}, - {"device", F_DEV, NEEDVALUE}, - {"flags", F_FLAGS, NEEDVALUE}, - {"gid", F_GID, NEEDVALUE}, - {"gname", F_GNAME, NEEDVALUE}, - {"ignore", F_IGN, 0}, - {"link", F_SLINK, NEEDVALUE}, - {"md5", F_MD5, NEEDVALUE}, - {"md5digest", F_MD5, NEEDVALUE}, - {"mode", F_MODE, NEEDVALUE}, - {"nlink", F_NLINK, NEEDVALUE}, - {"optional", F_OPT, 0}, - {"rmd160", F_RMD160, NEEDVALUE}, - {"rmd160digest",F_RMD160, NEEDVALUE}, - {"sha1", F_SHA1, NEEDVALUE}, - {"sha1digest", F_SHA1, NEEDVALUE}, - {"size", F_SIZE, NEEDVALUE}, - {"tags", F_TAGS, NEEDVALUE}, - {"time", F_TIME, NEEDVALUE}, - {"type", F_TYPE, NEEDVALUE}, - {"uid", F_UID, NEEDVALUE}, - {"uname", F_UNAME, NEEDVALUE} -}; - -static KEY typelist[] = { - {"block", F_BLOCK, }, - {"char", F_CHAR, }, - {"dir", F_DIR, }, - {"fifo", F_FIFO, }, - {"file", F_FILE, }, - {"link", F_LINK, }, - {"socket", F_SOCK, }, -}; - -slist_t excludetags, includetags; -int keys = KEYDEFAULT; - - -int keycompare(const void *, const void *); - -u_int -parsekey(const char *name, int *needvaluep) -{ - static int allbits; - KEY *k, tmp; - - if (allbits == 0) { - int i; - - for (i = 0; i < sizeof(keylist) / sizeof(KEY); i++) - allbits |= keylist[i].val; - } - tmp.name = name; - if (strcmp(name, "all") == 0) - return (allbits); - k = (KEY *)bsearch(&tmp, keylist, sizeof(keylist) / sizeof(KEY), - sizeof(KEY), keycompare); - if (k == NULL) - mtree_err("unknown keyword `%s'", name); - - if (needvaluep) - *needvaluep = k->flags & NEEDVALUE ? 1 : 0; - - return (k->val); -} - -u_int -parsetype(const char *name) -{ - KEY *k, tmp; - - tmp.name = name; - k = (KEY *)bsearch(&tmp, typelist, sizeof(typelist) / sizeof(KEY), - sizeof(KEY), keycompare); - if (k == NULL) - mtree_err("unknown file type `%s'", name); - - return (k->val); -} - -int -keycompare(const void *a, const void *b) -{ - - return (strcmp(((const KEY *)a)->name, ((const KEY *)b)->name)); -} - -void -mtree_err(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vwarnx(fmt, ap); - va_end(ap); - if (mtree_lineno) - warnx("failed at line %lu of the specification", - (u_long) mtree_lineno); - exit(1); - /* NOTREACHED */ -} - -void -addtag(slist_t *list, char *elem) -{ - -#define TAG_CHUNK 20 - - if ((list->count % TAG_CHUNK) == 0) { - char **new; - - new = (char **)realloc(list->list, (list->count + TAG_CHUNK) - * sizeof(char *)); - if (new == NULL) - mtree_err("memory allocation error"); - list->list = new; - } - list->list[list->count] = elem; - list->count++; -} - -void -parsetags(slist_t *list, char *args) -{ - char *p, *e; - int len; - - if (args == NULL) { - addtag(list, NULL); - return; - } - while ((p = strsep(&args, ",")) != NULL) { - if (*p == '\0') - continue; - len = strlen(p) + 3; /* "," + p + ",\0" */ - if ((e = malloc(len)) == NULL) - mtree_err("memory allocation error"); - snprintf(e, len, ",%s,", p); - addtag(list, e); - } -} - -/* - * matchtags - * returns 0 if there's a match from the exclude list in the node's tags, - * or there's an include list and no match. - * return 1 otherwise. - */ -int -matchtags(NODE *node) -{ - int i; - - if (node->tags) { - for (i = 0; i < excludetags.count; i++) - if (strstr(node->tags, excludetags.list[i])) - break; - if (i < excludetags.count) - return (0); - - for (i = 0; i < includetags.count; i++) - if (strstr(node->tags, includetags.list[i])) - break; - if (i > 0 && i == includetags.count) - return (0); - } else if (includetags.count > 0) { - return (0); - } - return (1); -} - -u_int -nodetoino(u_int type) -{ - - switch (type) { - case F_BLOCK: - return S_IFBLK; - case F_CHAR: - return S_IFCHR; - case F_DIR: - return S_IFDIR; - case F_FIFO: - return S_IFIFO; - case F_FILE: - return S_IFREG; - case F_LINK: - return S_IFLNK; -#ifdef S_IFSOCK - case F_SOCK: - return S_IFSOCK; -#endif - default: - printf("unknown type %d", type); - abort(); - } - /* NOTREACHED */ -} - -const char * -nodetype(u_int type) -{ - - return (inotype(nodetoino(type))); -} - - -const char * -inotype(u_int type) -{ - - switch (type & S_IFMT) { - case S_IFBLK: - return ("block"); - case S_IFCHR: - return ("char"); - case S_IFDIR: - return ("dir"); - case S_IFIFO: - return ("fifo"); - case S_IFREG: - return ("file"); - case S_IFLNK: - return ("link"); -#ifdef S_IFSOCK - case S_IFSOCK: - return ("socket"); -#endif - default: - return ("unknown"); - } - /* NOTREACHED */ -} diff --git a/compat/mtree/mtree.h b/compat/mtree/mtree.h deleted file mode 100644 index 59a0cc977fd..00000000000 --- a/compat/mtree/mtree.h +++ /dev/null @@ -1,129 +0,0 @@ -/* $NetBSD: mtree.h,v 1.21 2003/08/07 11:25:36 agc Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)mtree.h 8.1 (Berkeley) 6/6/93 - */ - -#ifndef _MTREE_H_ -#define _MTREE_H_ - -#define KEYDEFAULT (F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | \ - F_TIME | F_TYPE | F_UID | F_FLAGS) - -#define MISMATCHEXIT 2 - -typedef struct _node { - struct _node *parent, *child; /* up, down */ - struct _node *prev, *next; /* left, right */ - off_t st_size; /* size */ - struct timespec st_mtimespec; /* last modification time */ - char *slink; /* symbolic link reference */ - uid_t st_uid; /* uid */ - gid_t st_gid; /* gid */ -#define MBITS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) - mode_t st_mode; /* mode */ - dev_t st_rdev; /* device type */ - u_long st_flags; /* flags */ - nlink_t st_nlink; /* link count */ - u_long cksum; /* check sum */ - char *md5digest; /* MD5 digest */ - char *rmd160digest; /* RMD-160 digest */ - char *sha1digest; /* SHA1 digest */ - char *tags; /* tags, comma delimited */ - size_t lineno; /* line # entry came from */ - -#define F_CKSUM 0x00000001 /* cksum(1) check sum */ -#define F_DEV 0x00000002 /* device type */ -#define F_DONE 0x00000004 /* directory done */ -#define F_FLAGS 0x00000008 /* file flags */ -#define F_GID 0x00000010 /* gid */ -#define F_GNAME 0x00000020 /* group name */ -#define F_IGN 0x00000040 /* ignore */ -#define F_MAGIC 0x00000080 /* name has magic chars */ -#define F_MD5 0x00000100 /* MD5 digest */ -#define F_MODE 0x00000200 /* mode */ -#define F_NLINK 0x00000400 /* number of links */ -#define F_OPT 0x00000800 /* existence optional */ -#define F_RMD160 0x00001000 /* RMD-160 digest */ -#define F_SHA1 0x00002000 /* SHA1 digest */ -#define F_SIZE 0x00004000 /* size */ -#define F_SLINK 0x00008000 /* symbolic link */ -#define F_TAGS 0x00010000 /* tags */ -#define F_TIME 0x00020000 /* modification time */ -#define F_TYPE 0x00040000 /* file type */ -#define F_UID 0x00080000 /* uid */ -#define F_UNAME 0x00100000 /* user name */ -#define F_VISIT 0x00200000 /* file visited */ - - int flags; /* items set */ - -#define F_BLOCK 0x001 /* block special */ -#define F_CHAR 0x002 /* char special */ -#define F_DIR 0x004 /* directory */ -#define F_FIFO 0x008 /* fifo */ -#define F_FILE 0x010 /* regular file */ -#define F_LINK 0x020 /* symbolic link */ -#define F_SOCK 0x040 /* socket */ - int type; /* file type */ - - char name[1]; /* file name (must be last) */ -} NODE; - - -typedef struct { - char **list; - int count; -} slist_t; - - -/* - * prototypes for functions published to other programs which want to use - * the specfile parser but don't want to pull in all of "extern.h" - */ -const char *inotype(u_int); -u_int nodetoino(u_int); -int setup_getid(const char *); -NODE *spec(FILE *); -char *vispath(const char *); - - -#define RP(p) \ - ((p)->fts_path[0] == '.' && (p)->fts_path[1] == '/' ? \ - (p)->fts_path + 2 : (p)->fts_path) - -#define UF_MASK ((UF_NODUMP | UF_IMMUTABLE | \ - UF_APPEND | UF_OPAQUE) \ - & UF_SETTABLE) /* user settable flags */ -#define SF_MASK ((SF_ARCHIVED | SF_IMMUTABLE | \ - SF_APPEND) & SF_SETTABLE) /* root settable flags */ -#define CH_MASK (UF_MASK | SF_MASK) /* all settable flags */ -#define SP_FLGS (SF_IMMUTABLE | SF_APPEND) /* special flags */ - -#endif /* _MTREE_H_ */ diff --git a/compat/mtree/spec.c b/compat/mtree/spec.c deleted file mode 100644 index 768f8f6425d..00000000000 --- a/compat/mtree/spec.c +++ /dev/null @@ -1,594 +0,0 @@ -/* $NetBSD: spec.c,v 1.56 2004/06/20 22:20:18 jmc Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/*- - * Copyright (c) 2001-2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Luke Mewburn of Wasabi Systems. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include -#if defined(__RCSID) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)spec.c 8.2 (Berkeley) 4/28/95"; -#else -__RCSID("$NetBSD: spec.c,v 1.56 2004/06/20 22:20:18 jmc Exp $"); -#endif -#endif /* not lint */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" -#include "pack_dev.h" - -size_t mtree_lineno; /* Current spec line number */ -int Wflag; /* Don't "whack" permissions */ - -static dev_t parsedev(char *); -static void replacenode(NODE *, NODE *); -static void set(char *, NODE *); -static void unset(char *, NODE *); - -NODE * -spec(FILE *fp) -{ - NODE *centry, *last, *pathparent, *cur; - char *p, *e, *next; - NODE ginfo, *root; - char *buf, *tname, *ntname; - size_t tnamelen, plen; - - root = NULL; - centry = last = NULL; - tname = NULL; - tnamelen = 0; - memset(&ginfo, 0, sizeof(ginfo)); - for (mtree_lineno = 0; - (buf = fparseln(fp, NULL, &mtree_lineno, NULL, - FPARSELN_UNESCCOMM | FPARSELN_UNESCCONT | FPARSELN_UNESCESC)); - free(buf)) { - /* Skip leading whitespace. */ - for (p = buf; *p && isspace((unsigned char)*p); ++p) - continue; - - /* If nothing but whitespace, continue. */ - if (!*p) - continue; - -#ifdef DEBUG - fprintf(stderr, "line %lu: {%s}\n", - (u_long)mtree_lineno, p); -#endif - /* Grab file name, "$", "set", or "unset". */ - next = buf; - while ((p = strsep(&next, " \t")) != NULL && *p == '\0') - continue; - if (p == NULL) - mtree_err("missing field"); - - if (p[0] == '/') { - if (strcmp(p + 1, "set") == 0) - set(next, &ginfo); - else if (strcmp(p + 1, "unset") == 0) - unset(next, &ginfo); - else - mtree_err("invalid specification `%s'", p); - continue; - } - - if (strcmp(p, "..") == 0) { - /* Don't go up, if haven't gone down. */ - if (root == NULL) - goto noparent; - if (last->type != F_DIR || last->flags & F_DONE) { - if (last == root) - goto noparent; - last = last->parent; - } - last->flags |= F_DONE; - continue; - -noparent: mtree_err("no parent node"); - } - - plen = strlen(p) + 1; - if (plen > tnamelen) { - if ((ntname = realloc(tname, plen)) == NULL) - mtree_err("realloc: %s", strerror(errno)); - tname = ntname; - tnamelen = plen; - } - if (strunvis(tname, p) == -1) - mtree_err("strunvis failed on `%s'", p); - p = tname; - - pathparent = NULL; - if (strchr(p, '/') != NULL) { - cur = root; - for (; (e = strchr(p, '/')) != NULL; p = e+1) { - if (p == e) - continue; /* handle // */ - *e = '\0'; - if (strcmp(p, ".") != 0) { - while (cur && - strcmp(cur->name, p) != 0) { - cur = cur->next; - } - } - if (cur == NULL || cur->type != F_DIR) { - mtree_err("%s: %s", tname, - strerror(ENOENT)); - } - *e = '/'; - pathparent = cur; - cur = cur->child; - } - if (*p == '\0') - mtree_err("%s: empty leaf element", tname); - } - - if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL) - mtree_err("%s", strerror(errno)); - *centry = ginfo; - centry->lineno = mtree_lineno; - strcpy(centry->name, p); -#define MAGIC "?*[" - if (strpbrk(p, MAGIC)) - centry->flags |= F_MAGIC; - set(next, centry); - - if (root == NULL) { - /* - * empty tree - */ - if (strcmp(centry->name, ".") != 0 || - centry->type != F_DIR) - mtree_err( - "root node must be the directory `.'"); - last = root = centry; - root->parent = root; - } else if (pathparent != NULL) { - /* - * full path entry - */ - centry->parent = pathparent; - cur = pathparent->child; - if (cur == NULL) { - pathparent->child = centry; - last = centry; - } else { - for (; cur != NULL; cur = cur->next) { - if (strcmp(cur->name, centry->name) - == 0) { - /* existing entry; replace */ - replacenode(cur, centry); - break; - } - if (cur->next == NULL) { - /* last entry; add new */ - cur->next = centry; - centry->prev = cur; - break; - } - } - last = cur; - while (last->next != NULL) - last = last->next; - } - } else if (strcmp(centry->name, ".") == 0) { - /* - * duplicate "." entry; always replace - */ - replacenode(root, centry); - } else if (last->type == F_DIR && !(last->flags & F_DONE)) { - /* - * new relative child - * (no duplicate check) - */ - centry->parent = last; - last = last->child = centry; - } else { - /* - * relative entry, up one directory - * (no duplicate check) - */ - centry->parent = last->parent; - centry->prev = last; - last = last->next = centry; - } - } - return (root); -} - -#if 0 -/* - * dump_nodes -- - * dump the NODEs from `cur', based in the directory `dir'. - * if pathlast is none zero, print the path last, otherwise print - * it first. - */ -void -dump_nodes(const char *dir, NODE *root, int pathlast) -{ - NODE *cur; - char path[MAXPATHLEN]; - const char *name; - - for (cur = root; cur != NULL; cur = cur->next) { - if (cur->type != F_DIR && !matchtags(cur)) - continue; - - if (snprintf(path, sizeof(path), "%s%s%s", - dir, *dir ? "/" : "", cur->name) - >= sizeof(path)) - mtree_err("Pathname too long."); - - if (!pathlast) - printf("%s ", vispath(path)); - -#define MATCHFLAG(f) ((keys & (f)) && (cur->flags & (f))) - if (MATCHFLAG(F_TYPE)) - printf("type=%s ", nodetype(cur->type)); - if (MATCHFLAG(F_UID | F_UNAME)) { - if (keys & F_UNAME && - (name = user_from_uid(cur->st_uid, 1)) != NULL) - printf("uname=%s ", name); - else - printf("uid=%u ", cur->st_uid); - } - if (MATCHFLAG(F_GID | F_GNAME)) { - if (keys & F_GNAME && - (name = group_from_gid(cur->st_gid, 1)) != NULL) - printf("gname=%s ", name); - else - printf("gid=%u ", cur->st_gid); - } - if (MATCHFLAG(F_MODE)) - printf("mode=%#o ", cur->st_mode); - if (MATCHFLAG(F_DEV) && - (cur->type == F_BLOCK || cur->type == F_CHAR)) - printf("device=%#x ", cur->st_rdev); - if (MATCHFLAG(F_NLINK)) - printf("nlink=%d ", cur->st_nlink); - if (MATCHFLAG(F_SLINK)) - printf("link=%s ", cur->slink); - if (MATCHFLAG(F_SIZE)) - printf("size=%lld ", (long long)cur->st_size); - if (MATCHFLAG(F_TIME)) - printf("time=%ld.%ld ", (long)cur->st_mtimespec.tv_sec, - cur->st_mtimespec.tv_nsec); - if (MATCHFLAG(F_CKSUM)) - printf("cksum=%lu ", cur->cksum); - if (MATCHFLAG(F_MD5)) - printf("md5=%s ", cur->md5digest); - if (MATCHFLAG(F_RMD160)) - printf("rmd160=%s ", cur->rmd160digest); - if (MATCHFLAG(F_SHA1)) - printf("sha1=%s ", cur->sha1digest); - if (MATCHFLAG(F_FLAGS)) - printf("flags=%s ", - flags_to_string(cur->st_flags, "none")); - if (MATCHFLAG(F_IGN)) - printf("ignore "); - if (MATCHFLAG(F_OPT)) - printf("optional "); - if (MATCHFLAG(F_TAGS)) - printf("tags=%s ", cur->tags); - puts(pathlast ? vispath(path) : ""); - - if (cur->child) - dump_nodes(path, cur->child, pathlast); - } -} - -/* - * vispath -- - * strsvis(3) encodes path, which must not be longer than MAXPATHLEN - * characters long, and returns a pointer to a static buffer containing - * the result. - */ -char * -vispath(const char *path) -{ - const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' }; - static char pathbuf[4*MAXPATHLEN + 1]; - - strsvis(pathbuf, path, VIS_CSTYLE, extra); - return(pathbuf); -} -#endif - -static dev_t -parsedev(char *arg) -{ -#define MAX_PACK_ARGS 3 - u_long numbers[MAX_PACK_ARGS]; - char *p, *ep, *dev; - int argc; - pack_t *pack; - dev_t result; - const char *error = NULL; - - if ((dev = strchr(arg, ',')) != NULL) { - *dev++='\0'; - if ((pack = pack_find(arg)) == NULL) - mtree_err("unknown format `%s'", arg); - argc = 0; - while ((p = strsep(&dev, ",")) != NULL) { - if (*p == '\0') - mtree_err("missing number"); - numbers[argc++] = strtoul(p, &ep, 0); - if (*ep != '\0') - mtree_err("invalid number `%s'", - p); - if (argc > MAX_PACK_ARGS) - mtree_err("too many arguments"); - } - if (argc < 2) - mtree_err("not enough arguments"); - result = (*pack)(argc, numbers, &error); - if (error != NULL) - mtree_err(error); - } else { - result = (dev_t)strtoul(arg, &ep, 0); - if (*ep != '\0') - mtree_err("invalid device `%s'", arg); - } - return (result); -} - -static void -replacenode(NODE *cur, NODE *new) -{ - - if (cur->type != new->type) - mtree_err("existing entry for `%s', type `%s' does not match type `%s'", - cur->name, nodetype(cur->type), nodetype(new->type)); -#define REPLACE(x) cur->x = new->x -#define REPLACESTR(x) if (cur->x) free(cur->x); cur->x = new->x - - REPLACE(st_size); - REPLACE(st_mtimespec); - REPLACESTR(slink); - REPLACE(st_uid); - REPLACE(st_gid); - REPLACE(st_mode); - REPLACE(st_rdev); - REPLACE(st_flags); - REPLACE(st_nlink); - REPLACE(cksum); - REPLACESTR(md5digest); - REPLACESTR(rmd160digest); - REPLACESTR(sha1digest); - REPLACESTR(tags); - REPLACE(lineno); - REPLACE(flags); - free(new); -} - -static void -set(char *t, NODE *ip) -{ - int type, value, len; - gid_t gid; - uid_t uid; - char *kw, *val, *md, *ep; - void *m; - - val = NULL; - while ((kw = strsep(&t, "= \t")) != NULL) { - if (*kw == '\0') - continue; - if (strcmp(kw, "all") == 0) - mtree_err("invalid keyword `all'"); - ip->flags |= type = parsekey(kw, &value); - if (value) { - while ((val = strsep(&t, " \t")) != NULL && - *val == '\0') - continue; - if (val == NULL) - mtree_err("missing value"); - } - switch(type) { - case F_CKSUM: - ip->cksum = strtoul(val, &ep, 10); - if (*ep) - mtree_err("invalid checksum `%s'", val); - break; - case F_DEV: - ip->st_rdev = parsedev(val); - break; - case F_FLAGS: - if (strcmp("none", val) == 0) - ip->st_flags = 0; - else if (string_to_flags(&val, &ip->st_flags, NULL) - != 0) - mtree_err("invalid flag `%s'", val); - break; - case F_GID: - ip->st_gid = (gid_t)strtoul(val, &ep, 10); - if (*ep) - mtree_err("invalid gid `%s'", val); - break; - case F_GNAME: - if (Wflag) /* don't parse if whacking */ - break; - if (gid_from_group(val, &gid) == -1) - mtree_err("unknown group `%s'", val); - ip->st_gid = gid; - break; - case F_IGN: - /* just set flag bit */ - break; - case F_MD5: - if (val[0]=='0' && val[1]=='x') - md=&val[2]; - else - md=val; - if ((ip->md5digest = strdup(md)) == NULL) - mtree_err("memory allocation error"); - break; - case F_MODE: - if ((m = setmode(val)) == NULL) - mtree_err("invalid file mode `%s'", val); - ip->st_mode = getmode(m, 0); - free(m); - break; - case F_NLINK: - ip->st_nlink = (nlink_t)strtoul(val, &ep, 10); - if (*ep) - mtree_err("invalid link count `%s'", val); - break; - case F_OPT: - /* just set flag bit */ - break; - case F_RMD160: - if (val[0]=='0' && val[1]=='x') - md=&val[2]; - else - md=val; - if ((ip->rmd160digest = strdup(md)) == NULL) - mtree_err("memory allocation error"); - break; - case F_SHA1: - if (val[0]=='0' && val[1]=='x') - md=&val[2]; - else - md=val; - if ((ip->sha1digest = strdup(md)) == NULL) - mtree_err("memory allocation error"); - break; - case F_SIZE: - ip->st_size = (off_t)strtoll(val, &ep, 10); - if (*ep) - mtree_err("invalid size `%s'", val); - break; - case F_SLINK: - if ((ip->slink = strdup(val)) == NULL) - mtree_err("memory allocation error"); - break; - case F_TAGS: - len = strlen(val) + 3; /* "," + str + ",\0" */ - if ((ip->tags = malloc(len)) == NULL) - mtree_err("memory allocation error"); - snprintf(ip->tags, len, ",%s,", val); - break; - case F_TIME: - ip->st_mtimespec.tv_sec = - (time_t)strtoul(val, &ep, 10); - if (*ep != '.') - mtree_err("invalid time `%s'", val); - val = ep + 1; - ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10); - if (*ep) - mtree_err("invalid time `%s'", val); - break; - case F_TYPE: - ip->type = parsetype(val); - break; - case F_UID: - ip->st_uid = (uid_t)strtoul(val, &ep, 10); - if (*ep) - mtree_err("invalid uid `%s'", val); - break; - case F_UNAME: - if (Wflag) /* don't parse if whacking */ - break; - if (uid_from_user(val, &uid) == -1) - mtree_err("unknown user `%s'", val); - ip->st_uid = uid; - break; - default: - mtree_err( - "set(): unsupported key type 0x%x (INTERNAL ERROR)", - type); - /* NOTREACHED */ - } - } -} - -static void -unset(char *t, NODE *ip) -{ - char *p; - - while ((p = strsep(&t, " \t")) != NULL) { - if (*p == '\0') - continue; - ip->flags &= ~parsekey(p, NULL); - } -}