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.
* Add a size= field (only for plain files).
* Output fields in the same order used by mtree.
This commit is contained in:
apb 2009-04-07 22:07:54 +00:00
parent b6889a3f64
commit 534e2679af

View File

@ -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 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993\
#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 @@ __RCSID("$NetBSD: xinstall.c,v 1.105 2008/12/28 18:38:27 christos Exp $");
#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 @@ void install_dir(char *, u_int);
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 @@ main(int argc, char *argv[])
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 @@ main(int argc, char *argv[])
}
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 @@ main(int argc, char *argv[])
optarg);
break;
case 'o':
haveopt_o = 1;
owner = optarg;
break;
case 'p':
@ -471,20 +476,29 @@ makelink(char *from_name, char *to_name)
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 @@ makelink(char *from_name, char *to_name)
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 @@ makelink(char *from_name, char *to_name)
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 @@ makelink(char *from_name, char *to_name)
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 @@ makelink(char *from_name, char *to_name)
*/
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 @@ install(char *from_name, char *to_name, u_int flags)
}
#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 @@ install_dir(char *path, u_int flags)
|| 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 @@ metadata_log(const char *path, const char *type, struct timeval *tv,
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);
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",
(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);
if (tv != NULL && dopreserve)
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);
fputc('\n', metafp);
fflush(metafp); /* flush output */
/* unlock log file */