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