rsalz@pineapple.bbn.com (Richard Salz) (09/04/87)
[Try reading gobbledygook backwards. Someone doesn't like a certain
language... ++bsa]
I needed one of these for work. This is not derived from any licensed
software. It's too bad there's a SystemV version that has the same name
but totally different usage.
/r$
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Makefile README install.X install.c
# Wrapped by rsalz@pineapple.bbn.com on Wed Sep 2 12:58:15 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1776 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X##
X## Makefile for the install program.
X## This Makefile wants getopt(3) to be in your C library!
X## $Header:$
X##
X
X##
X## CONFIGURATION SECTION
X##
X## Do you have the snazzy/stupid <sys/wait.h>?
XD1 = -DSYS_WAIT=1
X## If you have vfork(2), use it.
XD2 = -DFORK=vfork
X#D2 = -DFORK=fork
X## If you #define this, we use our own exit() to avoid stdio crufties.
XD3 = -DEXIT=1
X#D3 = -UEXIT
X## Have "chown -f"?
XD4 = -DCHOWN_F_FLAG=1
X#D4 = -UCHOWN_F_FLAG
X## Have "chgrp -f" ?
XD5 = -DCHGRP_F_FLAG=1
X#D5 = -UCHGRP_F_FLAG
X## If you have to change this, something's really wrong.
XD6 = -DSTDERR=2
X## Differences in dialect, dialectical differences.
XD7 = -DIDX=index
X#D7 = -DIDX=strchr
X## Default owner of installed files.
XOWNER = root
X## Default group installed files should be placed in.
XGROUP = system
X## Change this to, e.g., -g, for debugging.
XOPT = -O
X## Where manpages get installed
XMANDIR = /usr/man/man1
X#MANDIR = /usr/man/u_man/man1
XMANEXT = .1
XMANPAGE = $(MANDIR)/install$(MANEXT)
X##
X## NOITCES NOITARUGIFNOC
X##
X
XD = $(D1) $(D2) $(D3) $(D4) $(D5) $(D6) $(D7)
XDEFS = $(D) -DDEF_OWNER=\"$(OWNER)\" -DDEF_GROUP=\"$(GROUP)\"
XCFLAGS = $(DEFS) $(OPT)
X
Xall: ./install install.man
X
Xinstall: all
X @echo This will install the programs... Do \"make all\" to compile
X @echo You have five seconds to interrupt.
X sleep 5
X ./install -o $(OWNER) -g $(GROUP) -m 555 -s install $(DESTDIR)
X ./install -o $(OWNER) -g $(GROUP) -m 444 -s install.man $(MANPAGE)
X
X
Xinstall.man: install.X Makefile
X @rm -f install.man
X sed -e "s/%OWNER%/$(OWNER)/" -e "s/%GROUP%/$(GROUP)/" \
X <install.X >install.man
X
X./install: install.c Makefile
X $(CC) $(CFLAGS) -o ./install install.c
X
Xlint: install.c
X lint -abhu $(DEFS) install.c >lint
X
Xclean:
X rm -f lint foo core tags a.out install install.man
END_OF_FILE
if test 1776 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(232 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
XThis is a public-domain implementation of the install(1) program,
Xsimilar to the one described in the BSD documentation.
X
XThere are about 10 configuration parameters you will have to edit.
XThey're all in the Makefile.
X
XEnjoy.
X /r$
END_OF_FILE
if test 232 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'install.X' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'install.X'\"
else
echo shar: Extracting \"'install.X'\" \(1413 characters\)
sed "s/^X//" >'install.X' <<'END_OF_FILE'
X.TH INSTALL 1 LOCAL
X.SH NAME
Xinstall \- install programs in (public) directories
X.SH SYNOPSIS
X.B install
X[
X.B \-c
X] [
X.B \-s
X] [
X.BI \-m mode
X] [
X.BI \-o owner
X] [
X.BI \-g group
X] file destination
X.SH DESCRIPTION
X.I Install
Xmoves or copies a file to a specified destination.
XIf
X.I destination
Xis a regular file, it will be removed before
X.I file
Xis installed in that name.
XIf
X.I destination
Xis a directory, then
X.I file
Xwill be installed in the directory with the same name.
X(This may cause problems, e.g., if
X.I file
Xis a full pathname.)
X.PP
XA number of options are provided:
X.TP
X.B \-c
XThe source is copied (with
X.IR cp (1))
Xrather than moved (with
X.IR mv (1)).
X.TP
X.B \-s
XThe symbol table is removed from the installed program (with
X.IR strip (1)).
X.TP
X.BI \-m mode
XThe permission bits of the installed program are set to the indicated
Xmode, rather than the default 0755.
X.TP
X.BI \-o owner
XThe specified user is made the owner of the program, rather than the default
X.IR %OWNER% .
X.TP
X.BI \-g group
XThe program is put in the specified group, rather than the default
X.IR %GROUP% .
X.PP
X.I Install
Xwill only install regular files, and tries not to copy a file onto itself.
X.PP
XThe changing of ownerships and file modes is done in the right order so
Xthat
X.RS
Xinstall \-m 4755 -o root a.out /bin/su
X.RE
Xsuffices to make a ``setuid root'' program.
X.SH "SEE ALSO"
Xchgrp(1), chmod(1), cp(1), mv(1), strip(1), chown(8)
END_OF_FILE
if test 1413 -ne `wc -c <'install.X'`; then
echo shar: \"'install.X'\" unpacked with wrong size!
fi
# end of 'install.X'
fi
if test -f 'install.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'install.c'\"
else
echo shar: Extracting \"'install.c'\" \(4225 characters\)
sed "s/^X//" >'install.c' <<'END_OF_FILE'
X/* $Revision:$
X** Install
X*/
X
X/*
X** Configuration section. This is all done in the Makefile.
X*/
X/* #define SYS_WAIT /* Have <sys/wait.h>? */
X/* #define FORK vfork /* If you have this use it... */
X/* #define FORK fork /* ...else use this */
X/* #define EXIT /* Needed to avoid stdio? */
X/* #define CHOWN_F_FLAG /* Have "chown -f"? */
X/* #define CHGRP_F_FLAG /* Have "chgrp -f"? */
X/* #define STDERR 2 /* Guess what this is */
X/* #define DEF_OWNER "root" /* Defalt owner of new files */
X/* #define DEF_GROUP "system" /* Default group for new files */
X
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef SYS_WAIT
X#include <sys/wait.h>
X#define WAITER union wait
X#else
X#define WAITER int
X#endif /* SYS_WAIT */
X
X
Xchar Source[BUFSIZ];
Xchar Destination[BUFSIZ];
Xchar *Pname;
X
Xchar *RMvec[] = {
X "/bin/rm", "-f", Destination, NULL
X};
X
Xchar *STRIPvec[] = {
X "/bin/strip", Destination, NULL
X};
X
Xchar *MOVEvec[] = {
X "/bin/mv", Source, Destination, NULL
X#define MV_CP MOVEvec[0]
X};
X
X
Xchar *CHMODvec[] = {
X "/bin/chmod", "755", Destination, NULL
X#define MODE CHMODvec[1]
X};
X
Xchar *CHOWNvec[] = {
X#ifdef CHOWN_F_FLAG
X "/etc/chown", "-f", DEF_OWNER, Destination, NULL
X#define OWNER CHOWNvec[2]
X#else
X "/etc/chown", DEF_OWNER, Destination, NULL
X#define OWNER CHOWNvec[1]
X#endif /* CHOWN_F_FLAG */
X};
X
Xchar *CHGRPvec[] = {
X#ifdef CHGRP_F_FLAG
X "/bin/chgrp", "-f", "system", Destination, NULL
X#define GROUP CHGRPvec[3]
X#else
X "/bin/chgrp", "system", Destination, NULL
X#define GROUP CHGRPvec[2]
X#endif /* CHGRP_F_FLAG */
X};
X
X/*
X** Externals.
X*/
Xextern char **environ;
Xextern char *optarg;
Xextern int optind;
Xextern char *IDX();
Xextern char *strcpy();
Xextern char *strcat();
X
X#ifdef lint
Xchar **environ;
Xchar *optarg;
Xint optind;
X#endif /* lint */
X
X
X
X#ifndef lint
X#ifdef EXIT
X/*
X** Avoid standard I/O crufties. Not needed on systems with a proper
X** C library.
X*/
Xexit(X)
X int X;
X{
X _exit(X);
X}
X#endif /* EXIT */
X#endif /* lint */
X
X
X/*
X** Print error message and die. No standard I/O.
X*/
Xvoid
XErr(s)
X char *s;
X{
X (void)write(STDERR, Pname, strlen(Pname));
X (void)write(STDERR, ": ", 3);
X (void)write(STDERR, s, strlen(s));
X (void)write(STDERR, ".\n", 2);
X exit(1);
X}
X
X
X/*
X** Spin off an argv[] command, and wait for it.
X*/
Xvoid
XDoit(av)
X char *av[];
X{
X WAITER W;
X int i;
X int j;
X
Xfor (i = 0; av[i]; i++) printf("%d. %s\n", i, av[i]);
X /* Spin until we can fork. */
X while ((i = FORK()) < 0) {
X perror("fork");
X (void)sleep(1);
X }
X
X /* Kid becomes the program. */
X if (i == 0) {
X execve(av[0], av, environ);
X perror(av[0]);
X _exit(1);
X }
X
X /* Parent waits for kid, and probably loops on error. */
X while ((j = wait(&W)) != i)
X if (j < 0)
X perror("wait");
X}
X
X
Xmain(ac, av)
X register int ac;
X register char *av[];
X{
X register int c;
X int Strip;
X struct stat Sb;
X
X Pname = (Pname = IDX(av[0], '/')) ? Pname + 1 : av[0];
X for (Strip = 0; (c = getopt(ac, av, "scm:o:g:")) != EOF; )
X switch (c) {
X case 's':
X Strip++;
X break;
X case 'c':
X MV_CP = "/bin/cp";
X break;
X case 'm':
X MODE = optarg;
X break;
X case 'o':
X OWNER = optarg;
X break;
X case 'g':
X GROUP = optarg;
X break;
X }
X
X /* Check number of files specified. */
X switch (ac -= optind) {
X case 1:
X Err("No destination specified");
X case 3:
X Err("Too many files specified");
X }
X av += optind;
X
X /* Is the source an existing, standard file? */
X if (stat(av[0], &Sb) < 0)
X Err("Source file doesn't exist");
X if ((Sb.st_mode & S_IFMT) != S_IFREG)
X Err("Source isn't a regular file");
X
X /* Is the destination the same as the source? */
X if (strcmp(av[0], av[1]) == 0 || strcmp(av[1], ".") == 0)
X Err("Can't move file onto itself");
X (void)strcpy(Source, av[0]);
X
X /* If the destination is a directory, make a file. */
X if (stat(av[1], &Sb) >= 0 && (Sb.st_mode & S_IFMT) == S_IFDIR)
X (void)strcat(strcat(strcpy(Destination, av[0]), "/"), av[1]);
X else
X (void)strcpy(Destination, av[1]);
X
X Doit(RMvec);
X Doit(MOVEvec);
X if (Strip)
X Doit(STRIPvec);
X Doit(CHOWNvec);
X Doit(CHGRPvec);
X Doit(CHMODvec);
X
X exit(0);
X}
END_OF_FILE
if test 4225 -ne `wc -c <'install.c'`; then
echo shar: \"'install.c'\" unpacked with wrong size!
fi
# end of 'install.c'
fi
echo shar: End of shell archive.
exit wr