- Add "-a afterinstallcommand", which runs "sh -c afterinstallcmd target"

after target has been installed and possibly stripped with -s, but
  before ownership, permissions or timestamps are set, and before
  renaming (with -r) occurs.  Per discussion with simonb.
- When metalogging hardlinks, log the mode of the existing target
  (rather than the default 0755), and ignore owner/group/fflags.
- Improve man page description of various options to include argument name.
- Clean up usage() to use getprogname(), etc.
This commit is contained in:
lukem 2002-03-19 14:17:04 +00:00
parent 376c14488f
commit 3d000fd59c
2 changed files with 138 additions and 25 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: install.1,v 1.29 2002/02/08 01:36:38 ross Exp $ .\" $NetBSD: install.1,v 1.30 2002/03/19 14:17:04 lukem Exp $
.\" .\"
.\" Copyright (c) 1987, 1990, 1993 .\" Copyright (c) 1987, 1990, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -33,7 +33,7 @@
.\" .\"
.\" @(#)install.1 8.1 (Berkeley) 6/6/93 .\" @(#)install.1 8.1 (Berkeley) 6/6/93
.\" .\"
.Dd October 26, 2001 .Dd March 20, 2002
.Dt INSTALL 1 .Dt INSTALL 1
.Os .Os
.Sh NAME .Sh NAME
@ -55,6 +55,9 @@
.Op Fl T Ar tags .Op Fl T Ar tags
.Ek .Ek
.Bk -words .Bk -words
.Op Fl a Ar command
.Ek
.Bk -words
.Op Fl m Ar mode .Op Fl m Ar mode
.Ek .Ek
.Bk -words .Bk -words
@ -85,6 +88,9 @@
.Op Fl T Ar tags .Op Fl T Ar tags
.Ek .Ek
.Bk -words .Bk -words
.Op Fl a Ar command
.Ek
.Bk -words
.Op Fl m Ar mode .Op Fl m Ar mode
.Ek .Ek
.Bk -words .Bk -words
@ -102,8 +108,8 @@
.Ar file1 ...\& .Ar file1 ...\&
.Ar fileN directory .Ar fileN directory
.Nm "" .Nm ""
.Op Fl Up
.Fl d .Fl d
.Op Fl Up
.Bk -words .Bk -words
.Op Fl M Ar metalog .Op Fl M Ar metalog
.Ek .Ek
@ -111,6 +117,9 @@
.Op Fl T Ar tags .Op Fl T Ar tags
.Ek .Ek
.Bk -words .Bk -words
.Op Fl a Ar command
.Ek
.Bk -words
.Op Fl m Ar mode .Op Fl m Ar mode
.Ek .Ek
.Bk -words .Bk -words
@ -143,6 +152,23 @@ if permissions allow, An alternate backup suffix may be specified via the
option's argument. option's argument.
.Pp .Pp
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl a Ar command
Run
.Ar command
on the target after installation and stripping
.Pq Fl s ,
but before
ownership, permissions or timestamps are set and before renaming
.Pq Fl r
occurs.
.Ar command
is invoked via the
.Xr sh 1
shell, allowing a single
.Fl a
argument be to specified to
.Nm
which the shell can then tokenize.
.It Fl b .It Fl b
Backup any existing files before overwriting them by renaming Backup any existing files before overwriting them by renaming
them to them to
@ -167,12 +193,15 @@ Copy the file.
This flag turns off the default behavior of This flag turns off the default behavior of
.Nm .Nm
where it deletes the original file after creating the target. where it deletes the original file after creating the target.
.It Fl f .It Fl d
Create directories.
Missing parent directories are created as required.
.It Fl f Ar flags
Specify the target's file flags. Specify the target's file flags.
(See (See
.Xr chflags 1 .Xr chflags 1
for a list of possible flags and their meanings.) for a list of possible flags and their meanings.)
.It Fl g .It Fl g Ar group
Specify a group. Specify a group.
.It Fl M Ar metalog .It Fl M Ar metalog
Write the metadata associated with each item installed to Write the metadata associated with each item installed to
@ -183,7 +212,7 @@ in an
specification line. specification line.
The metadata includes: the file name and file type, and depending upon The metadata includes: the file name and file type, and depending upon
other options, the owner, group, file flags, modification time, and tags. other options, the owner, group, file flags, modification time, and tags.
.It Fl m .It Fl m Ar mode
Specify an alternative mode. Specify an alternative mode.
The default mode is set to rwxr-xr-x (0755). The default mode is set to rwxr-xr-x (0755).
The specified mode may be either an octal or symbolic value; see The specified mode may be either an octal or symbolic value; see
@ -207,7 +236,7 @@ are:
.Ar m .Ar m
(mixed). Absolute and relative have effect only for symbolic links. Mixed links (mixed). Absolute and relative have effect only for symbolic links. Mixed links
are hard links for files on the same filesystem, symbolic otherwise. are hard links for files on the same filesystem, symbolic otherwise.
.It Fl o .It Fl o Ar owner
Specify an owner. Specify an owner.
.It Fl p .It Fl p
Preserve the source files access and modification times. Preserve the source files access and modification times.
@ -238,7 +267,7 @@ is used,
is invoked via the is invoked via the
.Xr sh 1 .Xr sh 1
shell, allowing a single shell, allowing a single
Fl S .Fl S
argument be to specified to argument be to specified to
.Nm .Nm
which the shell can then tokenize. Normally, which the shell can then tokenize. Normally,
@ -252,9 +281,6 @@ Specify the
.Xr mtree 8 .Xr mtree 8
tags to write out for the file when using tags to write out for the file when using
.Fl M Ar metalog . .Fl M Ar metalog .
.It Fl d
Create directories.
Missing parent directories are created as required.
.It Fl U .It Fl U
Indicate that install is running unprivileged, and that it should not Indicate that install is running unprivileged, and that it should not
try to change the owner, the group, or the file flags of the destination. try to change the owner, the group, or the file flags of the destination.

View File

@ -1,4 +1,4 @@
/* $NetBSD: xinstall.c,v 1.68 2002/02/28 00:22:51 lukem Exp $ */ /* $NetBSD: xinstall.c,v 1.69 2002/03/19 14:17:04 lukem Exp $ */
/* /*
* Copyright (c) 1987, 1993 * Copyright (c) 1987, 1993
@ -50,7 +50,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993\n\
#if 0 #if 0
static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93"; static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93";
#else #else
__RCSID("$NetBSD: xinstall.c,v 1.68 2002/02/28 00:22:51 lukem Exp $"); __RCSID("$NetBSD: xinstall.c,v 1.69 2002/03/19 14:17:04 lukem Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -90,6 +90,7 @@ FILE *metafp;
char *metafile; char *metafile;
u_long fileflags; u_long fileflags;
char *stripArgs; char *stripArgs;
char *afterinstallcmd;
char *suffix = BACKUP_SUFFIX; char *suffix = BACKUP_SUFFIX;
#define LN_ABSOLUTE 0x01 #define LN_ABSOLUTE 0x01
@ -103,6 +104,7 @@ char *suffix = BACKUP_SUFFIX;
#define HASUID 0x04 /* Tell install the uid was given */ #define HASUID 0x04 /* Tell install the uid was given */
#define HASGID 0x08 /* Tell install the gid was given */ #define HASGID 0x08 /* Tell install the gid was given */
void afterinstall(const char *, const char *, int);
void backup(const char *); void backup(const char *);
void copy(int, char *, int, char *, off_t); void copy(int, char *, int, char *, off_t);
int do_link(char *, char *); int do_link(char *, char *);
@ -130,8 +132,13 @@ main(int argc, char *argv[])
setprogname(argv[0]); setprogname(argv[0]);
iflags = 0; iflags = 0;
while ((ch = getopt(argc, argv, "cbB:df:g:l:m:M:o:prsS:T:U")) != -1) while ((ch = getopt(argc, argv, "a:cbB:df:g:l:m:M:o:prsS:T:U")) != -1)
switch((char)ch) { switch((char)ch) {
case 'a':
afterinstallcmd = strdup(optarg);
if (afterinstallcmd == NULL)
errx(1, "%s", strerror(ENOMEM));
break;
case 'B': case 'B':
suffix = optarg; suffix = optarg;
numberedbackup = 0; numberedbackup = 0;
@ -422,9 +429,26 @@ makelink(char *from_name, char *to_name)
} else { } else {
if (stat(to_name, &to_sb)) if (stat(to_name, &to_sb))
err(1, "%s: stat", to_name); err(1, "%s: stat", to_name);
if (S_ISREG(to_sb.st_mode)) if (S_ISREG(to_sb.st_mode)) {
metadata_log(to_name, "file", NULL, NULL);
/* XXX: only metalog hardlinked files */ /* XXX: only metalog hardlinked files */
int omode;
char *oowner, *ogroup, *offlags;
/* XXX: use underlying perms */
omode = mode;
mode = (to_sb.st_mode & 0777);
oowner = owner;
owner = NULL;
ogroup = group;
group = NULL;
offlags = fflags;
fflags = NULL;
metadata_log(to_name, "file", NULL, NULL);
mode = omode;
owner = oowner;
group = ogroup;
fflags = offlags;
}
return; return;
} }
} }
@ -580,7 +604,19 @@ install(char *from_name, char *to_name, u_int flags)
*/ */
close(to_fd); close(to_fd);
if ((to_fd = open(to_name, O_RDONLY, S_IRUSR | S_IWUSR)) < 0) if ((to_fd = open(to_name, O_RDONLY, S_IRUSR | S_IWUSR)) < 0)
err(1, "stripping %s", to_name); err(1, "stripping %s", to_name);
}
if (afterinstallcmd != NULL) {
afterinstall(afterinstallcmd, to_name, 1);
/*
* Re-open our fd on the target, in case we used an
* after-install command that does not work in-place
*/
close(to_fd);
if ((to_fd = open(to_name, O_RDONLY, S_IRUSR | S_IWUSR)) < 0)
err(1, "running after install command on %s", to_name);
} }
/* /*
@ -761,6 +797,49 @@ strip(char *to_name)
} }
} }
/*
* afterinstall --
* run provided command on the target file or directory after it's been
* installed and stripped, but before permissions are set or it's renamed
*/
void
afterinstall(const char *command, const char *to_name, int errunlink)
{
int serrno, status;
char *cmd;
switch (vfork()) {
case -1:
serrno = errno;
if (errunlink)
(void)unlink(to_name);
errx(1, "vfork: %s", strerror(serrno));
/*NOTREACHED*/
case 0:
/*
* build up a command line and let /bin/sh
* parse the arguments
*/
cmd = (char*)malloc(sizeof(char)*
(2+strlen(command)+
strlen(to_name)));
if (cmd == NULL)
errx(1, "%s", strerror(ENOMEM));
sprintf(cmd, "%s %s", command, to_name);
execl(_PATH_BSHELL, "sh", "-c", cmd, NULL);
warn("%s: exec of after install command", command);
_exit(1);
/*NOTREACHED*/
default:
if ((wait(&status) == -1 || status) && errunlink)
(void)unlink(to_name);
}
}
/* /*
* backup -- * backup --
* backup file "to_name" to to_name.suffix * backup file "to_name" to to_name.suffix
@ -817,6 +896,9 @@ install_dir(char *path, u_int flags)
break; break;
} }
if (afterinstallcmd != NULL)
afterinstall(afterinstallcmd, path, 0);
if (!dounpriv && ( if (!dounpriv && (
((flags & (HASUID | HASGID)) && chown(path, uid, gid) == -1) ((flags & (HASUID | HASGID)) && chown(path, uid, gid) == -1)
|| chmod(path, mode) == -1 )) { || chmod(path, mode) == -1 )) {
@ -907,14 +989,19 @@ xdirname(char *path)
void void
usage(void) usage(void)
{ {
const char *prog;
(void)fprintf(stderr, "\ prog = getprogname();
usage: install [-Ubcprs] [-M log] [-T tags] [-B suffix] [-f flags] [-m mode]\n\
[-o owner] [-g group] [-l linkflags] [-S stripflags] file1 file2\n\ (void)fprintf(stderr,
install [-Ubcprs] [-M log] [-T tags] [-B suffix] [-f flags] [-m mode]\n\ "usage: %s [-Ubcprs] [-M log] [-T tags] [-B suffix] [-a afterinstallcmd]\n"
[-o owner] [-g group] [-l linkflags] [-S stripflags]\n\ " [-f flags] [-m mode] [-o owner] [-g group] [-l linkflags]\n"
file1 ... fileN directory\n\ " [-S stripflags] file1 file2\n"
install [-Up] [-M log] [-T tags] -d [-m mode]\n\ " %s [-Ubcprs] [-M log] [-T tags] [-B suffix] [-a afterinstallcmd]\n"
[-o owner] [-g group] directory ...\n"); " [-f flags] [-m mode] [-o owner] [-g group] [-l linkflags]\n"
" [-S stripflags] file1 ... fileN directory\n"
" %s -d [-Up] [-M log] [-T tags] [-a afterinstallcmd] [-m mode]\n"
" [-o owner] [-g group] directory ...\n",
prog, prog, prog);
exit(1); exit(1);
} }