Module Name:    src
Committed By:   apb
Date:           Tue Apr  7 22:07:54 UTC 2009

Modified Files:
        src/usr.bin/xinstall: xinstall.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.105 -r1.106 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/usr.bin/xinstall/xinstall.c
diff -u src/usr.bin/xinstall/xinstall.c:1.105 src/usr.bin/xinstall/xinstall.c:1.106
--- src/usr.bin/xinstall/xinstall.c:1.105	Sun Dec 28 18:38:27 2008
+++ src/usr.bin/xinstall/xinstall.c	Tue Apr  7 22:07:54 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: xinstall.c,v 1.105 2008/12/28 18:38:27 christos Exp $	*/
+/*	$NetBSD: xinstall.c,v 1.106 2009/04/07 22:07:54 apb 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.105 2008/12/28 18:38:27 christos Exp $");
+__RCSID("$NetBSD: xinstall.c,v 1.106 2009/04/07 22:07:54 apb Exp $");
 #endif
 #endif /* not lint */
 
@@ -83,6 +83,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];
@@ -125,7 +126,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);
@@ -184,10 +185,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':
@@ -222,6 +225,7 @@
 				}
 			break;
 		case 'm':
+			haveopt_m = 1;
 			if (!(set = setmode(optarg)))
 				err(1, "Cannot set file mode `%s'", optarg);
 			mode = getmode(set, 0);
@@ -237,6 +241,7 @@
 				    optarg);
 			break;
 		case 'o':
+			haveopt_o = 1;
 			owner = optarg;
 			break;
 		case 'p':
@@ -471,20 +476,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);
@@ -498,7 +512,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;
@@ -516,7 +531,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;
 	}
 
@@ -558,7 +573,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;
 	}
 
@@ -568,7 +583,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);
 }
 
 /*
@@ -746,7 +761,8 @@
 	}
 #endif
 
-	metadata_log(to_name, "file", tv, NULL, digestresult);
+	metadata_log(to_name, "file", tv, NULL, digestresult,
+	    (devnull ? 0 : from_sb.st_size));
 	free(digestresult);
 }
 
@@ -1037,17 +1053,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 *link, const char *digestresult, off_t size)
 {
 	static const char	extra[] = { ' ', '\t', '\n', '\\', '#', '\0' };
 	const char	*p;
@@ -1085,24 +1102,27 @@
 	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 (link) {
+		strsvis(buf, link, 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=%lld.%ld", 
+		fprintf(metafp, " time=%lld.%ld",
 			(long long)tv[1].tv_sec, (long)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