Module Name:    src
Committed By:   bouyer
Date:           Sat Jun  6 22:10:13 UTC 2009

Modified Files:
        src/distrib/common [netbsd-5]: parselist.awk
        src/distrib/sets [netbsd-5]: maketars
        src/share/dict [netbsd-5]: Makefile
        src/share/mk [netbsd-5]: bsd.README bsd.hostprog.mk bsd.kmodule.mk
            bsd.lib.mk bsd.links.mk bsd.man.mk bsd.prog.mk
        src/share/zoneinfo [netbsd-5]: Makefile
        src/usr.bin/xinstall [netbsd-5]: xinstall.c

Log Message:
Pull up following revision(s) (requested by snj in ticket #790):
        share/mk/bsd.lib.mk: revision 1.298
        share/mk/bsd.man.mk: revision 1.100
        share/mk/bsd.hostprog.mk: revision 1.55
        distrib/sets/maketars: revision 1.66
        share/zoneinfo/Makefile: revision 1.43
        share/mk/bsd.kmodule.mk: revision 1.19
        usr.bin/xinstall/xinstall.c: revisions 1.106 - 1.108 via patch
        share/mk/bsd.prog.mk: revision 1.241
        share/dict/Makefile: revision 1.17
        share/mk/bsd.README: revision 1.249
        distrib/common/parselist.awk: revision 1.16
        share/mk/bsd.links.mk: revision 1.34
Explicitly sort entries on preparing set files from METALOG.
METALOG could have different order due to install(1) race
on parallel builds, and mtree(8) doesn't sort files.
Should fix inconsistent shared sets among builds as seen in
/pub/NetBSD-daily/netbsd-5/200904010000Z/shared/ and
/pub/NetBSD-daily/netbsd-5/200904010002Z/shared/ dirs.
Okay'ed by s...@.
Changes for installing with a metalog:
* When installing hard links and using a metalog, if -o, -g, -m, or -f
  args were explicitly specified on the command line, then believe them,
  but do not implicitly believe uname/gname/mode/flags from the file
  system.
* Output fields in the same order used by mtree.
Fix -Wshadow -Wcast-qual issues
Re-calculate size and digestresult after stripping, to ensure that
correct values appear in the metalog.
Add LINKSOWN, LINKSGRP, and LINKSMODE variables for use by bsd.links.mk
when installing hard links.  They have no effect except when using a
metalog, in which case the information is added to the metalog.  In
the future, these variables may be replaced by a method for explicitly
recording hard links in a metadata log.
Also change a few things that called ${INSTALL_LINK} without going
through bsd.links.mk.
Reviewed by perry and joerg.  This should fix PR 24457 and PR 41155.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.15.4.1 src/distrib/common/parselist.awk
cvs rdiff -u -r1.64.6.2 -r1.64.6.3 src/distrib/sets/maketars
cvs rdiff -u -r1.16 -r1.16.38.1 src/share/dict/Makefile
cvs rdiff -u -r1.236.2.7 -r1.236.2.8 src/share/mk/bsd.README
cvs rdiff -u -r1.53 -r1.53.2.1 src/share/mk/bsd.hostprog.mk
cvs rdiff -u -r1.13.2.1 -r1.13.2.2 src/share/mk/bsd.kmodule.mk
cvs rdiff -u -r1.289.2.2 -r1.289.2.3 src/share/mk/bsd.lib.mk
cvs rdiff -u -r1.32 -r1.32.24.1 src/share/mk/bsd.links.mk
cvs rdiff -u -r1.98 -r1.98.2.1 src/share/mk/bsd.man.mk
cvs rdiff -u -r1.239.2.1 -r1.239.2.2 src/share/mk/bsd.prog.mk
cvs rdiff -u -r1.42 -r1.42.12.1 src/share/zoneinfo/Makefile
cvs rdiff -u -r1.103 -r1.103.4.1 src/usr.bin/xinstall/xinstall.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/common/parselist.awk
diff -u src/distrib/common/parselist.awk:1.15 src/distrib/common/parselist.awk:1.15.4.1
--- src/distrib/common/parselist.awk:1.15	Wed Apr 30 13:10:48 2008
+++ src/distrib/common/parselist.awk	Sat Jun  6 22:10:13 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: parselist.awk,v 1.15 2008/04/30 13:10:48 martin Exp $
+#	$NetBSD: parselist.awk,v 1.15.4.1 2009/06/06 22:10:13 bouyer Exp $
 #
 # Copyright (c) 2002 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -225,7 +225,7 @@
 				    crunchprog, 555);
 				continue;
 			}
-			link(crunchprog, $i);
+			link(crunchprog, $i, 555);
 		}
 	}
 	next;
@@ -248,7 +248,7 @@
 		err("Usage: LINK prog link [...]");
 	if (mode == "install" || mode == "mtree" || mode == "populate") {
 		for (i = 3; i <= NF; i++)
-			link($2, $i);
+			link($2, $i, 444);
 	}
 	next;
 }
@@ -305,7 +305,8 @@
 	if (perm == "")
 		perm = 444;
 	if (mode == "install") {
-		printf("\t${INSTALL_FILE} -o ${BINOWN} -g ${BINGRP} -m %s %s %s/%s\n",
+		printf("\t${INSTALL_FILE} -o ${BINOWN} -g ${BINGRP}" \
+		    " -m %s %s %s/%s\n",
 		    perm, src, ENVIRON["TARGETDIR"], dest)
 	} else if (mode == "mtree") {
 		printf("./%s mode=%s\n", dest, perm);
@@ -316,13 +317,14 @@
 	}
 }
 
-function link (src, dest) \
+function link (src, dest, perm) \
 {
 	if (mode == "install") {
-		printf("\t${INSTALL_LINK} %s/%s %s/%s\n",
-		    ENVIRON["TARGETDIR"], src, ENVIRON["TARGETDIR"], dest)
+		printf("\t${INSTALL_LINK} -o ${BINOWN} -g ${BINGRP}" \
+		    " -m %s %s/%s %s/%s\n",
+		    perm, ENVIRON["TARGETDIR"], src, ENVIRON["TARGETDIR"], dest)
 	} else if (mode == "mtree") {
-		printf("./%s\n", dest);
+		printf("./%s mode=%s\n", dest, perm);
 	} else {
 		printf("rm -rf %s/%s\n", ENVIRON["TARGETDIR"], dest);
 		printf("(cd %s; ln %s %s) || exit 1\n",

Index: src/distrib/sets/maketars
diff -u src/distrib/sets/maketars:1.64.6.2 src/distrib/sets/maketars:1.64.6.3
--- src/distrib/sets/maketars:1.64.6.2	Tue Apr  7 20:48:40 2009
+++ src/distrib/sets/maketars	Sat Jun  6 22:10:12 2009
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $NetBSD: maketars,v 1.64.6.2 2009/04/07 20:48:40 snj Exp $
+# $NetBSD: maketars,v 1.64.6.3 2009/06/06 22:10:12 bouyer Exp $
 #
 # Make release tar files for some or all lists.  Usage:
 # maketars [-b] [-x] [-i installdir] [-a arch] [-m machine] [-s setsdir]
@@ -148,7 +148,8 @@
 		(
 			echo "/set uname=root gname=wheel"
 			${AWK} -f "${rundir}/join.awk" \
-				"${SDIR}/flist.${setname}.full" "${metalog}"
+				"${SDIR}/flist.${setname}.full" "${metalog}" \
+				    | ${SORT} -u
 			echo "./etc/mtree/set.${setname} type=file mode=0444"
 		) > "${setlistdir}/set.${setname}"
 		# We deliberately do not add set.${setname} to ${metalog},

Index: src/share/dict/Makefile
diff -u src/share/dict/Makefile:1.16 src/share/dict/Makefile:1.16.38.1
--- src/share/dict/Makefile:1.16	Wed Sep 18 08:12:29 2002
+++ src/share/dict/Makefile	Sat Jun  6 22:10:13 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.16 2002/09/18 08:12:29 lukem Exp $
+#	$NetBSD: Makefile,v 1.16.38.1 2009/06/06 22:10:13 bouyer Exp $
 #	@(#)Makefile	8.1 (Berkeley) 6/5/93
 
 # Missing: connectives, words
@@ -8,5 +8,6 @@
 FILES=	README propernames web2 web2a
 FILESDIR=${BINDIR}/dict
 LINKS=	${FILESDIR}/web2 ${FILESDIR}/words
+LINKSMODE= ${FILESMODE}
 
 .include <bsd.prog.mk>

Index: src/share/mk/bsd.README
diff -u src/share/mk/bsd.README:1.236.2.7 src/share/mk/bsd.README:1.236.2.8
--- src/share/mk/bsd.README:1.236.2.7	Mon Jan 26 00:30:32 2009
+++ src/share/mk/bsd.README	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.README,v 1.236.2.7 2009/01/26 00:30:32 snj Exp $
+#	$NetBSD: bsd.README,v 1.236.2.8 2009/06/06 22:10:12 bouyer Exp $
 #	@(#)bsd.README	8.2 (Berkeley) 4/2/94
 
 This is the README file for the make "include" files for the NetBSD
@@ -1019,6 +1019,11 @@
 The include file <bsd.links.mk> handles the LINKS and SYMLINKS variables
 and is included from from <bsd.lib.mk> and <bsd.prog.mk>.
 
+LINKSOWN, LINKSGRP, and LINKSMODE, are relevant only if a metadata log
+is used. The defaults may be modified by other bsd.*.mk files which
+include bsd.links.mk.  In the future, these variables may be replaced
+by a method for explicitly recording hard links in a metadata log.
+
 LINKS		The list of hard links, consisting of pairs of paths:
 			source-file target-file
 		${DESTDIR} is prepended to both paths before linking.
@@ -1040,6 +1045,18 @@
 		are installed by the `configinstall' target,
 		not the `install' target.
 
+LINKSOWN	Link owner.  [${BINOWN}]
+
+LINKSGRP	Link group.  [${BINGRP}]
+
+LINKSMODE	Link mode.  [${NONBINMODE}]
+
+LINKSOWN_<fn>	Link owner of the specific file <fn>.
+
+LINKSGRP_<fn>	Link group of the specific file <fn>.
+
+LINKSMODE_<fn>	Link mode of the specific file <fn>.
+
 
 =-=-=-=-=   bsd.man.mk   =-=-=-=-=
 

Index: src/share/mk/bsd.hostprog.mk
diff -u src/share/mk/bsd.hostprog.mk:1.53 src/share/mk/bsd.hostprog.mk:1.53.2.1
--- src/share/mk/bsd.hostprog.mk:1.53	Thu Oct  2 17:54:53 2008
+++ src/share/mk/bsd.hostprog.mk	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.hostprog.mk,v 1.53 2008/10/02 17:54:53 joerg Exp $
+#	$NetBSD: bsd.hostprog.mk,v 1.53.2.1 2009/06/06 22:10:12 bouyer Exp $
 #	@(#)bsd.prog.mk	8.2 (Berkeley) 4/2/94
 
 .include <bsd.init.mk>
@@ -130,6 +130,7 @@
 .endif
 
 ##### Pull in related .mk logic
+LINKSMODE?= ${BINMODE}
 .include <bsd.man.mk>
 .include <bsd.nls.mk>
 .include <bsd.files.mk>

Index: src/share/mk/bsd.kmodule.mk
diff -u src/share/mk/bsd.kmodule.mk:1.13.2.1 src/share/mk/bsd.kmodule.mk:1.13.2.2
--- src/share/mk/bsd.kmodule.mk:1.13.2.1	Thu Dec  4 02:18:06 2008
+++ src/share/mk/bsd.kmodule.mk	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.kmodule.mk,v 1.13.2.1 2008/12/04 02:18:06 snj Exp $
+#	$NetBSD: bsd.kmodule.mk,v 1.13.2.2 2009/06/06 22:10:12 bouyer Exp $
 
 .include <bsd.init.mk>
 .include <bsd.klinks.mk>
@@ -93,6 +93,9 @@
 .endif
 
 ##### Pull in related .mk logic
+LINKSOWN?= ${KMODULEOWN}
+LINKSGRP?= ${KMODULEGRP}
+LINKSMODE?= ${KMODULEMODE}
 .include <bsd.man.mk>
 .include <bsd.links.mk>
 .include <bsd.dep.mk>

Index: src/share/mk/bsd.lib.mk
diff -u src/share/mk/bsd.lib.mk:1.289.2.2 src/share/mk/bsd.lib.mk:1.289.2.3
--- src/share/mk/bsd.lib.mk:1.289.2.2	Fri Jan  9 03:35:51 2009
+++ src/share/mk/bsd.lib.mk	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.lib.mk,v 1.289.2.2 2009/01/09 03:35:51 snj Exp $
+#	$NetBSD: bsd.lib.mk,v 1.289.2.3 2009/06/06 22:10:12 bouyer Exp $
 #	@(#)bsd.lib.mk	8.3 (Berkeley) 4/22/94
 
 .include <bsd.init.mk>
@@ -714,6 +714,9 @@
 .endif	# !target(libinstall)						# }
 
 ##### Pull in related .mk logic
+LINKSOWN?= ${LIBOWN}
+LINKSGRP?= ${LIBGRP}
+LINKSMODE?= ${LIBMODE}
 .include <bsd.man.mk>
 .include <bsd.nls.mk>
 .include <bsd.files.mk>

Index: src/share/mk/bsd.links.mk
diff -u src/share/mk/bsd.links.mk:1.32 src/share/mk/bsd.links.mk:1.32.24.1
--- src/share/mk/bsd.links.mk:1.32	Mon Sep 11 22:24:09 2006
+++ src/share/mk/bsd.links.mk	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.links.mk,v 1.32 2006/09/11 22:24:09 dbj Exp $
+#	$NetBSD: bsd.links.mk,v 1.32.24.1 2009/06/06 22:10:12 bouyer Exp $
 
 .include <bsd.init.mk>
 
@@ -8,11 +8,22 @@
 ##### Default values
 LINKS?=
 SYMLINKS?=
+LINKSOWN?=	${BINOWN}
+LINKSGRP?=	${BINGRP}
+LINKSMODE?=	${NONBINMODE}
 
 __linkinstall: .USE
 	${_MKSHMSG_INSTALL} ${.TARGET}; \
-	${_MKSHECHO} "${INSTALL_LINK} ${.ALLSRC} ${.TARGET}" && \
-	${INSTALL_LINK} ${.ALLSRC} ${.TARGET}
+	${_MKSHECHO} "${INSTALL_LINK} \
+	    -o ${LINKSOWN_${.ALLSRC:T}:U${LINKSOWN}} \
+	    -g ${LINKSGRP_${.ALLSRC:T}:U${LINKSGRP}} \
+	    -m ${LINKSMODE_${.ALLSRC:T}:U${LINKSMODE}} \
+	    ${.ALLSRC} ${.TARGET}" && \
+	${INSTALL_LINK} \
+	    -o ${LINKSOWN_${.ALLSRC:T}:U${LINKSOWN}} \
+	    -g ${LINKSGRP_${.ALLSRC:T}:U${LINKSGRP}} \
+	    -m ${LINKSMODE_${.ALLSRC:T}:U${LINKSMODE}} \
+	    ${.ALLSRC} ${.TARGET}
 
 ##### Install rules
 .PHONY:		linksinstall

Index: src/share/mk/bsd.man.mk
diff -u src/share/mk/bsd.man.mk:1.98 src/share/mk/bsd.man.mk:1.98.2.1
--- src/share/mk/bsd.man.mk:1.98	Fri Aug 29 04:52:44 2008
+++ src/share/mk/bsd.man.mk	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.man.mk,v 1.98 2008/08/29 04:52:44 lukem Exp $
+#	$NetBSD: bsd.man.mk,v 1.98.2.1 2009/06/06 22:10:12 bouyer Exp $
 #	@(#)bsd.man.mk	8.1 (Berkeley) 6/8/93
 
 .include <bsd.init.mk>
@@ -54,8 +54,10 @@
 # XXX consider including bsd.links.mk and using __linkinstall instead
 __linkinstallpage: .USE
 	${_MKSHMSG_INSTALL} ${.TARGET}; \
-	${_MKSHECHO} "${INSTALL_LINK} ${.ALLSRC} ${.TARGET}" && \
-	${INSTALL_LINK} ${.ALLSRC} ${.TARGET}
+	${_MKSHECHO} "${INSTALL_LINK} -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} \
+	    ${.ALLSRC} ${.TARGET}" && \
+	${INSTALL_LINK} -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} \
+	    ${.ALLSRC} ${.TARGET}
 
 ##### Build and install rules (source form pages)
 

Index: src/share/mk/bsd.prog.mk
diff -u src/share/mk/bsd.prog.mk:1.239.2.1 src/share/mk/bsd.prog.mk:1.239.2.2
--- src/share/mk/bsd.prog.mk:1.239.2.1	Sat Dec  6 21:56:37 2008
+++ src/share/mk/bsd.prog.mk	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: bsd.prog.mk,v 1.239.2.1 2008/12/06 21:56:37 snj Exp $
+#	$NetBSD: bsd.prog.mk,v 1.239.2.2 2009/06/06 22:10:12 bouyer Exp $
 #	@(#)bsd.prog.mk	8.2 (Berkeley) 4/2/94
 
 .ifndef HOSTPROG
@@ -442,6 +442,9 @@
 .PHONY:		scriptsinstall
 
 ##### Pull in related .mk logic
+LINKSOWN?= ${BINOWN}
+LINKSGRP?= ${BINGRP}
+LINKSMODE?= ${BINMODE}
 .include <bsd.man.mk>
 .include <bsd.nls.mk>
 .include <bsd.files.mk>

Index: src/share/zoneinfo/Makefile
diff -u src/share/zoneinfo/Makefile:1.42 src/share/zoneinfo/Makefile:1.42.12.1
--- src/share/zoneinfo/Makefile:1.42	Thu Nov  8 20:14:07 2007
+++ src/share/zoneinfo/Makefile	Sat Jun  6 22:10:12 2009
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.42 2007/11/08 20:14:07 drochner Exp $
+#	$NetBSD: Makefile,v 1.42.12.1 2009/06/06 22:10:12 bouyer Exp $
 
 .include <bsd.own.mk>
 
@@ -104,8 +104,10 @@
 				continue; \
 			fi; \
 			${_MKSHMSG_INSTALL} $$destfile; \
-			${_MKSHECHO} ${INSTALL_LINK} $$lastfile $$destfile; \
-			${INSTALL_LINK} $$lastfile $$destfile; \
+			${_MKSHECHO} ${INSTALL_LINK} -o ${BINOWN} -g ${BINGRP} \
+			    -m ${NONBINMODE} $$lastfile $$destfile; \
+			${INSTALL_LINK} -o ${BINOWN} -g ${BINGRP} \
+			    -m ${NONBINMODE} $$lastfile $$destfile; \
 		else \
 			lastdevino=$$devino; \
 			lastfile=$$destfile; \

Index: src/usr.bin/xinstall/xinstall.c
diff -u src/usr.bin/xinstall/xinstall.c:1.103 src/usr.bin/xinstall/xinstall.c:1.103.4.1
--- src/usr.bin/xinstall/xinstall.c:1.103	Mon Jul 21 14:19:28 2008
+++ src/usr.bin/xinstall/xinstall.c	Sat Jun  6 22:10:13 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: xinstall.c,v 1.103 2008/07/21 14:19:28 lukem Exp $	*/
+/*	$NetBSD: xinstall.c,v 1.103.4.1 2009/06/06 22:10:13 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -46,7 +46,7 @@
 #if 0
 static char sccsid[] = "@(#)xinstall.c	8.1 (Berkeley) 7/21/93";
 #else
-__RCSID("$NetBSD: xinstall.c,v 1.103 2008/07/21 14:19:28 lukem Exp $");
+__RCSID("$NetBSD: xinstall.c,v 1.103.4.1 2009/06/06 22:10:13 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -82,6 +82,7 @@
 #define BACKUP_SUFFIX ".old"
 
 int	dobackup, dodir, dostrip, dolink, dopreserve, dorename, dounpriv;
+int	haveopt_f, haveopt_g, haveopt_m, haveopt_o;
 int	numberedbackup;
 int	mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
 char	pathbuf[MAXPATHLEN];
@@ -92,7 +93,7 @@
 u_long	fileflags;
 char	*stripArgs;
 char	*afterinstallcmd;
-char	*suffix = BACKUP_SUFFIX;
+const char *suffix = BACKUP_SUFFIX;
 char	*destdir;
 
 enum {
@@ -124,7 +125,7 @@
 int	main(int, char *[]);
 void	makelink(char *, char *);
 void	metadata_log(const char *, const char *, struct timeval *,
-	    const char *, const char *);
+	    const char *, const char *, off_t);
 int	parseid(char *, id_t *);
 void	strip(char *);
 void	usage(void);
@@ -183,10 +184,12 @@
 			break;
 #if ! HAVE_NBTOOL_CONFIG_H
 		case 'f':
+			haveopt_f = 1;
 			fflags = optarg;
 			break;
 #endif
 		case 'g':
+			haveopt_g = 1;
 			group = optarg;
 			break;
 		case 'h':
@@ -221,6 +224,7 @@
 				}
 			break;
 		case 'm':
+			haveopt_m = 1;
 			if (!(set = setmode(optarg)))
 				err(1, "Cannot set file mode `%s'", optarg);
 			mode = getmode(set, 0);
@@ -236,6 +240,7 @@
 				    optarg);
 			break;
 		case 'o':
+			haveopt_o = 1;
 			owner = optarg;
 			break;
 		case 'p':
@@ -470,20 +475,29 @@
 			if (stat(to_name, &to_sb))
 				err(1, "%s: stat", to_name);
 			if (S_ISREG(to_sb.st_mode)) {
-					/* XXX: only metalog hardlinked files */
+					/* XXX: hard links to anything
+					 * other than plain files are not
+					 * metalogged
+					 */
 				int omode;
 				char *oowner, *ogroup, *offlags;
 				char *dres;
 
-					/* XXX: use underlying perms */
+					/* XXX: use underlying perms,
+					 * unless overridden on command line.
+					 */
 				omode = mode;
-				mode = (to_sb.st_mode & 0777);
+				if (!haveopt_m)
+					mode = (to_sb.st_mode & 0777);
 				oowner = owner;
-				owner = NULL;
+				if (!haveopt_o)
+					owner = NULL;
 				ogroup = group;
-				group = NULL;
+				if (!haveopt_g)
+					group = NULL;
 				offlags = fflags;
-				fflags = NULL;
+				if (!haveopt_f)
+					fflags = NULL;
 				switch (digesttype) {
 				case DIGEST_MD5:
 					dres = MD5File(from_name, NULL);
@@ -497,7 +511,8 @@
 				default:
 					dres = NULL;
 				}
-				metadata_log(to_name, "file", NULL, NULL, dres);
+				metadata_log(to_name, "file", NULL, NULL,
+				    dres, to_sb.st_size);
 				free(dres);
 				mode = omode;
 				owner = oowner;
@@ -515,7 +530,7 @@
 			err(1, "%s: realpath", from_name);
 		do_symlink(src, to_name);
 			/* XXX: src may point outside of destdir */
-		metadata_log(to_name, "link", NULL, src, NULL);
+		metadata_log(to_name, "link", NULL, src, NULL, 0);
 		return;
 	}
 
@@ -557,7 +572,7 @@
 
 		do_symlink(lnk, to_name);
 			/* XXX: lnk may point outside of destdir */
-		metadata_log(to_name, "link", NULL, lnk, NULL);
+		metadata_log(to_name, "link", NULL, lnk, NULL, 0);
 		return;
 	}
 
@@ -567,7 +582,7 @@
 	 */
 	do_symlink(from_name, to_name);
 		/* XXX: from_name may point outside of destdir */
-	metadata_log(to_name, "link", NULL, from_name, NULL);
+	metadata_log(to_name, "link", NULL, from_name, NULL, 0);
 }
 
 /*
@@ -578,17 +593,18 @@
 install(char *from_name, char *to_name, u_int flags)
 {
 	struct stat	from_sb;
-#if ! HAVE_NBTOOL_CONFIG_H
 	struct stat	to_sb;
-#endif
 	struct timeval	tv[2];
+	off_t		size;
 	int		devnull, from_fd, to_fd, serrno, tmpmode;
 	char		*p, tmpl[MAXPATHLEN], *oto_name, *digestresult;
 
+	size = -1;
 	if (!dolink) {
 			/* ensure that from_sb & tv are sane if !dolink */
 		if (stat(from_name, &from_sb))
 			err(1, "%s: stat", from_name);
+		size = from_sb.st_size;
 #if BSD4_4 && !HAVE_NBTOOL_CONFIG_H
 		TIMESPEC_TO_TIMEVAL(&tv[0], &from_sb.st_atimespec);
 		TIMESPEC_TO_TIMEVAL(&tv[1], &from_sb.st_mtimespec);
@@ -600,7 +616,8 @@
 #endif
 	}
 
-	if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) {
+	if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL) != 0) {
+		devnull = 0;
 		if (!dolink) {
 			if (!S_ISREG(from_sb.st_mode))
 				errx(1, "%s: not a regular file", from_name);
@@ -612,12 +629,12 @@
 			    (p = strrchr(from_name, '/')) ? ++p : from_name);
 			to_name = pathbuf;
 		}
-		devnull = 0;
 	} else {
+		devnull = 1;
+		size = 0;
 #if HAVE_STRUCT_STAT_ST_FLAGS
 		from_sb.st_flags = 0;	/* XXX */
 #endif
-		devnull = 1;
 	}
 
 	/*
@@ -678,6 +695,16 @@
 		close(to_fd);
 		if ((to_fd = open(to_name, O_RDONLY, S_IRUSR | S_IWUSR)) < 0)
 			err(1, "stripping %s", to_name);
+
+		/*
+		 * Recalculate size and digestresult after stripping.
+		 */
+		if (fstat(to_fd, &to_sb) != 0)
+			err(1, "%s: fstat", to_name);
+		size = to_sb.st_size;
+		digestresult =
+		    copy(to_fd, to_name, -1, NULL, size);
+
 	}
 
 	if (afterinstallcmd != NULL) {
@@ -745,13 +772,15 @@
 	}
 #endif
 
-	metadata_log(to_name, "file", tv, NULL, digestresult);
+	metadata_log(to_name, "file", tv, NULL, digestresult, size);
 	free(digestresult);
 }
 
 /*
  * copy --
- *	copy from one file to another
+ *	copy from one file to another, returning a digest.
+ *
+ *	If to_fd < 0, just calculate a digest, don't copy.
  */
 char *
 copy(int from_fd, char *from_name, int to_fd, char *to_name, off_t size)
@@ -775,6 +804,8 @@
 		SHA1Init(&ctxSHA1);
 		break;
 	case DIGEST_NONE:
+		if (to_fd < 0)
+			return NULL; /* no need to do anything */
 	default:
 		break;
 	}
@@ -802,7 +833,7 @@
 				warnx("madvise: %s", strerror(errno));
 #endif
 
-			if (write(to_fd, p, size) != size) {
+			if (to_fd >= 0 && write(to_fd, p, size) != size) {
 				serrno = errno;
 				(void)unlink(to_name);
 				errx(1, "%s: write: %s",
@@ -825,7 +856,8 @@
 		} else {
  mmap_failed:
 			while ((nr = read(from_fd, buf, sizeof(buf))) > 0) {
-				if ((nw = write(to_fd, buf, nr)) != nr) {
+				if (to_fd >= 0 &&
+				    (nw = write(to_fd, buf, nr)) != nr) {
 					serrno = errno;
 					(void)unlink(to_name);
 					errx(1, "%s: write: %s", to_name,
@@ -873,7 +905,7 @@
 {
 	static const char exec_failure[] = ": exec of strip failed: ";
 	int	serrno, status;
-	const char *stripprog, *progname;
+	const char * volatile stripprog, *progname;
 	char *cmd;
 
 	if ((stripprog = getenv("STRIP")) == NULL) {
@@ -1036,17 +1068,18 @@
 	    || chmod(path, mode) == -1 )) {
                 warn("%s: chown/chmod", path);
 	}
-	metadata_log(path, "dir", NULL, NULL, NULL);
+	metadata_log(path, "dir", NULL, NULL, NULL, 0);
 }
 
 /*
  * metadata_log --
  *	if metafp is not NULL, output mtree(8) full path name and settings to
- *	metafp, to allow permissions to be set correctly by other tools.
+ *	metafp, to allow permissions to be set correctly by other tools,
+ *	or to allow integrity checks to be performed.
  */
 void
 metadata_log(const char *path, const char *type, struct timeval *tv,
-	const char *link, const char *digestresult)
+	const char *slink, const char *digestresult, off_t size)
 {
 	static const char	extra[] = { ' ', '\t', '\n', '\\', '#', '\0' };
 	const char	*p;
@@ -1084,23 +1117,26 @@
 	strsvis(buf, p, VIS_CSTYLE, extra);		/* encode name */
 	p = buf;
 							/* print details */
-	fprintf(metafp, ".%s%s type=%s mode=%#o", *p ? "/" : "", p, type, mode);
-	if (link) {
-		strsvis(buf, link, VIS_CSTYLE, extra);	/* encode link */
-		fprintf(metafp, " link=%s", buf);
-	}
+	fprintf(metafp, ".%s%s type=%s", *p ? "/" : "", p, type);
 	if (owner)
 		fprintf(metafp, " uname=%s", owner);
 	if (group)
 		fprintf(metafp, " gname=%s", group);
-	if (fflags)
-		fprintf(metafp, " flags=%s", fflags);
-	if (tags)
-		fprintf(metafp, " tags=%s", tags);
+	fprintf(metafp, " mode=%#o", mode);
+	if (slink) {
+		strsvis(buf, slink, VIS_CSTYLE, extra);	/* encode link */
+		fprintf(metafp, " link=%s", buf);
+	}
+	if (*type == 'f') /* type=file */
+		fprintf(metafp, " size=%lld", (long long)size);
 	if (tv != NULL && dopreserve)
 		fprintf(metafp, " time=%ld.%ld", tv[1].tv_sec, tv[1].tv_usec);
 	if (digestresult && digest)
 		fprintf(metafp, " %s=%s", digest, digestresult);
+	if (fflags)
+		fprintf(metafp, " flags=%s", fflags);
+	if (tags)
+		fprintf(metafp, " tags=%s", tags);
 	fputc('\n', metafp);
 	fflush(metafp);					/* flush output */
 							/* unlock log file */

Reply via email to