[comp.sources.misc] An install

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