summaryrefslogtreecommitdiff
path: root/pkgtools/mtree
diff options
context:
space:
mode:
authorjlam <jlam@pkgsrc.org>2003-09-05 18:38:58 +0000
committerjlam <jlam@pkgsrc.org>2003-09-05 18:38:58 +0000
commit3d58e022001a4caa9e0c4ee48bc2d1a090261b02 (patch)
tree6fd08ee80972fe4f4cd0929061717ca4a55f5519 /pkgtools/mtree
parent60207a145d7d617ef345988c591b4fc181e26af5 (diff)
downloadpkgsrc-3d58e022001a4caa9e0c4ee48bc2d1a090261b02.tar.gz
Make this build using libnbcompat-20030829. Several files from the older
libnbcompat where moved into mtree/files since they logically belong together (and are that way in the NetBSD src tree).
Diffstat (limited to 'pkgtools/mtree')
-rw-r--r--pkgtools/mtree/files/Makefile.in5
-rw-r--r--pkgtools/mtree/files/config.h.in12
-rwxr-xr-xpkgtools/mtree/files/configure73
-rw-r--r--pkgtools/mtree/files/configure.ac5
-rw-r--r--pkgtools/mtree/files/extern.h88
-rw-r--r--pkgtools/mtree/files/getid.c453
-rw-r--r--pkgtools/mtree/files/misc.c305
-rw-r--r--pkgtools/mtree/files/mtree.h129
-rw-r--r--pkgtools/mtree/files/pack_dev.c317
-rw-r--r--pkgtools/mtree/files/pack_dev.h59
-rw-r--r--pkgtools/mtree/files/spec.c612
-rw-r--r--pkgtools/mtree/files/stat_flags.c197
-rw-r--r--pkgtools/mtree/files/stat_flags.h35
13 files changed, 2285 insertions, 5 deletions
diff --git a/pkgtools/mtree/files/Makefile.in b/pkgtools/mtree/files/Makefile.in
index 51e991149bd..5398eea2ab0 100644
--- a/pkgtools/mtree/files/Makefile.in
+++ b/pkgtools/mtree/files/Makefile.in
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.in,v 1.5 2003/09/05 04:38:45 grant Exp $
+# $NetBSD: Makefile.in,v 1.6 2003/09/05 18:38:58 jlam Exp $
srcdir= @srcdir@
@@ -22,7 +22,8 @@ INSTALL= @INSTALL@
PROG= mtree
-SRCS= compare.c crc.c create.c excludes.c mtree.c verify.c
+SRCS= compare.c crc.c create.c excludes.c misc.c mtree.c spec.c verify.c \
+ getid.c stat_flags.c pack_dev.c
OBJS= $(SRCS:.c=.o)
.PHONY: all clean install
diff --git a/pkgtools/mtree/files/config.h.in b/pkgtools/mtree/files/config.h.in
index 62fc465f012..b711e3f4f37 100644
--- a/pkgtools/mtree/files/config.h.in
+++ b/pkgtools/mtree/files/config.h.in
@@ -37,9 +37,15 @@
/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the `util' library (-lutil). */
+#undef HAVE_LIBUTIL
+
/* Define to 1 if you have the `mbsrtowcs' function. */
#undef HAVE_MBSRTOWCS
@@ -55,6 +61,9 @@
/* Define to 1 if you have the `mkdir' function. */
#undef HAVE_MKDIR
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -97,6 +106,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the <util.h> header file. */
+#undef HAVE_UTIL_H
+
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
diff --git a/pkgtools/mtree/files/configure b/pkgtools/mtree/files/configure
index affdabdf196..8b7d09e4a25 100755
--- a/pkgtools/mtree/files/configure
+++ b/pkgtools/mtree/files/configure
@@ -2242,8 +2242,74 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-# Checks for header files.
+# Checks for libraries.
+
+
+echo "$as_me:$LINENO: checking for fparseln in -lutil" >&5
+echo $ECHO_N "checking for fparseln in -lutil... $ECHO_C" >&6
+if test "${ac_cv_lib_util_fparseln+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char fparseln ();
+int
+main ()
+{
+fparseln ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_util_fparseln=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_util_fparseln=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_util_fparseln" >&5
+echo "${ECHO_T}$ac_cv_lib_util_fparseln" >&6
+if test $ac_cv_lib_util_fparseln = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUTIL 1
+_ACEOF
+
+ LIBS="-lutil $LIBS"
+
+fi
+
+
+# Checks for header files.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2718,7 +2784,10 @@ done
-for ac_header in fnmatch.h
+
+
+
+for ac_header in fnmatch.h grp.h pwd.h util.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
diff --git a/pkgtools/mtree/files/configure.ac b/pkgtools/mtree/files/configure.ac
index 9601a581aca..6318cec3ffb 100644
--- a/pkgtools/mtree/files/configure.ac
+++ b/pkgtools/mtree/files/configure.ac
@@ -10,9 +10,12 @@ AC_CONFIG_HEADER([config.h])
AC_PROG_CC
AC_PROG_INSTALL
+# Checks for libraries.
+AC_CHECK_LIB(util, fparseln)
+
# Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS([fnmatch.h])
+AC_CHECK_HEADERS([fnmatch.h grp.h pwd.h util.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
diff --git a/pkgtools/mtree/files/extern.h b/pkgtools/mtree/files/extern.h
new file mode 100644
index 00000000000..9bba26ca45d
--- /dev/null
+++ b/pkgtools/mtree/files/extern.h
@@ -0,0 +1,88 @@
+/* $NetBSD: extern.h,v 1.1 2003/09/05 18:38:58 jlam 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_CONFIG_H
+#include "config.h"
+#else
+#define HAVE_STRUCT_STAT_ST_FLAGS 1
+#endif
+
+#include <nbcompat.h>
+#if HAVE_ERR_H
+#include <err.h>
+#endif
+#if HAVE_FTS_H
+#include <fts.h>
+#endif
+
+#if HAVE_NETDB_H
+/* For MAXHOSTNAMELEN on some platforms. */
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#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/pkgtools/mtree/files/getid.c b/pkgtools/mtree/files/getid.c
new file mode 100644
index 00000000000..e2303ec1bd5
--- /dev/null
+++ b/pkgtools/mtree/files/getid.c
@@ -0,0 +1,453 @@
+/* $NetBSD: getid.c,v 1.1 2003/09/05 18:38:58 jlam Exp $ */
+/* from: NetBSD: getpwent.c,v 1.48 2000/10/03 03:22:26 enami Exp */
+/* from: NetBSD: getgrent.c,v 1.41 2002/01/12 23:51:30 lukem Exp */
+
+/*
+ * Copyright (c) 1987, 1988, 1989, 1993, 1994, 1995
+ * 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) 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_CONFIG_H
+#include "config.h"
+#endif
+#include <nbcompat.h>
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#if HAVE_GRP_H
+#include <grp.h>
+#endif
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_TIME_H
+#include <time.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "extern.h"
+
+static struct group * gi_getgrnam(const char *);
+static struct group * gi_getgrgid(gid_t);
+static int gi_setgroupent(int);
+static void gi_endgrent(void);
+static int grstart(void);
+static int grscan(int, gid_t, const char *);
+static int grmatchline(int, gid_t, const char *);
+
+static struct passwd * gi_getpwnam(const char *);
+static struct passwd * gi_getpwuid(uid_t);
+static int gi_setpassent(int);
+static void gi_endpwent(void);
+static int pwstart(void);
+static int pwscan(int, uid_t, const char *);
+static int pwmatchline(int, uid_t, const char *);
+
+#define MAXGRP 200
+#define MAXLINELENGTH 1024
+
+static FILE *_gr_fp;
+static struct group _gr_group;
+static int _gr_stayopen;
+static int _gr_filesdone;
+static FILE *_pw_fp;
+static struct passwd _pw_passwd; /* password structure */
+static int _pw_stayopen; /* keep fd's open */
+static int _pw_filesdone;
+
+static char grfile[MAXPATHLEN];
+static char pwfile[MAXPATHLEN];
+
+static char *members[MAXGRP];
+static char grline[MAXLINELENGTH];
+static char pwline[MAXLINELENGTH];
+
+int
+setup_getid(const char *dir)
+{
+ if (dir == NULL)
+ return (0);
+
+ /* close existing databases */
+ gi_endgrent();
+ gi_endpwent();
+
+ /* build paths to new databases */
+ snprintf(grfile, sizeof(grfile), "%s/group", dir);
+ snprintf(pwfile, sizeof(pwfile), "%s/master.passwd", dir);
+
+ /* try to open new databases */
+ if (!grstart() || !pwstart())
+ return (0);
+
+ /* switch pwcache(3) lookup functions */
+ if (pwcache_groupdb(gi_setgroupent, gi_endgrent,
+ gi_getgrnam, gi_getgrgid) == -1
+ || pwcache_userdb(gi_setpassent, gi_endpwent,
+ gi_getpwnam, gi_getpwuid) == -1)
+ return (0);
+
+ return (1);
+}
+
+
+/*
+ * group lookup functions
+ */
+
+static struct group *
+gi_getgrnam(const char *name)
+{
+ int rval;
+
+ if (!grstart())
+ return NULL;
+ rval = grscan(1, 0, name);
+ if (!_gr_stayopen)
+ endgrent();
+ return (rval) ? &_gr_group : NULL;
+}
+
+static struct group *
+gi_getgrgid(gid_t gid)
+{
+ int rval;
+
+ if (!grstart())
+ return NULL;
+ rval = grscan(1, gid, NULL);
+ if (!_gr_stayopen)
+ endgrent();
+ return (rval) ? &_gr_group : NULL;
+}
+
+static int
+gi_setgroupent(int stayopen)
+{
+
+ if (!grstart())
+ return 0;
+ _gr_stayopen = stayopen;
+ return 1;
+}
+
+static void
+gi_endgrent(void)
+{
+
+ _gr_filesdone = 0;
+ if (_gr_fp) {
+ (void)fclose(_gr_fp);
+ _gr_fp = NULL;
+ }
+}
+
+static int
+grstart(void)
+{
+
+ _gr_filesdone = 0;
+ if (_gr_fp) {
+ rewind(_gr_fp);
+ return 1;
+ }
+ if (grfile[0] == '\0') /* sanity check */
+ return 0;
+ return (_gr_fp = fopen(grfile, "r")) ? 1 : 0;
+}
+
+
+static int
+grscan(int search, gid_t gid, const char *name)
+{
+
+ if (_gr_filesdone)
+ return 0;
+ for (;;) {
+ if (!fgets(grline, sizeof(grline), _gr_fp)) {
+ if (!search)
+ _gr_filesdone = 1;
+ return 0;
+ }
+ /* skip lines that are too big */
+ if (!strchr(grline, '\n')) {
+ int ch;
+
+ while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
+ ;
+ continue;
+ }
+ if (grmatchline(search, gid, name))
+ return 1;
+ }
+ /* NOTREACHED */
+}
+
+static int
+grmatchline(int search, gid_t gid, const char *name)
+{
+ unsigned long id;
+ char **m;
+ char *cp, *bp, *ep;
+
+ /* name may be NULL if search is nonzero */
+
+ bp = grline;
+ memset(&_gr_group, 0, sizeof(_gr_group));
+ _gr_group.gr_name = strsep(&bp, ":\n");
+ if (search && name && strcmp(_gr_group.gr_name, name))
+ return 0;
+ _gr_group.gr_passwd = strsep(&bp, ":\n");
+ if (!(cp = strsep(&bp, ":\n")))
+ return 0;
+ id = strtoul(cp, &ep, 10);
+ if (id > GID_MAX || *ep != '\0')
+ return 0;
+ _gr_group.gr_gid = (gid_t)id;
+ if (search && name == NULL && _gr_group.gr_gid != gid)
+ return 0;
+ cp = NULL;
+ if (bp == NULL)
+ return 0;
+ for (_gr_group.gr_mem = m = members;; bp++) {
+ if (m == &members[MAXGRP - 1])
+ break;
+ if (*bp == ',') {
+ if (cp) {
+ *bp = '\0';
+ *m++ = cp;
+ cp = NULL;
+ }
+ } else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
+ if (cp) {
+ *bp = '\0';
+ *m++ = cp;
+ }
+ break;
+ } else if (cp == NULL)
+ cp = bp;
+ }
+ *m = NULL;
+ return 1;
+}
+
+
+/*
+ * user lookup functions
+ */
+
+static struct passwd *
+gi_getpwnam(const char *name)
+{
+ int rval;
+
+ if (!pwstart())
+ return NULL;
+ rval = pwscan(1, 0, name);
+ if (!_pw_stayopen)
+ endpwent();
+ return (rval) ? &_pw_passwd : NULL;
+}
+
+static struct passwd *
+gi_getpwuid(uid_t uid)
+{
+ int rval;
+
+ if (!pwstart())
+ return NULL;
+ rval = pwscan(1, uid, NULL);
+ if (!_pw_stayopen)
+ endpwent();
+ return (rval) ? &_pw_passwd : NULL;
+}
+
+static int
+gi_setpassent(int stayopen)
+{
+
+ if (!pwstart())
+ return 0;
+ _pw_stayopen = stayopen;
+ return 1;
+}
+
+static void
+gi_endpwent(void)
+{
+
+ _pw_filesdone = 0;
+ if (_pw_fp) {
+ (void)fclose(_pw_fp);
+ _pw_fp = NULL;
+ }
+}
+
+static int
+pwstart(void)
+{
+
+ _pw_filesdone = 0;
+ if (_pw_fp) {
+ rewind(_pw_fp);
+ return 1;
+ }
+ if (pwfile[0] == '\0') /* sanity check */
+ return 0;
+ return (_pw_fp = fopen(pwfile, "r")) ? 1 : 0;
+}
+
+
+static int
+pwscan(int search, uid_t uid, const char *name)
+{
+
+ if (_pw_filesdone)
+ return 0;
+ for (;;) {
+ if (!fgets(pwline, sizeof(pwline), _pw_fp)) {
+ if (!search)
+ _pw_filesdone = 1;
+ return 0;
+ }
+ /* skip lines that are too big */
+ if (!strchr(pwline, '\n')) {
+ int ch;
+
+ while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
+ ;
+ continue;
+ }
+ if (pwmatchline(search, uid, name))
+ return 1;
+ }
+ /* NOTREACHED */
+}
+
+static int
+pwmatchline(int search, uid_t uid, const char *name)
+{
+ unsigned long id;
+ char *cp, *bp, *ep;
+
+ /* name may be NULL if search is nonzero */
+
+ bp = pwline;
+ memset(&_pw_passwd, 0, sizeof(_pw_passwd));
+ _pw_passwd.pw_name = strsep(&bp, ":\n"); /* name */
+ if (search && name && strcmp(_pw_passwd.pw_name, name))
+ return 0;
+
+ _pw_passwd.pw_passwd = strsep(&bp, ":\n"); /* passwd */
+
+ if (!(cp = strsep(&bp, ":\n"))) /* uid */
+ return 0;
+ id = strtoul(cp, &ep, 10);
+ if (id > UID_MAX || *ep != '\0')
+ return 0;
+ _pw_passwd.pw_uid = (uid_t)id;
+ if (search && name == NULL && _pw_passwd.pw_uid != uid)
+ return 0;
+
+ if (!(cp = strsep(&bp, ":\n"))) /* gid */
+ return 0;
+ id = strtoul(cp, &ep, 10);
+ if (id > GID_MAX || *ep != '\0')
+ return 0;
+ _pw_passwd.pw_gid = (gid_t)id;
+
+ if (!(ep = strsep(&bp, ":"))) /* class */
+ return 0;
+ if (!(ep = strsep(&bp, ":"))) /* change */
+ return 0;
+ if (!(ep = strsep(&bp, ":"))) /* expire */
+ return 0;
+
+ if (!(_pw_passwd.pw_gecos = strsep(&bp, ":\n"))) /* gecos */
+ return 0;
+ if (!(_pw_passwd.pw_dir = strsep(&bp, ":\n"))) /* directory */
+ return 0;
+ if (!(_pw_passwd.pw_shell = strsep(&bp, ":\n"))) /* shell */
+ return 0;
+
+ if (strchr(bp, ':') != NULL)
+ return 0;
+
+ return 1;
+}
+
diff --git a/pkgtools/mtree/files/misc.c b/pkgtools/mtree/files/misc.c
new file mode 100644
index 00000000000..c72bd0bfc24
--- /dev/null
+++ b/pkgtools/mtree/files/misc.c
@@ -0,0 +1,305 @@
+/* $NetBSD: misc.c,v 1.1 2003/09/05 18:38:59 jlam 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_CONFIG_H
+#include "config.h"
+#endif
+#include <nbcompat.h>
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if defined(__RCSID) && !defined(lint)
+__RCSID("$NetBSD: misc.c,v 1.1 2003/09/05 18:38:59 jlam Exp $");
+#endif /* not lint */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#if HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#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;
+ case F_SOCK:
+ return S_IFSOCK;
+ 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");
+ case S_IFSOCK:
+ return ("socket");
+ default:
+ return ("unknown");
+ }
+ /* NOTREACHED */
+}
diff --git a/pkgtools/mtree/files/mtree.h b/pkgtools/mtree/files/mtree.h
new file mode 100644
index 00000000000..709600def70
--- /dev/null
+++ b/pkgtools/mtree/files/mtree.h
@@ -0,0 +1,129 @@
+/* $NetBSD: mtree.h,v 1.1 2003/09/05 18:38:59 jlam 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/pkgtools/mtree/files/pack_dev.c b/pkgtools/mtree/files/pack_dev.c
new file mode 100644
index 00000000000..781332351a6
--- /dev/null
+++ b/pkgtools/mtree/files/pack_dev.c
@@ -0,0 +1,317 @@
+/* $NetBSD: pack_dev.c,v 1.1 2003/09/05 18:38:59 jlam Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * 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_CONFIG_H
+#include "config.h"
+#endif
+#include <nbcompat.h>
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if defined(__RCSID) && !defined(lint)
+__RCSID("$NetBSD: pack_dev.c,v 1.1 2003/09/05 18:38:59 jlam Exp $");
+#endif /* not lint */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#if HAVE_ERR_H
+#include <err.h>
+#endif
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pack_dev.h"
+
+static pack_t pack_netbsd;
+static pack_t pack_freebsd;
+static pack_t pack_8_8;
+static pack_t pack_12_20;
+static pack_t pack_14_18;
+static pack_t pack_8_24;
+static pack_t pack_bsdos;
+static int compare_format(const void *, const void *);
+
+
+ /* exported */
+portdev_t
+pack_native(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev(numbers[0], numbers[1]);
+ if (major(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+static portdev_t
+pack_netbsd(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_netbsd(numbers[0], numbers[1]);
+ if (major_netbsd(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_netbsd(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
+#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0))
+#define makedev_freebsd(x,y) ((portdev_t)((((x) << 8) & 0x0000ff00) | \
+ (((y) << 0) & 0xffff00ff)))
+
+static portdev_t
+pack_freebsd(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_freebsd(numbers[0], numbers[1]);
+ if (major_freebsd(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_freebsd(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
+#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
+#define makedev_8_8(x,y) ((portdev_t)((((x) << 8) & 0x0000ff00) | \
+ (((y) << 0) & 0x000000ff)))
+
+static portdev_t
+pack_8_8(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_8_8(numbers[0], numbers[1]);
+ if (major_8_8(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_8_8(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20))
+#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0))
+#define makedev_12_20(x,y) ((portdev_t)((((x) << 20) & 0xfff00000) | \
+ (((y) << 0) & 0x000fffff)))
+
+static portdev_t
+pack_12_20(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_12_20(numbers[0], numbers[1]);
+ if (major_12_20(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_12_20(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18))
+#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0))
+#define makedev_14_18(x,y) ((portdev_t)((((x) << 18) & 0xfffc0000) | \
+ (((y) << 0) & 0x0003ffff)))
+
+static portdev_t
+pack_14_18(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_14_18(numbers[0], numbers[1]);
+ if (major_14_18(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_14_18(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24))
+#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0))
+#define makedev_8_24(x,y) ((portdev_t)((((x) << 24) & 0xff000000) | \
+ (((y) << 0) & 0x00ffffff)))
+
+static portdev_t
+pack_8_24(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_8_24(numbers[0], numbers[1]);
+ if (major_8_24(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_8_24(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20))
+#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8))
+#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
+#define makedev_12_12_8(x,y,z) ((portdev_t)((((x) << 20) & 0xfff00000) | \
+ (((y) << 8) & 0x000fff00) | \
+ (((z) << 0) & 0x000000ff)))
+
+static portdev_t
+pack_bsdos(int n, u_long numbers[])
+{
+ portdev_t dev;
+
+ if (n == 2) {
+ dev = makedev_12_20(numbers[0], numbers[1]);
+ if (major_12_20(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (minor_12_20(dev) != numbers[1])
+ errx(1, "invalid minor number");
+ } else if (n == 3) {
+ dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
+ if (major_12_12_8(dev) != numbers[0])
+ errx(1, "invalid major number");
+ if (unit_12_12_8(dev) != numbers[1])
+ errx(1, "invalid unit number");
+ if (subunit_12_12_8(dev) != numbers[2])
+ errx(1, "invalid subunit number");
+ } else
+ errx(1, "too many fields for format");
+ return (dev);
+}
+
+
+ /* list of formats and pack functions */
+ /* this list must be sorted lexically */
+struct format {
+ const char *name;
+ pack_t *pack;
+} formats[] = {
+ {"386bsd", pack_8_8},
+ {"4bsd", pack_8_8},
+ {"bsdos", pack_bsdos},
+ {"freebsd", pack_freebsd},
+ {"hpux", pack_8_24},
+ {"isc", pack_8_8},
+ {"linux", pack_8_8},
+ {"native", pack_native},
+ {"netbsd", pack_netbsd},
+ {"osf1", pack_12_20},
+ {"sco", pack_8_8},
+ {"solaris", pack_14_18},
+ {"sunos", pack_8_8},
+ {"svr3", pack_8_8},
+ {"svr4", pack_14_18},
+ {"ultrix", pack_8_8},
+};
+
+static int
+compare_format(const void *key, const void *element)
+{
+ const char *name;
+ const struct format *format;
+
+ name = key;
+ format = element;
+
+ return (strcmp(name, format->name));
+}
+
+
+pack_t *
+pack_find(const char *name)
+{
+ struct format *format;
+
+ format = bsearch(name, formats,
+ sizeof(formats)/sizeof(formats[0]),
+ sizeof(formats[0]), compare_format);
+ if (format == 0)
+ return (NULL);
+ return (format->pack);
+}
diff --git a/pkgtools/mtree/files/pack_dev.h b/pkgtools/mtree/files/pack_dev.h
new file mode 100644
index 00000000000..a1a5302f96f
--- /dev/null
+++ b/pkgtools/mtree/files/pack_dev.h
@@ -0,0 +1,59 @@
+/* $NetBSD: pack_dev.h,v 1.1 2003/09/05 18:39:00 jlam Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * 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.
+ */
+
+#ifndef _PACK_DEV_H
+#define _PACK_DEV_H
+
+#ifdef __CYGWIN__
+typedef __dev32_t portdev_t;
+#else
+typedef dev_t portdev_t;
+#endif
+typedef portdev_t pack_t(int, u_long []);
+
+pack_t *pack_find(const char *);
+pack_t pack_native;
+
+#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8)))
+#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \
+ (((x) & 0x000000ff) >> 0)))
+#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \
+ (((y) << 12) & 0xfff00000) | \
+ (((y) << 0) & 0x000000ff)))
+
+#endif /* _PACK_DEV_H */
diff --git a/pkgtools/mtree/files/spec.c b/pkgtools/mtree/files/spec.c
new file mode 100644
index 00000000000..52481bab6f1
--- /dev/null
+++ b/pkgtools/mtree/files/spec.c
@@ -0,0 +1,612 @@
+/* $NetBSD: spec.c,v 1.1 2003/09/05 18:39:00 jlam 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_CONFIG_H
+#include "config.h"
+#endif
+#include <nbcompat.h>
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#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.1 2003/09/05 18:39:00 jlam Exp $");
+#endif
+#endif /* not lint */
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_GRP_H
+#include <grp.h>
+#endif
+#if HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_VIS_H
+#include <vis.h>
+#endif
+
+#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;
+ 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) {
+ tnamelen = plen;
+ if ((tname = realloc(tname, tnamelen)) == NULL)
+ mtree_err("realloc: %s", strerror(errno));
+ }
+ 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);
+}
+
+/*
+ * 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);
+}
+
+
+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;
+
+ 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);
+ } 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 type `%s' does not match type `%s'",
+ 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);
+ }
+}
diff --git a/pkgtools/mtree/files/stat_flags.c b/pkgtools/mtree/files/stat_flags.c
new file mode 100644
index 00000000000..4312da6c9b9
--- /dev/null
+++ b/pkgtools/mtree/files/stat_flags.c
@@ -0,0 +1,197 @@
+/* $NetBSD: stat_flags.c,v 1.1 2003/09/05 18:39:00 jlam Exp $ */
+
+/*-
+ * Copyright (c) 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.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <nbcompat.h>
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if defined(__RCSID) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)stat_flags.c 8.2 (Berkeley) 7/28/94";
+#else
+__RCSID("$NetBSD: stat_flags.c,v 1.1 2003/09/05 18:39:00 jlam Exp $");
+#endif
+#endif /* not lint */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#else
+#define HAVE_STRUCT_STAT_ST_FLAGS 1
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_FTS_H
+#include <fts.h>
+#endif
+#if HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "stat_flags.h"
+
+#define SAPPEND(s) do { \
+ if (prefix != NULL) \
+ (void)strlcat(string, prefix, sizeof(string)); \
+ (void)strlcat(string, s, sizeof(string)); \
+ prefix = ","; \
+} while (/* CONSTCOND */ 0)
+
+/*
+ * flags_to_string --
+ * Convert stat flags to a comma-separated string. If no flags
+ * are set, return the default string.
+ */
+char *
+flags_to_string(u_long flags, const char *def)
+{
+ static char string[128];
+ const char *prefix;
+
+ string[0] = '\0';
+ prefix = NULL;
+#if HAVE_STRUCT_STAT_ST_FLAGS
+ if (flags & UF_APPEND)
+ SAPPEND("uappnd");
+ if (flags & UF_IMMUTABLE)
+ SAPPEND("uchg");
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & UF_OPAQUE)
+ SAPPEND("opaque");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+#endif
+ if (prefix == NULL)
+ strlcpy(string, def, sizeof(string));
+ return (string);
+}
+
+#define TEST(a, b, f) { \
+ if (!strcmp(a, b)) { \
+ if (clear) { \
+ if (clrp) \
+ *clrp |= (f); \
+ if (setp) \
+ *setp &= ~(f); \
+ } else { \
+ if (setp) \
+ *setp |= (f); \
+ if (clrp) \
+ *clrp &= ~(f); \
+ } \
+ break; \
+ } \
+}
+
+/*
+ * string_to_flags --
+ * Take string of arguments and return stat flags. Return 0 on
+ * success, 1 on failure. On failure, stringp is set to point
+ * to the offending token.
+ */
+int
+string_to_flags(char **stringp, u_long *setp, u_long *clrp)
+{
+ int clear;
+ char *string, *p;
+
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+
+#if HAVE_STRUCT_STAT_ST_FLAGS
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ clear = 0;
+ *stringp = p;
+ if (*p == '\0')
+ continue;
+ if (p[0] == 'n' && p[1] == 'o') {
+ clear = 1;
+ p += 2;
+ }
+ switch (p[0]) {
+ case 'a':
+ TEST(p, "arch", SF_ARCHIVED);
+ TEST(p, "archived", SF_ARCHIVED);
+ return (1);
+ case 'd':
+ clear = !clear;
+ TEST(p, "dump", UF_NODUMP);
+ return (1);
+ case 'n':
+ /*
+ * Support `nonodump'. Note that
+ * the state of clear is not changed.
+ */
+ TEST(p, "nodump", UF_NODUMP);
+ return (1);
+ case 'o':
+ TEST(p, "opaque", UF_OPAQUE);
+ return (1);
+ case 's':
+ TEST(p, "sappnd", SF_APPEND);
+ TEST(p, "sappend", SF_APPEND);
+ TEST(p, "schg", SF_IMMUTABLE);
+ TEST(p, "schange", SF_IMMUTABLE);
+ TEST(p, "simmutable", SF_IMMUTABLE);
+ return (1);
+ case 'u':
+ TEST(p, "uappnd", UF_APPEND);
+ TEST(p, "uappend", UF_APPEND);
+ TEST(p, "uchg", UF_IMMUTABLE);
+ TEST(p, "uchange", UF_IMMUTABLE);
+ TEST(p, "uimmutable", UF_IMMUTABLE);
+ return (1);
+ default:
+ return (1);
+ }
+ }
+#endif
+
+ return (0);
+}
diff --git a/pkgtools/mtree/files/stat_flags.h b/pkgtools/mtree/files/stat_flags.h
new file mode 100644
index 00000000000..bf8b30fb536
--- /dev/null
+++ b/pkgtools/mtree/files/stat_flags.h
@@ -0,0 +1,35 @@
+/* $NetBSD: stat_flags.h,v 1.1 2003/09/05 18:39:00 jlam 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) 5/31/93
+ */
+
+char *flags_to_string(u_long, const char *);
+int string_to_flags(char **, u_long *, u_long *);