[comp.sources.unix] v24i068: Purdue software product installation system, Part06/07

rsalz@uunet.uu.net (Rich Salz) (03/21/91)

Submitted-by: Kevin Braunsdorf <ksb@cc.purdue.edu>
Posting-number: Volume 24, Issue 68
Archive-name: pucc-install/part06

#!/bin/sh
# This is part 06 of pucc-1b
# ============= purge/filedup.c ==============
if test ! -d 'purge'; then
    echo 'x - creating directory purge'
    mkdir 'purge'
fi
if test -f 'purge/filedup.c' -a X"$1" != X"-c"; then
	echo 'x - skipping purge/filedup.c (File already exists)'
else
echo 'x - extracting purge/filedup.c (Text)'
sed 's/^X//' << 'Purdue' > 'purge/filedup.c' &&
/*
X * $Id: filedup.c,v 3.0 90/09/17 11:38:20 ksb Exp $
X * keep track of unique inode/dev pairs for me				(ksb)
X */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
X
extern char *sys_errlist[];
#define strerror(Me) (sys_errlist[Me])
extern int errno;
X
#include "filedup.h"
X
static AVL *AVpAVInsert = nilAV;	/* used by AVInsert & AVVerify()*/
static AE_ELEMENT *AVpAEInsert = nilAE;
static struct stat *AEpstCur;
static char *AEpcName;
X
static void
AEInit(pAE)
AE_ELEMENT *pAE;
{
X	extern char *malloc(), *strcpy();
X	pAE->mydev = AEpstCur->st_dev;
X	pAE->myino = AEpstCur->st_ino;
X	pAE->pcname = strcpy(malloc(strlen(AEpcName)+1),AEpcName);
}
X
static int
AECmp(pAE)
AE_ELEMENT *pAE;
{
X	register int cmp;
X	if (0 == (cmp = pAE->mydev - AEpstCur->st_dev)) {
X		if (0 == (cmp = pAE->myino - AEpstCur->st_ino)) {
X			return 0;
X		}
X	}
X	return cmp;
}
X
/*
X * make an AVL tree empty						(ksb)
X *
X * in most code "AVL *pAVRoot = nilAV;" is better than calling this routine
X */
void
AVInit(ppAV)
AVL **ppAV;
{
X	*ppAV = nilAV;
}
X
/*
X * Fix an AVL tree node that is in violation of the rules		(dsg)
X * calls look like:
X *     AV_rotate(ppAVRoot, AV_LCHILD)
X *     AV_rotate(ppAVRoot, AV_RCHILD)
X * to fix nodes that are left tipped, and right tipped respectivly
X *
X * return
X *	1: if the tree is shorter after the rotate (always true for insert)
X *	0: if same depth
X */
static int
AV_rotate(ppAVRoot, fSide)
AVL **ppAVRoot;
register int fSide;
{
X	register AVL *pAVCopy, *pAVFirst, *pAVSecond;
X	register int fOther;
X
X	pAVCopy = *ppAVRoot;
X	pAVFirst = pAVCopy->AVsbpAVchild[fSide];
X
X	fOther = 1^fSide;
X						/* Three point rotate	*/
X	if (fSide == pAVFirst->AVbtipped) {
X		pAVCopy->AVbtipped = AV_BAL_CENTER;
X		pAVFirst->AVbtipped = AV_BAL_CENTER;
X
X		*ppAVRoot = pAVFirst;
X		pAVCopy->AVsbpAVchild[fSide] = pAVFirst->AVsbpAVchild[fOther];
X		pAVFirst->AVsbpAVchild[fOther] = pAVCopy;
X
X						/* Five point rotate	*/
X	} else if (AV_BAL_CENTER != pAVFirst->AVbtipped) {
X		pAVSecond = pAVFirst->AVsbpAVchild[fOther];
X
X		if (AV_BAL_CENTER == pAVSecond->AVbtipped) {
X			pAVCopy->AVbtipped = AV_BAL_CENTER;
X			pAVFirst->AVbtipped = AV_BAL_CENTER;
X		} else if (fSide == pAVSecond->AVbtipped) {
X			pAVCopy->AVbtipped = fOther;
X			pAVFirst->AVbtipped = AV_BAL_CENTER;
X		} else {
X			pAVCopy->AVbtipped = AV_BAL_CENTER;
X			pAVFirst->AVbtipped = fSide;
X		}
X		pAVSecond->AVbtipped = AV_BAL_CENTER;
X		*ppAVRoot = pAVFirst->AVsbpAVchild[fOther];
X		pAVFirst->AVsbpAVchild[fOther] = pAVSecond->AVsbpAVchild[fSide];
X		pAVSecond->AVsbpAVchild[fSide] = pAVCopy->AVsbpAVchild[fSide];
X		pAVCopy->AVsbpAVchild[fSide] = pAVSecond->AVsbpAVchild[fOther];
X		pAVSecond->AVsbpAVchild[fOther] = pAVCopy;
X
X	/*
X	 * Insert: we shouldn't be here
X	 * Delete: a 3-point or a 5-point rotate works here, so we
X	 * choose the less expensive one.  Also, this is the case
X	 * where the balance factors come out skewed, and the tree
X	 * doesn't shrink.
X	 */
X	} else {
X		pAVCopy->AVbtipped = fSide;
X		pAVFirst->AVbtipped = fOther;
X
X		*ppAVRoot = pAVFirst;
X		pAVCopy->AVsbpAVchild[fSide] = pAVFirst->AVsbpAVchild[fOther];
X		pAVFirst->AVsbpAVchild[fOther] = pAVCopy;
X
X		return 0;
X	}
X	return 1;
}
X
/*
X * find a node keyed on AVpAEInsert -- set AVpAVInsert to inserted	(dsg)
X * element if fAdd
X *
X * calling sequence:
X *	{ AECmp must know the "current key now" }
X *	AVInsert(& pAVRoot, fAdd);
X *
X * result:
X *	AVpAVInsert is inserted element (don't touch!)
X *	AVpAEInsert points to user data in the record
X *
X * returns:
X *	true if tree became deeper
X */
static int
AVInsert(ppAVRoot, fAdd)
AVL **ppAVRoot;
int fAdd;
{
X	extern char *malloc();
X	register AVL *pAVCopy;
X	auto int fCmp;
X
X	pAVCopy = *ppAVRoot;
X	if (nilAV == pAVCopy) {
X		if (fAdd) {
X			AVpAVInsert = *ppAVRoot = (AVL *)malloc(sizeof(AVL));
X			AVpAVInsert->AVbtipped = AV_BAL_CENTER;
X			AVpAVInsert->AVsbpAVchild[AV_LCHILD] = nilAV;
X			AVpAVInsert->AVsbpAVchild[AV_RCHILD] = nilAV;
X			AVpAEInsert = & AVpAVInsert->AE_data;
X			AEInit(AVpAEInsert);
X			return 1;
X		}
X		AVpAEInsert = nilAE;
X		AVpAVInsert = nilAV;
X	} else if (0 == (fCmp = AECmp(& pAVCopy->AE_data))) {
X		AVpAVInsert = pAVCopy;
X		AVpAEInsert = & AVpAVInsert->AE_data;
X	} else if (fCmp < 0) {
X		if (AVInsert(& pAVCopy->AVsbpAVchild[AV_LCHILD], fAdd)) {
X			switch (pAVCopy->AVbtipped) {
X			case AV_BAL_LEFT:
X				(void)AV_rotate(ppAVRoot, AV_LCHILD);
X				break;
X			case AV_BAL_CENTER:
X				pAVCopy->AVbtipped = AV_BAL_LEFT;
X				return 1;
X			case AV_BAL_RIGHT:
X				pAVCopy->AVbtipped = AV_BAL_CENTER;
X				break;
X			}
X		}
X	} else if (AVInsert(& pAVCopy->AVsbpAVchild[AV_RCHILD], fAdd)) {
X		switch (pAVCopy->AVbtipped) {
X		case AV_BAL_RIGHT:
X			(void)AV_rotate(ppAVRoot, AV_RCHILD);
X			break;
X		case AV_BAL_CENTER:
X			pAVCopy->AVbtipped = AV_BAL_RIGHT;
X			return 1;
X		case AV_BAL_LEFT:
X			pAVCopy->AVbtipped = AV_BAL_CENTER;
X			break;
X		}
X	}
X	return 0;
}
X
#if 0
/*
X * a prototype function for AVScan					(ksb)
X */
int
AV_prototype(pAE)
AE_ELEMENT *pAE;
{
X	/* bar(pAE->foo); */
X	return 0;		/* compatible with MICE			*/
}
#endif /* example */
X
/*
X * scan an avl tree inorder calling pFunc with each each node		(ksb)
X *
X * the function passed should return non-zero for stop (MICE)
X */
int
AVScan(pAVRoot, pFunc)
AVL *pAVRoot;
int (*pFunc)();			/* prototype AV_prototype		*/
{
X	register int r;
X
X	while (nilAV != pAVRoot) {
X		if (0 != (r = AVScan(pAVRoot->AVsbpAVchild[AV_LCHILD], pFunc)))
X			return r;
X		if (0 != (r = (*pFunc)(& pAVRoot->AE_data)))
X			return r;
X		pAVRoot = pAVRoot->AVsbpAVchild[AV_RCHILD];
X	}
X	return 0;
}
X
X
#if 0
/*
X * return name for this node in tree					(ksb)
X */
char *
FDName(ppAV, pst)
AVL **ppAV;
struct stat *pst;
{
X	/* see if it was the last one we found
X	 */
X	if (nilAE != AVpAEInsert && pst->st_ino == AVpAEInsert->myino &&
X	     pst->st_dev == AVpAEInsert->mydev)
X		return AVpAEInsert->pcname;
X
X	AEpstCur = pst;
X	(void)AVInsert(ppAV, 0);
X	AEpstCur = (struct stat *)0;
X
X	if (nilAE != AVpAEInsert)
X		return AVpAEInsert->pcname;
X	return (char *)0;
}
#endif
X
/*
X * return name that is in tree						(ksb)
X */
char *
FDAdd(ppAV, pcName, pst)
AVL **ppAV;
struct stat *pst;
char *pcName;
{
X	AEpstCur = pst;
X	AEpcName = pcName;
X	(void)AVInsert(ppAV, 1);
X	AEpcName = (char *)0;
X	AEpstCur = (struct stat *)0;
X	return AVpAEInsert->pcname;
}
X
#if TEST
char *progname = "frtest";
X
int
main(argc, argv)
int argc;
char **argv;
{
X	auto char acFile[MAXPATHLEN+2];
X	auto struct stat stBuf;
X	register char *pcEnd;
X	auto AVL *pAV;
X	extern char *strchr();
X
X	AVInit(& pAV);
X
X	while ((char *)0 != fgets(acFile, MAXPATHLEN+1, stdin)) {
X		if ((char *)0 == (pcEnd = strchr(acFile, '\n'))) {
X			fprintf(stderr, "%s: name too long\n", progname);
X			exit(1);
X		}
X		*pcEnd = '\000';
X		if (-1 == lstat(acFile, &stBuf)) {
X			fprintf(stderr, "%s: stat: %s: %s\n", progname, acFile, strerror(errno));
X			continue;
X		}
X		printf("%s %s\n", acFile, FDAdd(&pAV, acFile, &stBuf));
X	}
X	exit(0);
}
#endif
Purdue
chmod 0444 purge/filedup.c ||
echo 'restore of purge/filedup.c failed'
Wc_c="`wc -c < 'purge/filedup.c'`"
test 6893 -eq "$Wc_c" ||
	echo 'purge/filedup.c: original size 6893, current size' "$Wc_c"
fi
# ============= install.d/install.h ==============
if test ! -d 'install.d'; then
    echo 'x - creating directory install.d'
    mkdir 'install.d'
fi
if test -f 'install.d/install.h' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/install.h (File already exists)'
else
echo 'x - extracting install.d/install.h (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/install.h' &&
/*
X * $Id: install.h,v 7.1 90/09/17 10:34:16 ksb Exp $
X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
/*
X * all the externs and positioning for install				(ksb)
X */
#define PATCH_LEVEL	0
X
#if defined(SYSV) || defined(HPUX7)
X
#include <sys/signal.h>
#include <sys/fcntl.h>
#include <string.h>
X
#if !defined(MAXPATHLEN)
#define MAXPATHLEN	256
#endif	/* already defined by someone		*/
#define vfork	fork		/* no vfork				*/
extern struct group *getgrent(), *getgrgid(), *getgrnam();
extern struct passwd *getpwent(), *getpwuid(), *getpwnam();
X
#else	/* BSD					*/
X
#include <fcntl.h>
#include <strings.h>
X
#define strchr	index
#define strrchr	rindex
X
#if defined(pdp11)
#include <wait.h>
#else	/* bsd 4.?				*/
#include <sys/wait.h>
#endif	/* bsd 2.?				*/
X
#endif	/* system 5				*/
X
#if defined(DYNIX)
#include <sys/universe.h>
#endif	/* universe stuff for symlinks		*/
X
extern int errno;		/* for perror(3)			*/
extern char *sys_errlist[];
#define strerror(Me)	(sys_errlist[Me])
X
#if !HAVE_ACCTTYPES
#define	uid_t int
#define gid_t int
#endif	/* find a uid/gid type			*/
X
#if defined(HAVE_SLINKS) ? HAVE_SLINKS : defined(S_IFLNK)
X
#define LSTAT	lstat
#if !defined(HAVE_SLINKS)
#define HAVE_SLINKS	1
#endif
X
#if !defined(SLINKOK)
#define SLINKOK		FALSE	/* allow src to be a symlink?		*/
#endif	/* default source links to not allow	*/
X
#if !defined(DLINKOK)
#define DLINKOK		FALSE	/* allow dst to be a symlink?		*/
#endif	/* default destination links to not allow */
X
#else	/* we don't need to worry about lstat	*/
X
#define LSTAT	stat
#if !defined(HAVE_SLINKS)
#define HAVE_SLINKS	0
#endif
#endif	/* if we have symlink preserving stat	*/
X
X
/* a crutch or two
X */
#define EQUAL(s1,s2)	(0==strcmp(s1,s2))
#define MAXTRIES	16		/* retrys on mktemp clashes	*/
#define	PATMKTEMP	"XXXXXX"	/* tack this on for mktemp(3)	*/
#define TRUE		(1)		/* you know, boolean like	*/
#define FALSE		(0)		/* you know, boolean like	*/
#define SUCCEED		(1)		/* our internal success code	*/
#define FAIL		(-1)		/* our internal failure code	*/
#define EXIT_FSYS	0x40		/* failed system call		*/
#define EXIT_OPT	0x41		/* bad option or data		*/
#define EXIT_INTER	0x42		/* internal error		*/
X
#define PERM_RWX(x)	((x) & 0777)
#define PERM_BITS(x)	((x) & 07777)
#define SAFEMASK	(~(S_ISUID|S_ISGID|S_ISVTX))
X
X
/*
X * defaults that the installer gets if here doesn't -D define them
X */
#if defined(INHERIT_OK)
X
/* in this case we will copy modes whenever we get a chance,
X * (we use a (char*)0 to record `inherit').
X */
#if !defined(DEFOWNER)
#define DEFOWNER	(char *)0	/* files are all inherit owner	*/
#endif	/* might not want to use this; old UNIX?*/
X
#if !defined(DEFGROUP)
#define DEFGROUP	(char *)0	/* inherit group owner of file	*/
#endif	/* any local should be set in Makefile	*/
X
#if !defined(DEFMODE)
#define DEFMODE		(char *)0	/* file installation mode	*/
#endif	/* all other files			*/
X
#if !defined(DEFDIROWNER)
#define DEFDIROWNER	(char *)0	/* dirs inherit owner		*/
#endif	/* might not want to use this; old UNIX?*/
X
#if !defined(DEFDIRGROUP)
#define DEFDIRGROUP	(char *)0	/* inherit group owner of dirs	*/
#endif	/* any local should be set in Makefile	*/
X
#if !defined(DEFDIRMODE)
#define DEFDIRMODE	(char *)0	/* inherit directory mode	*/
#endif	/* all dirs can be read by default	*/
X
#if !defined(ODIROWNER)
#define ODIROWNER	(char *)0
#endif	/* default backup dir owner		*/
X
#if !defined(ODIRGROUP)
#define ODIRGROUP	(char *)0
#endif	/* default backup dir group		*/
X
#if !defined(ODIRMODE)
#define ODIRMODE	(char *)0
#endif	/* default backup dir mode		*/
X
#else
X
/*
X * otherwise we want to set all these default modes here...
X */
X
#if !defined(DEFOWNER)
#define DEFOWNER	"root"		/* files are all root owned	*/
#endif	/* might not want to use this; old UNIX?*/
X
#if !defined(DEFGROUP)
#define DEFGROUP	"binary"	/* group owner of files		*/
#endif	/* any local should be set in Makefile	*/
X
#if !defined(DEFMODE)
#define DEFMODE		"0755"		/* file installation mode	*/
#endif	/* all other files			*/
X
#if !defined(DEFDIROWNER)
#define DEFDIROWNER	DEFOWNER	/* dirs are all root owned	*/
#endif	/* might not want to use this; old UNIX?*/
X
#if !defined(DEFDIRGROUP)
#define DEFDIRGROUP	DEFGROUP	/* group owner of dirs		*/
#endif	/* any local should be set in Makefile	*/
X
#if !defined(DEFDIRMODE)
#define DEFDIRMODE	"0755"		/* directory installation mode	*/
#endif	/* all dirs can be read by default	*/
X
#if !defined(ODIROWNER)
#define ODIROWNER	DEFDIROWNER
#endif	/* default backup dir owner		*/
X
#if !defined(ODIRGROUP)
#define ODIRGROUP	DEFDIRGROUP
#endif	/* default backup dir group		*/
X
#if !defined(ODIRMODE)
#define ODIRMODE	DEFDIRMODE
#endif	/* default backup dir mode		*/
X
#endif	/* must never inherit modes		*/
X
X
#if !defined(OLDDIR)
#define OLDDIR		"OLD"
#endif	/* default backup directory name	*/
X
#if !defined(TMPINST)
#define TMPINST		"#instXXXXXX"
#endif	/* mktemp to get source on same device	*/
X
#if !defined(TMPBOGUS)
#define TMPBOGUS	"#bogusXXXXXX"
#endif	/* last link to a running binary wedge	*/
X
#if defined(INST_FACILITY)
#include <syslog.h>
#if !defined(MAXLOGLINE)
#define MAXLOGLINE	256
#endif	/* sprintf buffer size for syslog	*/
#endif	/* syslog changes to the system		*/
X
#if !defined(BLKSIZ)
#define BLKSIZ		8192	/* default blocksize for DoCopy()	*/
#endif	/* maybe not big enough			*/
Purdue
chmod 0444 install.d/install.h ||
echo 'restore of install.d/install.h failed'
Wc_c="`wc -c < 'install.d/install.h'`"
test 6261 -eq "$Wc_c" ||
	echo 'install.d/install.h: original size 6261, current size' "$Wc_c"
fi
# ============= install.d/configure.h ==============
if test -f 'install.d/configure.h' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/configure.h (File already exists)'
else
echo 'x - extracting install.d/configure.h (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/configure.h' &&
/*
X * $Id: configure.h,v 7.5 90/10/08 11:42:13 ksb Exp $
X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
/* install includes this file for the system admin to #define things
X * she wants to change from the default values.  Read the descriptions
X * in the install source code (lines 150-250) and #define them here
X * to the local values.
X *
X * Some other major feature can be activated here.
X */
X
/* some machines define one of these in /usr/include/sys/param.h
X * if so you do not need it here...
X */
/* #define SYSV /**/
/* #define bsd /**/
/* #define DYNIX /**/
/* #define HPUX7 /**/
/* #define sun /**/
X
/* if we still don't know the platform look for other clues
X */
#if !defined(bsd) && !defined(SYSV) && !defined(DYNIX) && !defined(HPUX7)
X
#if defined(BSD)
#define bsd 1
#else
#if defined(dynix)
#define DYNIX 1
#endif /* try dynix */
#endif /* try bsd */
X
#endif /* still do not know */
X
/* DYNIX looks enough like bsd for this to be true
X */
#if defined(DYNIX) && !defined(bsd)
#define bsd
#endif
X
X
/* Some sysV machines have getwd, some getcwd, some none
X * If you do not have one, get one.
X * (maybe popen a /bin/pwd and read it into the buffer?)
X */
#if defined(SYSV) || defined(HPUX7)
#define getwd(Mp) getcwd(Mp,MAXPATHLEN)	/* return pwd		*/
extern char *getcwd();
#else
extern char *getwd();
#endif
X
X
/* the macros {DEF,DEFDIR,ODIR}{MODE,GROUP,OWNER}
X * provide the default modes for any new files installed on the system
X * a value in "quotes" will force that value, a nil pointer will
X * force the value to be inherited from the parrent directory.
X *
X * The ones you do not set will be extrapolated from the others,
X * start with DEFMODE as the default mode for a file, DEFDIRMODE
X * as the defualt directory mode for all directories, and ODIRMODE
X * as the mode for building OLD directories.
X */
/* #define DEFGROUP	"daemon"	/* ls -lg /bin/ls for a guess	*/
/* #define ODIROWNER	"charon"	/* safe login for purge to use	*/
#define ODIRGROUP	((char *)0)	/* inherit group so mode works	*/
#define ODIRMODE	((char *)0)	/* inherit the OLD dir mode	*/
X
X
/* this option allows all the binaries in a directory to
X * get their default owner/group/mode from the directory
X * (rather then hard coded defaults)
X * This has the drawback that errors are propogated as well!
X */
/* #define INHERIT_OK			/* propogate modes down tree	*/
X
X
/* should the user be able to install a file on top of a symbolic link?
X */
/* #define DLINKOK	TRUE		/* yes, back it up		*/
X
X
/* should the user be able to use a symbolic link as a source file?
X */
/* #define SLINKOK	TRUE		/* yes, copy as a plain file	*/
X
X
/* if we have ansi C prototypes (cannot depend on __STDC__, sorry)
X */
#define HAVE_PROTO	0
X
X
/* do we have an mkdir(2) system call?
X */
#if defined(pdp11) || defined(SYSV)
#define HAVE_MKDIR	0
#else
#define HAVE_MKDIR	1
#endif
X
X
/* do we have to run a ranlib command on *.a files (-l)
X */
#if defined(SYSV) || defined(HPUX7)
#define HAVE_RANLIB	0
#else
#define HAVE_RANLIB	1
#endif
X
/* here you may #define alternate paths to some programs
X * BIN{CHGRP,LS,MKDIR,RANLIB,STRIP}
X */
/* #define BINRANLIB	"/usr/gnu/ranlib"		/**/
X
X
/* here you may set the flags used when we (under -v) run ls on a file
X * or directory
X * LS{,DIR}ARGS
X */
/* #define LSARGS	"-lsg"			/**/
X
X
/* which file to include <strings.h> or <string.h> {STRINGS=1, STRING=0}
X */
#define STRINGS		defined(bsd)
X
X
/* do we have scandir,readdir and friends in <sys/dir.h>, else look for
X * <ndir.h>
X */
#define BSDDIR		defined(bsd)||defined(sun)
X
X
/* do we have accounting type (uid_t, gid_t)?  (default to int)
X */
#if defined(pdp11) || defined(DYNIX) || defined(SYSV) || defined(sun)
#define HAVE_ACCTTYPES	0
#else
#define HAVE_ACCTTYPES	1
#endif
X
X
/* do we have a kernel quota system?  (bsd like)
X * (if so savepwent has to copy a quota struct)
X */
#if defined(bsd)
#define HAVE_QUOTA	1
#else
#define HAVE_QUOTA	0
#endif
X
X
/* if your chmod(2) will not drop setgid bits on a dir with `chmod 755 dir`
X * you need to define BROKEN_CHMOD (Suns have this problem -- yucko!)
X * See SunBotch() in instck.c for more flamage.
X */
#define BROKEN_CHMOD	defined(sun)
X
X
/* instck needs to know the name of the magic number field in a
X * (struct exec) in <a.out.h>, and some other stuff
X */
#if defined(HPUX7)
#define MNUMBER		a_magic.file_type
#define MSYMS		a_lesyms
#define EXHDR		struct exec
#else
#if defined(bsd)||defined(sun)
#define MNUMBER		a_magic		/* magic number			*/
#define MSYMS		a_syms		/* number of symbols (strip)	*/
#define EXHDR		struct exec	/* type of this struct		*/
#else
#if defined(eta)
#define MNUMBER		f_magic
#define MSYMS		f_nsyms
#define EXHDR		struct filehdr
#else /* SYSV? */
#define MNUMBER		a_info
#define MSYMS		a_syms
#define EXHDR		struct exec
#endif
#endif
#endif
X
X
/* CONFIG controls the code to consult a checklist of special files.
X * Set CONFIG to "", or (char *)0, for other effects.
X * By #define'ing a checklist file you enable the code for it.
X */
#define CONFIG "/usr/local/etc/install.cf"	/* check list, and code	*/
/* #define CONFIG ""				/* no list, but code	*/
/* #undef CONFIG				/* no check or code	*/
X
X
/* INST_FACILITY controls installation syslogging.
X * (LOG_LOCAL2 was the first local slot we had a PUCC)
X * To enable installation syslog'ing uncomment the #define below.
X */
#if defined(bsd) || defined(HPUX7)
X
#if BSD > 42 || defined(HPUX7)
#define INST_FACILITY LOG_LOCAL2 	/* our 4.3 log facility		*/
#else
#define INST_FACILITY LOG_INFO 		/* our 4.2 log facility		*/
#endif
X
#else /* not bsd, not dynix */
X
#if defined(eta10)
#define INST_FACILITY LOG_LOCAL2 	/* eta10 uses 4.3 log facility	*/
#else	/* assume no logging here */
#undef INST_FACILITY			/* we do not log changes	*/
#endif
X
#endif 
Purdue
chmod 0644 install.d/configure.h ||
echo 'restore of install.d/configure.h failed'
Wc_c="`wc -c < 'install.d/configure.h'`"
test 6676 -eq "$Wc_c" ||
	echo 'install.d/configure.h: original size 6676, current size' "$Wc_c"
fi
# ============= instck/instck.1l ==============
if test ! -d 'instck'; then
    echo 'x - creating directory instck'
    mkdir 'instck'
fi
if test -f 'instck/instck.1l' -a X"$1" != X"-c"; then
	echo 'x - skipping instck/instck.1l (File already exists)'
else
echo 'x - extracting instck/instck.1l (Text)'
sed 's/^X//' << 'Purdue' > 'instck/instck.1l' &&
.\" Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
.\" 47907.  All rights reserved.
.\"
.\" Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
.\"	       Jeff Smith, jsmith@cc.purdue.edu, purdue!jsmith
.\"
.\" This software is not subject to any license of the American Telephone
.\" and Telegraph Company or the Regents of the University of California.
.\"
.\" Permission is granted to anyone to use this software for any purpose on
.\" any computer system, and to alter it and redistribute it freely, subject
.\" to the following restrictions:
.\"
.\" 1. Neither the authors nor Purdue University are responsible for any
.\"    consequences of the use of this software.
.\"
.\" 2. The origin of this software must not be misrepresented, either by
.\"    explicit claim or by omission.  Credit to the authors and Purdue
.\"    University must appear in documentation and sources.
.\"
.\" 3. Altered versions must be plainly marked as such, and must not be
.\"    misrepresented as being the original software.
.\"
.\" 4. This notice may not be removed or altered.
.\"
.\" $Laser: ${tbl-tbl} %f | ${ltroff-ltroff} -man
.\" $Compile: ${tbl-tbl} %f | ${nroff-nroff} -man | ${PAGER-${more-more}}
.TH INSTCK 1L PUCC
.SH NAME
instck \- look for improperly installed files
.SH SYNOPSIS
\fBinstck\fP [\fB\-dilSv\fP] [\fB\-C\fP\fIchecklist\fP] [\fB\-g\fP\fIgroup\fP] [\fB\-m\fP\fImode\fP] [\fB\-o\fP\fIowner\fP] \fIdirectories\fP
.br
\fBinstck\fP [\fB\-G\fP] [\fB\-dl\fP] \fIdirectories\fP
.br
\fBinstck\fP [\fB\-hV\fP]
.SH DESCRIPTION
.PP
.I Instck
reads a system \fIchecklist\fP for a list of correct modes for
installed files.
It scans the file systems for incorrect owners, groups, modes etc.
.PP
For instance, if the shell were installed setuid root via:
.br
X	install \-m7555 \-o root \-g wheel sh /bin
.br
(note the extra \`5\') instck might find it.
.PP
If the given \fIdirectories\fP end with \*(lqOLD\*(rq they are
only searched for half installed files and insecure backup modes.
Patterns read from the \fIchecklist\fP which do not start with
a slash (`/') are examined from the remaining \fIdirectories\fP.
.PP
.I Instck
prompts stdin with suggested repairs under the \fB\-i\fP option.
.SH OPTIONS
.TP
.BI \-C checklist
Search \fIchecklist\fP for the expressions to match the
installed files (see \fIinstall.cf\fP(5L).
.TP
.B \-d
Do not check the contents of a directory, as in \fIls\fP(1).
.TP
.BI \-g group
Set the default group for installed files.
.TP
.B \-G
This option will generate a checklist file for the given directories.
Such a file may have to be edited to be useful.
.TP
.B \-h
Print a summary of \fIinstck\fP's usage.
.TP
.B \-i
Prompt the user with suggested shell commands, for example if /tmp was
the wrong mode \fIinstck\fP might prompt with:
.sp 1
X	instck: `/tmp' mode 0777 doesn't have bits to match drwxrwxrwt (1777)
.br
X	instck: chmod 1777 /tmp [nfhqy]
.sp 1
A reply of `y' or `Y' will run the proposed command, `f' will skip to
the next file.
.TP
.B \-l
A long list will be made of all the files that didn't match any rule.
Under \-\fBG\fP all files will be put in the checklist.
.TP
.BI \-m mode
Set the default mode for installed files.
.TP
.BI \-o owner
Set the default owner for installed files.
.TP
.B \-S
Run as if geteuid() returned zero.
.TP
.B \-v
Be more verbose.
.TP
.B \-V
Give version information.
.SH EXAMPLES
.TP
instck /bin /usr/bin /usr/ucb /usr/local/bin /etc
report inconsistent installations in the listed directories.
.TP
instck \-v /etc
report inconsistent installations in /etc, be very verbose.
.TP
instck \-G /bin
generate a checklist for /bin and all the files in /bin.
.TP
instck \-V
Report version information, e.g.
.br
.RS
.TS
l s s
l s s
l l l.
instck: version: $\&Id: main.c,v 6.0 90/03/08 15:34:49 ksb Exp $
instck: configuration file: /usr/local/etc/install.cf
instck: defaults: owner=root	group=binary	mode=\-rwxr\-xr\-x
.TE
.RE
.SH FILES
.TS
l l.
/usr/local/lib/instck.cf	the default \fIchecklist\fP file
.TE
.SH AUTHOR
Kevin Braunsdorf, Purdue University Computing Center (ksb@cc.purdue.edu)
.br
Copyright \*(co 1990 Purdue Research Foundation.  All rights reserved.
.SH SEE ALSO
ls(1), chown(8), chgrp(1), chmod(1), install(1), ranlib(1), strip(1),
geteuid(2),
syslog(3), install.cf(5L)
Purdue
chmod 0444 instck/instck.1l ||
echo 'restore of instck/instck.1l failed'
Wc_c="`wc -c < 'instck/instck.1l'`"
test 4281 -eq "$Wc_c" ||
	echo 'instck/instck.1l: original size 4281, current size' "$Wc_c"
fi
# ============= instck/path.c ==============
if test -f 'instck/path.c' -a X"$1" != X"-c"; then
	echo 'x - skipping instck/path.c (File already exists)'
else
echo 'x - extracting instck/path.c (Text)'
sed 's/^X//' << 'Purdue' > 'instck/path.c' &&
/*
X * $Id: path.c,v 7.1 90/09/17 10:25:42 ksb Exp $
X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
/*
X * routines to keep track of many files in a UNIX file system		(ksb)
X */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
X
#include "configure.h"
#include "install.h"
#include "main.h"
#include "special.h"
#include "instck.h"
#include "path.h"
X
#if STRINGS
#include <strings.h>
#else
#include <string.h>
#endif
X
extern char *malloc();
X
int chSep = '/';
X
static int (*pFunc)();
static char acBuffer[MAXPATHLEN];
X
static int
RecurPath(pCM, pch)
COMPONENT *pCM;
char *pch;
{
X	register int i;
X
X	if (nilCM == pCM) {
X		return 0;
X	}
X	for (*pch++ = chSep; (COMPONENT *)0 != pCM; pCM = pCM->pCMsibling) {
X		(void)strcpy(pch, pCM->pccomp);
X		if (pCM->fprint)
X			(*pFunc)(acBuffer, & pCM->user_data);
X		i = RecurPath(pCM->pCMchild, strchr(pch, '\000'));
X		if (0 != i) {
X			break;
X		}
X	}
X	return i;
}
X
int
ApplyPath(pCM, l_func)
COMPONENT *pCM;
int (*l_func)();
{
X	auto int (*temp)();
X	auto int i;
X
X	temp = pFunc;
X	if (nilCM != pCM) {
X		pFunc = l_func;
X		i = RecurPath(pCM, acBuffer);
X	}
X	pFunc = temp;
X	return i;
}
X
/*
X * add a (unique) path element
X *	AddPath(& pCMPath, "/usr/local/bin/foo");
X *
X * does a lot of unneded work some times, but a good hack at 2:30 am
X */
PATH_DATA *
AddPath(ppCM, pch)
COMPONENT **ppCM;
char *pch;
{
X	static char acEnd[] = "\000";
X	register char *pchTemp;
X	register COMPONENT *pCM = nilCM;
X
X	while ('\000' != *pch) {
X		while (chSep == *pch) {		/* /a//b		*/
X			++pch;
X		}
X
X		if ((char *)0 == (pchTemp = strchr(pch, chSep))) {
X			pchTemp = acEnd;
X		} else {
X			*pchTemp = '\000';
X		}
X		while (nilCM != (pCM = *ppCM)) {	/* level match	  */
X			if (0 == strcmp(pCM->pccomp, pch)) {
X				if ('\000' == pchTemp[1]) {
X					/* break 2 ! */
X					goto escape;
X				}
X				goto contin;
X			}
X			ppCM = & pCM->pCMsibling;
X		}
X
X		/* not at this level, add it at end
X		 */
X		pCM = newCM();
X		pCM->pCMsibling = nilCM;
X		pCM->pCMchild = nilCM;
X		pCM->pccomp = malloc((strlen(pch)|7)+1);
X		PUInit(& pCM->user_data);
X		(void)strcpy(pCM->pccomp, pch);
X		pCM->fprint = 0;
X		*ppCM = pCM;
X
X	contin:
X		*pchTemp++ = chSep;
X		pch = pchTemp;
X		ppCM = & pCM->pCMchild;
X	}
escape:
X	if (nilCM != pCM)
X		pCM->fprint = 1;
X	return (nilCM != pCM) ? & pCM->user_data : (PATH_DATA *)0;
}
Purdue
chmod 0444 instck/path.c ||
echo 'restore of instck/path.c failed'
Wc_c="`wc -c < 'instck/path.c'`"
test 3262 -eq "$Wc_c" ||
	echo 'instck/path.c: original size 3262, current size' "$Wc_c"
fi
# ============= install.d/Makefile ==============
if test -f 'install.d/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/Makefile (File already exists)'
else
echo 'x - extracting install.d/Makefile (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/Makefile' &&
# Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
# 47907.  All rights reserved.
#
# Written by Jeff Smith, jsmith@cc.purdue.edu, purdue!jsmith
#
# This software is not subject to any license of the American Telephone
# and Telegraph Company or the Regents of the University of California.
#
# Permission is granted to anyone to use this software for any purpose on
# any computer system, and to alter it and redistribute it freely, subject
# to the following restrictions:
#
# 1. Neither the authors nor Purdue University are responsible for any
#    consequences of the use of this software.
#
# 2. The origin of this software must not be misrepresented, either by
#    explicit claim or by omission.  Credit to the authors and Purdue
#    University must appear in documentation and sources.
#
# 3. Altered versions must be plainly marked as such, and must not be
#    misrepresented as being the original software.
#
# 4. This notice may not be removed or altered.
#
# install's Makefile
#
# $Id: Makefile,v 7.3 90/10/08 13:14:57 ksb Exp $
#
# Set appropriate defaults for your site in (configure.h) unless you want
# the default owner, group, and mode for installations where none were
# specified and install can't figure out something reasonable.
#
# I suggest you lpr install.h and look at it while you edit configure.h
#
X
BIN=	${DESTDIR}/usr/bin
ETC=	${DESTDIR}/usr/local/etc
PROG=	install
TPROG=	installp
X
#L=/usr/include/local
L=../libopt
I=/usr/include
S=/usr/include/sys
P=
X
CDEFS=
INCLUDE= -I$L
DEBUG=	-O
CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
X
HDR=	configure.h dir.h file.h install.h main.h special.h special.i \
X	syscalls.h
OBJ=	dir.o file.o main.o special.o syscalls.o
SRC=	dir.c file.c main.c special.c syscalls.c
MAN=	install.1l
SOURCE=	Makefile ${SRC} ${HDR} ${MAN}
X
all: ${TPROG}
X
${TPROG}:$P ${OBJ}
#	${CC} ${CFLAGS} ${OBJ} -o $@ -lopt
#	${CC} ${CFLAGS} ${OBJ} -o $@ -L /usr/local/lib -lopt
X	${CC} ${CFLAGS} ${OBJ} -o $@ ../libopt/libopt.a
#	${CC} ${CFLAGS} ${OBJ} -o $@ -lopt -lsocket
X
clean: FRC
X	rm -f Makefile.bak ${TPROG} *.o a.out core errs lint.errs shar tags
X
depend:	${SRC} ${HDR} FRC
X	maketd ${CDEFS} ${INCLUDE} ${SRC}
X
install: all myself.cf FRC
X	./installp -C./myself.cf -cvs ${TPROG} ${BIN}/${PROG}
X
lint: ${SRC} ${HDR} FRC
X	lint -h ${CDEFS} ${INCLUDE} ${SRC}
X
mkcat: ${MAN}
X	mkcat ${MAN}
X
print: ${SROUCE} FRC
X	lpr -J'${PROG} source' ${SROUCE}
X
source: ${SOURCE}
X
spotless: clean
X	rcsclean ${SOURCE}
X
tags: ${SRC} ${HDR}
X	ctags -t ${SRC} ${HDR}
X
${SOURCE}:
X	co -q $@
X
FRC:
X
# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
X
dir.o: configure.h dir.c install.h main.h special.h syscalls.h
X
file.o: configure.h dir.h file.c install.h main.h special.h syscalls.h
X
main.o: configure.h dir.h file.h install.h main.c special.h syscalls.h
X
special.o: configure.h install.h main.h special.c special.h special.i \
X	syscalls.h
X
syscalls.o: configure.h install.h main.h syscalls.c
X
# *** Do not add anything here - It will go away. ***
Purdue
chmod 0644 install.d/Makefile ||
echo 'restore of install.d/Makefile failed'
Wc_c="`wc -c < 'install.d/Makefile'`"
test 2977 -eq "$Wc_c" ||
	echo 'install.d/Makefile: original size 2977, current size' "$Wc_c"
fi
# ============= install.d/README ==============
if test -f 'install.d/README' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/README (File already exists)'
else
echo 'x - extracting install.d/README (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/README' &&
# $Id: README,v 7.0 90/09/17 09:41:36 ksb Exp $
X
Install is a tool for updating system files in a  controlled
environment.   The  design philosophy of install is to automate the
installation process and put  it  as  much  out  of reach  of  human
carelessness as possible, while providing a flexible, easy to use
tool.  Install provides the  following features:
X
X o    Install increases system security by providing  a  con-
X      trolled   installation   environment.   It  checks  the
X      actions of the superuser against a  configuration  file
X      that  you  build  (either by hand or using instck(1L)),
X      and can prevent grievous mistakes such as installing  a
X      shell  setuid  to  a  privileged  user, or installing a
X      world-writable password file.   An  appropriate  confi-
X      guration  file  can  guarantee that files are installed
X      with correct owner, group and mode,  that  strip(1)  is
X      run  on  binaries  and  ranlib(1)  is run on libraries.
X      Regardless of whether you create a configuration  file,
X      install  warns  you of many possible errors, unless you
X      make it quiet with its -q option.  For instance, if you
X      install a new version of the ex(1) editor and forget to
X      update its links, install will notice the  extra  links
X      to  the existing version and warn you that you might be
X      making a mistake.
X
X o    Installed files do not overwrite current versions.  The
X      current  version  is backed up to a subdirectory of its
X      dot directory (named "OLD" by default), where it may be
X      easily  re-installed  in  the case of an unforseen bug.
X      The companion program purge(1L) removes these backed-up
X      files  after a user-specified interval.  By default, if
X      you repeatedly install new versions of a file,  install
X      creates a series of backups, providing a primitive form
X      of version control.
X
X o    Install increases accountability by logging the actions
X      of  the  superuser.  This makes it easier to track down
X      errors after the fact.
X
X o    Install simplifies Makefiles by allowing you to combine
X      operations that would require several steps into a sin-
X      gle one (e.g., you can specify in a single command line
X      a   file's  ownership,  group,  mode,  whether  to  run
X      strip(1) or ranlib(1), and which  hard  or  soft  links
X      should be made).
X
X o    Despite its power and potential complexity, install  is
X      easy  to use interactively because it intuits appropri-
X      ate installation parameters for you,  either  by  using
X      those   associated  with  the  existing  file,  or  its
X      compilation-dependent defaults.  In most cases  you  do
X      not  have  to  specify  a  file's owner, group, or mode
X      unless you want them to be different from  an  existing
X      file.   Typical  interactive  usage  is simply "install
X      file destination."
X
X o    Install is as careful as  it  can  be  to  complete  an
X      installation once it is begun.  There is a point in the
X      code where unlink(2) and rename(2) must be executed  in
X      close  succession, and that is the only window in which
X      a system crash or a signal might leave system files  in
X      an  inconsistent state (unfortunately, this is not true
X      under operating systems that do not provide  an  atomic
X      rename(2) system call).  This is true even when install
X      must copy files across file system boundaries.
X
X o    Install may also be used to remove  (de-install)  files
X      in a controlled manner.
X
X o    Finally, install currently runs on a variety of  archi-
X      tectures  and  operating systems and is easy to port to
X      new platforms.
X
X
Known bugs, or problems....
X
install -d -rn /tmp/i-do-not-exist/OLD
X
X	outputs an error from stat about i-do-not-exist not existings,
X	(we know).  This is because the structure of building OLD dirs
X	from main.c is broken.  It should be easy to fix with a check
X	in dir.c/DirInstall for -n.  But then we have to find a directory
X	to stat to get the modes for the parent, and we can be wrong
X	(explicit owner/group/mode options will fool us).
X
X
kayessbee, ksb@cc.purdue.edu
Purdue
chmod 0444 install.d/README ||
echo 'restore of install.d/README failed'
Wc_c="`wc -c < 'install.d/README'`"
test 4174 -eq "$Wc_c" ||
	echo 'install.d/README: original size 4174, current size' "$Wc_c"
fi
# ============= install.d/main.h ==============
if test -f 'install.d/main.h' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/main.h (File already exists)'
else
echo 'x - extracting install.d/main.h (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/main.h' &&
/*
X * $Id: main.h,v 7.0 90/09/17 09:41:59 ksb Exp $
X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
/*
X * paths, names and options of tools we need to fork
X */
extern char BINCHGRP[];
extern char BINSTRIP[];
#if !defined(SYSV)
extern char BINRANLIB[];
#endif	/* sysV site do not have to run ranlib	*/
extern char BINLS[];
#if defined(SYSV)
extern char LSARGS[];
extern char LSDIRARGS[];
#else	/* bsd needs a -g option to show group	*/
extern char LSARGS[];
extern char LSDIRARGS[];
#endif	/* how does ls(1) show both owner&group	*/
X
X
/* global variables for options
X */
extern char *progname;		/* tail of argv[0]			*/
extern char *Group;		/* given group ownership		*/
extern char *Owner;		/* given owner				*/
extern char *Mode;		/* given mode				*/
extern char *HardLinks;		/* hard links to installed file		*/
extern char *SoftLinks;		/* symlinks to installed file		*/
extern int Copy;		/* we're copying			*/
extern int Destroy;		/* user doesn't want an OLD		*/
extern int BuildDir;		/* we're installing a directory		*/
extern int KeepTimeStamp;	/* if preserving timestamp		*/
extern int fQuiet;		/* suppress some errors, be quiet	*/
extern int Ranlib;		/* if we're running ranlib(1)		*/
extern int Strip;		/* if we're running strip(1)		*/
extern int fDelete;		/* remove the file/dir, log it		*/
extern int fRecurse;		/* Sun-like recursive dir install	*/
extern int fTrace;		/* if just tracing			*/
extern int fVerbose;		/* if verbose				*/
extern int f1Copy;		/* only keep one copy			*/
#if defined(CONFIG)
extern struct passwd *pwdDef;	/* aux default owner for config file	*/
extern struct group *grpDef;	/* aux default group for config file	*/
extern char *pcSpecial;		/* file contains ckecked paths		*/
#endif	/* have a -C option?			*/
X
/*
X * global variables, but not option flags
X */
extern int bHaveRoot;		/* we have root permissions		*/
extern char *pcGuilty;		/* the name logged as the installer	*/
X
#define INSTALL	1
Purdue
chmod 0444 install.d/main.h ||
echo 'restore of install.d/main.h failed'
Wc_c="`wc -c < 'install.d/main.h'`"
test 2898 -eq "$Wc_c" ||
	echo 'install.d/main.h: original size 2898, current size' "$Wc_c"
fi
# ============= install.d/special.h ==============
if test -f 'install.d/special.h' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/special.h (File already exists)'
else
echo 'x - extracting install.d/special.h (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/special.h' &&
/*
X * $Id: special.h,v 7.1 90/10/22 11:47:12 ksb Exp $
X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
/*
X * if we have a config file (check list) we need to represent each	(ksb)
X * line of the file in a struct.
X */
#if defined(CONFIG)
X
#define	CF_STRIP	's'
#define CF_RANLIB	'l'
#define CF_NONE		'n'
#define CF_ANY		'?'
X
#define CF_IS_STRIP(MCF)	(CF_STRIP == (MCF).chstrip)
#define CF_IS_RANLIB(MCF)	(CF_RANLIB == (MCF).chstrip)
#define CF_IS_NONE(MCF)		(CF_NONE == (MCF).chstrip)
#define CF_IS_ANY(MCF)		(CF_ANY == (MCF).chstrip)
X
typedef struct CFnode {
X	int ffound;		/* is the file we have			*/
X	int mtype;		/* file type bits			*/
X	int mmust;		/* mode as an int			*/
X	int moptional;		/* optional mode as an int		*/
X	short int fbangowner;	/* !root form for owner			*/
X	short int fbanggroup;	/* !system form for group		*/
X	char acmode[16];	/* mode as a string			*/
X	char acowner[16];	/* owner as a string			*/
X	char acgroup[16];	/* group as a string			*/
X	char chstrip;		/* strip ('l','s','-','*')		*/
X	char *pcmesg;		/* text to print after install		*/
X	uid_t uid;		/* used only by instck, to save lookups */
X	gid_t gid;		/* same as above			*/
X	int iline;		/* the matching line on the cf file	*/
X	char *pcspecial;	/* the special file we were searching	*/
X	char *pcpat;		/* the glob pattern we matched on	*/
X	char *pclink;		/* we a re just a link to another file	*/
} CHLIST;
X
#if !defined(MAXCNFLINE)
#define MAXCNFLINE	132
#endif	/* lenght of a config line		*/
X
#if HAVE_PROTO
extern char *NodeType(unsigned int, char *);
extern void ModetoStr(char *, int, int);
#if defined(INSTCK)
extern void DirCk(int, char **, char *, CHLIST *);
#endif
extern void Special(char *, char *, CHLIST *);
X
#else
extern char *NodeType();
extern void ModetoStr();
#if defined(INSTCK)
extern void DirCk();
#endif
extern void Special();
X
#endif
X
#endif	/* set check list flags from config file */
X
#define IS_LINK(MCL)  ((char *)0 != (MCL).pclink)
extern char *apcOO[];		/* name of 0/1 for user			*/
extern struct group *grpDef;	/* default group on all files (this dir)*/
extern struct passwd *pwdDef;	/* default owner on all files (this dir)*/
X
/*
X * this macro could be in glob.h, or not...
X */
#define SamePath(Mglob, Mfile)	_SamePath(Mglob, Mfile, 1)
X
#if HAVE_PROTO
extern void CvtMode(char *, int *, int *);
extern int _SamePath(char *, char *, int);
extern void InitCfg(char *, char *);
#else
extern void CvtMode();
extern int _SamePath();
extern void InitCfg();
#endif
Purdue
chmod 0444 install.d/special.h ||
echo 'restore of install.d/special.h failed'
Wc_c="`wc -c < 'install.d/special.h'`"
test 3429 -eq "$Wc_c" ||
	echo 'install.d/special.h: original size 3429, current size' "$Wc_c"
fi
# ============= purge/purge.8l ==============
if test -f 'purge/purge.8l' -a X"$1" != X"-c"; then
	echo 'x - skipping purge/purge.8l (File already exists)'
else
echo 'x - extracting purge/purge.8l (Text)'
sed 's/^X//' << 'Purdue' > 'purge/purge.8l' &&
.\" $Id: purge.8l,v 7.0 90/09/17 11:38:42 ksb Exp $
.\" by Kevin Braunsdorf
.TH PURGE 8L LOCAL
.SH NAME
purge \- remove outdated backup copies of installed programs
.SH SYNOPSIS
\fB/usr/local/etc/purge\fP [\-\fBASVhnv\fP] [\-\fBd\fP \fIdays\fP] [\-\fBu\fP \fIuser\fP] [\fIdirs\fP]
.SH DESCRIPTION
.PP
\fIPurge\fP removes backup files that are more than \fIdays\fP old from
OLD directories created by \fIinstall\fP(1L).  \fIPurge\fP locates the
OLD directories by recursively descending \fIdirs\fP selecting directories
named \*(lqOLD\*(rq that the invoker owns.
.PP
\fIPurge\fP does not remove backup files with multiple hard links if it
cannot find all the links.
This is an indication that a product was installed without
regard for multiple names (\fIinstall\fP warns the installer in
such cases, but the error message may have been inadvertently ignored).
\fIPurge\fP directs the maintainer to run \fIinstck\fP(1L)
to correct any such problems.
.SH OPTIONS
.TP
.BI \-A
Allow OLD directories owned by any user to be searched for out of date backup files.
.TP
.BI \-d days
Days to keep backup files (default 14).
.TP
.BI \-h 
Print a help message.
.TP
.BI \-n 
Do not really execute commands, output what would be done (see \-\fBv\fP).
.TP
.BI \-S 
Run as if we are the superuser.
In combination with \-\fBn\fP this allows a system administrator to
see what \fIpurge\fP would do when run as root.
.TP
.BI \-u user
OLD directories may (also) be owned by this user.
.TP
.BI \-v 
Be verbose by showing approximate actions as shell commands.
.TP
.BI \-V 
Show version information.
.SH EXAMPLES
.TP
purge -v -d7 $HOME/bin
Remove any backup files from my bin which are older than one week.
.TP
purge -Sn /bin/OLD
Show which files purge would remove from /bin's OLD directory.
.TP
purge -u news -u uucp -u adm -u lp /
When run as root, purge all system OLD directories on this machine.
.TP
purge -V
Output \fIpurge\fP's version information, eg.:
.sp 1
.nf
purge: $\&Id: purge.c,v 2.0 90/06/24 21:28:27 ksb Exp $
purge: default superuser login name: root
purge: backup directory name: OLD
purge: valid backup directory owner: root
.fi
.SH BUGS
.PP
\fIPurge\fP does not cross nfs mount points.
.PP
This version of \fIpurge\fP is slightly incompatible with the shell script.
.SH AUTHOR
David L Stevens, Purdue UNIX Group, dls@cc.purdue.edu
.br
Kevin Braunsdorf, Purdue UNIX Group, ksb@cc.purdue.edu
.SH "SEE ALSO"
install(1L), instck(1L), rm(1), sh(1)
Purdue
chmod 0444 purge/purge.8l ||
echo 'restore of purge/purge.8l failed'
Wc_c="`wc -c < 'purge/purge.8l'`"
test 2444 -eq "$Wc_c" ||
	echo 'purge/purge.8l: original size 2444, current size' "$Wc_c"
fi
# ============= purge/main.c ==============
if test -f 'purge/main.c' -a X"$1" != X"-c"; then
	echo 'x - skipping purge/main.c (File already exists)'
else
echo 'x - extracting purge/main.c (Text)'
sed 's/^X//' << 'Purdue' > 'purge/main.c' &&
/*
X * machine generated cmd line parser
X */
X
#include <ctype.h>
#include "getopt.h"
#include <stdio.h>
#include "configure.h"
#include "install.h"
#include "purge.h"
X
char
X	*progname = "$Id$",
X	u_terse[] = " [-ASVhnv] [-d days] [-u user] [dirs]",
X	*u_help[] = {
X		"A      purge for all users",
X		"S      run as if we were the superuser",
X		"V      show version information",
X		"d days days to keep backup files (default 14)",
X		"h      print this help message",
X		"n      do not really execute commands",
X		"u user OLD directories may be owned by this user",
X		"v      be verbose",
X		"dirs   dirs to purge",
X		(char *)0
X	};
int
X	fAnyOwner = 0,
X	fSuperUser = 0,
X	fVersion = 0,
X	iDays = 14,
X	fExec = 1,
X	fVerbose = 0;
X
static char sbData[] = "%s: illegal data for %s option `%c\'\n";
X
static void
chkint(opt, pch)
int opt;
char *pch;
{
X	register int c;
X
X	while (isspace(*pch))
X		++pch;
X	c = *pch;
X	if ('+' == c || '-' == c)
X		++pch;
X	while (isdigit(*pch))
X		++pch;
X	if ('\000' != *pch) {
X		fprintf(stderr, sbData, progname, "integer", opt);
X		exit(1);
X	}
}
X
/*
X * parser
X */
int
main(argc, argv)
int argc;
char **argv;
{
X	static char
X		sbOpt[] = "ASVd:hnu:v",
X		*u_pch = (char *)0;
X	static int
X		u_loop = 0;
X	register int curopt;
X	extern int atoi();
X	extern char *strrchr();
X
X	progname = strrchr(argv[0], '/');
X	if ((char *)0 == progname)
X		progname = argv[0];
X	else
X		++progname;
X	while (EOF != (curopt = getopt(argc, argv, sbOpt))) {
X		switch (curopt) {
X		case BADARG:
X			fprintf(stderr, "%s: option %c needs a parameter\n", progname, optopt);
X			exit(1);
X		case BADCH:
X			fprintf(stderr, "%s: usage%s\n", progname, u_terse);
X			exit(1);
X		case 'A':
X			fAnyOwner = ! 0;
X			continue;
X		case 'S':
X			fSuperUser = ! 0;
X			continue;
X		case 'V':
X			fVersion = ! 0;
X			continue;
X		case 'd':
X			chkint('d', optarg);
X			iDays = atoi(optarg);
X			continue;
X		case 'h':
X			fprintf(stdout, "%s: usage%s\n", progname, u_terse);
X			for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
X				fprintf(stdout, "%s\n", u_pch);
X			}
X			exit(0);
X		case 'n':
X			fExec = !1;
X			fVerbose = !0;
X			continue;
X		case 'u':
X			(void)AddHer(optarg);
X			continue;
X		case 'v':
X			fVerbose = ! 0;
X			continue;
X		}
X		break;
X	}
X	InitAll();
X	if (fVersion) {
X		exit(Version());
X	}
X
X	curopt = 1;
X	while (EOF != getarg(argc, argv)) {
X		curopt = 0;
X		Which(optarg);
X	}
X	if (curopt) {
X		exit(0);
X	}
X
X	Done();
X	exit(0);
}
Purdue
chmod 0644 purge/main.c ||
echo 'restore of purge/main.c failed'
Wc_c="`wc -c < 'purge/main.c'`"
test 2394 -eq "$Wc_c" ||
	echo 'purge/main.c: original size 2394, current size' "$Wc_c"
fi
# ============= purge/Makefile.mkcmd ==============
if test -f 'purge/Makefile.mkcmd' -a X"$1" != X"-c"; then
	echo 'x - skipping purge/Makefile.mkcmd (File already exists)'
else
echo 'x - extracting purge/Makefile.mkcmd (Text)'
sed 's/^X//' << 'Purdue' > 'purge/Makefile.mkcmd' &&
#	$Id: Makefile,v 7.2 90/11/28 08:52:31 ksb Exp $
#
#	Makefile for purge
#
X
PROG=	purge
BIN=	${DESTDIR}/usr/local/etc
MANROOT= ${DESTDIR}/usr/man
X
# where is the source code for install(1L)?
INSTALLD= ../install.d
#INSTALLD= /usr/src/usr.bin/install.d
#INSTALLD= /usr/src/local/cmd/install.d
X
# which type of links to build
#LN=ln
LN=ln -s
X
L=../libopt
#L=/usr/include/local
I=/usr/include
S=/usr/include/sys
P=
X
INCLUDE= -I$L
DEBUG=	-O
CDEFS=  
CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
X
LINKH=	configure.h install.h
LINKC=	
LINK=	${LINKH} ${LINKC}
GENH=	main.h ${LINKH}
GENC=	main.c ${LINKC}
GEN=	${GENC} ${GENH}
HDR=	purge.h filedup.h
SRC=	purge.c filedup.c
DEP=	${GENC} ${SRC}
OBJ=	main.o purge.o filedup.o
MAN=	purge.8l
OTHER=	README purge.m
SOURCE=	Makefile ${OTHER} ${MAN} ${HDR} ${SRC}
X
all: ${PROG}
X
${PROG}:$P ${OBJ}
#	${CC} -o $@ ${CFLAGS} ${OBJ} -lopt
#	${CC} -o $@ ${CFLAGS} ${OBJ} -L /usr/local/lib -lopt
X	${CC} -o $@ ${CFLAGS} ${OBJ} ../libopt/libopt.a
X
main.h: main.c
X
main.c: ${PROG}.m
X	mkcmd std_help.m ${PROG}.m
X	-(cmp -s prog.c main.c || (cp prog.c main.c && echo main.c updated))
X	-(cmp -s prog.h main.h || (cp prog.h main.h && echo main.h updated))
X	rm -f prog.[ch]
X
swap: main.c main.h
X	mv Makefile Makefile.mkcmd
X	mv Makefile.plain Makefile
X	make depend
X
links: ${LINK}
X
${LINK}:
X	${LN} ${INSTALLD}/$@ ./$@
X
clean: FRC
X	rm -f Makefile.bak ${PROG} ${GEN} *.o a.out core errs lint.out tags
X
calls: ${SRC} ${HDR} ${GEN} FRC
X	calls ${CDEFS} ${INCLUDE} ${DEP}
X
depend: ${SRC} ${HDR} ${GEN} FRC
X	maketd ${CDEFS} ${INCLUDE} ${DEP}
X
dirs: ${BIN}
X
install: all dirs FRC
X	install -cs ${PROG} ${BIN}/${PROG}
X
lint: ${SRC} ${HDR} ${GEN} FRC
X	lint -h ${CDEFS} ${INCLUDE} ${DEP}
X
mkcat: ${MAN}
X	mkcat -r${MANROOT} ${MAN}
X
print: source FRC
X	lpr -J'${PROG} source' ${SOURCE}
X
source: ${SOURCE}
X
spotless: clean
X	rcsclean ${SOURCE}
X
tags: ${HDR} ${SRC} ${GEN}
X	ctags -t ${HDR} ${SRC} ${GEN}
X
/ ${BIN}:
X	install -dr $@
X
${SOURCE}:
X	co -q $@
X
FRC:
X
# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
X
main.o: configure.h install.h main.c purge.h
X
purge.o: configure.h filedup.h install.h main.h purge.c purge.h
X
filedup.o: filedup.c filedup.h
X
# *** Do not add anything here - It will go away. ***
Purdue
chmod 0644 purge/Makefile.mkcmd ||
echo 'restore of purge/Makefile.mkcmd failed'
Wc_c="`wc -c < 'purge/Makefile.mkcmd'`"
test 2197 -eq "$Wc_c" ||
	echo 'purge/Makefile.mkcmd: original size 2197, current size' "$Wc_c"
fi
# ============= install.cf/Makefile ==============
if test ! -d 'install.cf'; then
    echo 'x - creating directory install.cf'
    mkdir 'install.cf'
fi
if test -f 'install.cf/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping install.cf/Makefile (File already exists)'
else
echo 'x - extracting install.cf/Makefile (Text)'
sed 's/^X//' << 'Purdue' > 'install.cf/Makefile' &&
#	$Id: Makefile,v 7.1 90/11/28 12:38:12 ksb Exp $
#
#	Makefile for install.cf
#
X
PROG=	install.cf
ETC=	${DESTDIR}/usr/local/etc
DOC=	${DESTDIR}/usr/man
X
SRC=	install.cf
MAN=	install.cf.5l
OTHER=	README
SOURCE=	Makefile ${OTHER} ${MAN} ${SRC}
X
all: ${PROG}
X
clean: FRC
X	rm -f Makefile.bak a.out core errs lint.out tags
X
deinstall: ${MAN} ${DOC} FRC
X	install -R ${ETC}/${PROG}
X	mkcat -r${DOC} -D ${MAN}
X
depend: FRC
X
dirs: ${ETC}
X
install: all dirs FRC
X	install -c -m644 ${PROG} ${ETC}/${PROG}
X
lint: FRC
X
mkcat: ${MAN} ${DOC} FRC
X	mkcat -r${DOC} ${MAN}
X
print: source FRC
X	lpr -J'${PROG} source' ${SOURCE}
X
source: ${SOURCE}
X
spotless: clean
X	rcsclean ${SOURCE}
X
tags: FRC
X
/ ${ETC}:
X	install -dr $@
X
${SOURCE}:
X	co -q $@
X
FRC:
X
# DO NOT DELETE THIS LINE - make depend DEPENDS ON IT
X
# *** Do not add anything here - It will go away. ***
Purdue
chmod 0644 install.cf/Makefile ||
echo 'restore of install.cf/Makefile failed'
Wc_c="`wc -c < 'install.cf/Makefile'`"
test 837 -eq "$Wc_c" ||
	echo 'install.cf/Makefile: original size 837, current size' "$Wc_c"
fi
# ============= install.d/syscalls.h ==============
if test -f 'install.d/syscalls.h' -a X"$1" != X"-c"; then
	echo 'x - skipping install.d/syscalls.h (File already exists)'
else
echo 'x - extracting install.d/syscalls.h (Text)'
sed 's/^X//' << 'Purdue' > 'install.d/syscalls.h' &&
/*
X * $Id: syscalls.h,v 7.0 90/09/17 09:42:07 ksb Exp $
X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
X * 47907.  All rights reserved.
X *
X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. Neither the authors nor Purdue University are responsible for any
X *    consequences of the use of this software.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Credit to the authors and Purdue
X *    University must appear in documentation and sources.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.
X *
X * 4. This notice may not be removed or altered.
X */
X
#if HAVE_PROTO
extern void BlockSigs(void);
extern void UnBlockSigs(void);
extern void Die(char *);
extern struct group * savegrent(struct group *);
extern struct passwd *savepwent(struct passwd *);
extern void ChMode(char *, int);
extern void ChGroup(char *, struct group *pgroup);
extern void ChOwnGrp(char *, struct passwd *, struct group *);
extern void ChTimeStamp(char *, struct stat *);
extern int DoCopy(char *, char *);
extern char *Mytemp(char *);
extern void MungName(char *);
extern char *StrTail(char *);
#if HAVE_SLINK
extern int CopySLink(char *, char *);
#endif	/* don't handle links at all */
extern int Rename(char *, char *, char *);
extern int IsDir(char *);
extern int MyWait(int);
extern int RunCmd(char *, char *, char *);
#else
extern void BlockSigs();
extern void UnBlockSigs();
extern void Die();
extern struct group * savegrent();
extern struct passwd *savepwent();
extern void ChMode();
extern void ChGroup();
extern void ChOwnGrp();
extern void ChTimeStamp();
extern char *Mytemp();
extern void MungName();
extern char *StrTail();
extern int DoCopy();
#if HAVE_SLINK
extern int CopySLink();
#endif	/* don't handle links at all */
extern int Rename();
extern int IsDir();
extern int MyWait();
extern int RunCmd();
#endif
X
extern uid_t geteuid();
extern gid_t getegid();
Purdue
chmod 0444 install.d/syscalls.h ||
echo 'restore of install.d/syscalls.h failed'
Wc_c="`wc -c < 'install.d/syscalls.h'`"
test 2372 -eq "$Wc_c" ||
	echo 'install.d/syscalls.h: original size 2372, current size' "$Wc_c"
fi
true || echo 'restore of instck/path.h failed'
echo End of part 6, continue with part 7
exit 0

exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.