#! /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 archive 4 (of 8)."
# Contents:  tripwire-1.0 tripwire-1.0/include tripwire-1.0/sigs
#   tripwire-1.0/sigs/crc tripwire-1.0/sigs/md5 tripwire-1.0/src
#   tripwire-1.0/src/preen.report.c tripwire-1.0/src/utils.c
#   tripwire-1.0/src/config.parse.c tripwire-1.0/sigs/md5/md5.c
#   tripwire-1.0/include/tripwire.h tripwire-1.0/sigs/crc/crc.h
# Wrapped by spaf@uther.cs.purdue.edu on Tue Nov  3 16:31:56 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'tripwire-1.0' ; then
    echo shar: Creating directory \"'tripwire-1.0'\"
    mkdir 'tripwire-1.0'
fi
if test ! -d 'tripwire-1.0/include' ; then
    echo shar: Creating directory \"'tripwire-1.0/include'\"
    mkdir 'tripwire-1.0/include'
fi
if test ! -d 'tripwire-1.0/sigs' ; then
    echo shar: Creating directory \"'tripwire-1.0/sigs'\"
    mkdir 'tripwire-1.0/sigs'
fi
if test ! -d 'tripwire-1.0/sigs/crc' ; then
    echo shar: Creating directory \"'tripwire-1.0/sigs/crc'\"
    mkdir 'tripwire-1.0/sigs/crc'
fi
if test ! -d 'tripwire-1.0/sigs/md5' ; then
    echo shar: Creating directory \"'tripwire-1.0/sigs/md5'\"
    mkdir 'tripwire-1.0/sigs/md5'
fi
if test ! -d 'tripwire-1.0/src' ; then
    echo shar: Creating directory \"'tripwire-1.0/src'\"
    mkdir 'tripwire-1.0/src'
fi
if test -f 'tripwire-1.0/src/preen.report.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.0/src/preen.report.c'\"
else
echo shar: Extracting \"'tripwire-1.0/src/preen.report.c'\" \(15903 characters\)
sed "s/^X//" >'tripwire-1.0/src/preen.report.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: preen.report.c,v 1.3 92/11/03 02:44:02 genek Exp $";
X#endif
X
X/*
X * preen.report.c
X *
X *	report generation given the data from preening
X *
X * Gene Kim
X * Purdue University
X */
X
X#include "../include/config.h"
X#include <stdio.h>
X#ifdef STDLIBH
X#include <stdlib.h>
X#endif
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef STRINGH
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X#include <time.h>
X#ifdef MALLOCH
X# include <malloc.h>
X#endif
X#include "../include/list.h"
X#include "../include/tripwire.h"
X
Xstatic void preen_report_changed_enum();
Xstatic int preen_change_count();
Xstatic char *structstat_fill();
Xstatic void pair_print_ss();
Xstatic void pair_print_ll();
Xstatic void pair_print_llo();
X
X/*
X * preen_report()
X *
X *	report on:
X *		which files have been ADDED
X *		which files have been DELETED
X *		which files have been CHANGED
X *			what attribute changed?
X */
X
Xvoid
Xpreen_report()
X{
X    struct list_elem *p;
X    struct stat statnew, statold;
X    char sigsnew[NUM_SIGS][SIG_MAX_LEN], sigsold[NUM_SIGS][SIG_MAX_LEN];
X    char *s;
X    int unignored;
X
X    fprintf(stderr, "###\n");
X    fprintf(stderr, "###\t\t\tTotal files scanned:\t\t%d\n", files_scanned_num);
X    fprintf(stderr, "###\t\t\t      Files added:\t\t%d\n", diff_added_num);
X    fprintf(stderr, "###\t\t\t      Files deleted:\t\t%d\n", diff_deleted_num);
X    fprintf(stderr, "###\t\t\t      Files changed:\t\t%d\n", diff_changed_num);
X    fprintf(stderr, "###\n");
X    fprintf(stderr, "###\t\t\tAfter applying rules:\n");
X    fprintf(stderr, "###\t\t\t      Changes discarded:\t%d\n",
X			diff_added_num + diff_deleted_num + diff_changed_num -
X	      		(unignored = preen_change_count()) );
X    fprintf(stderr, "###\t\t\t      Changes remaining:\t%d\n",
X		        unignored + diff_added_num + diff_deleted_num);
X    fprintf(stderr, "###\n");
X
X    /****** added ******/
X
X    /* open each of the three lists, using &diff_xxxx_list as keys */
X    if (list_open(&diff_added_list) < 0) {
X	fprintf(stderr, "preen_report: list_open() failed!\n");
X	exit(1);
X    }
X
X    /* print out each added file in sequence */
X    while ((p = list_get(&diff_added_list)) != NULL) {
X	(void) structstat_fill(p->varvalue, &statnew, sigsnew);
X	direntry_print(p->varname, statnew, DIFF_ADDED);
X    }
X
X    if (list_close(&diff_added_list) < 0) {
X	fprintf(stderr, "preen_report: list_close() failed!\n");
X	exit(1);
X    }
X
X    /****** deleted ******/
X
X    /* now print out the files that were deleted */
X    if (list_open(&diff_deleted_list) < 0) {
X	fprintf(stderr, "preen_report: list_open() failed!\n");
X	exit(1);
X    }
X
X    /* print out each added file in sequence */
X    while ((p = list_get(&diff_deleted_list)) != NULL) {
X	(void) structstat_fill(p->varvalue, &statnew, sigsnew);
X	direntry_print(p->varname, statnew, DIFF_DELETED);
X    }
X
X    if (list_close(&diff_deleted_list) < 0) {
X	fprintf(stderr, "preen_report: list_close() failed!\n");
X	exit(1);
X    }
X
X    /***** changed ******/
X
X    /*
X     * interate through the list
X     *		get the ignore vector
X     *		foreach each (attribute) {
X     *			if (attribute != attribute')
X     *				if (!ignored) { flag it; }
X     *		}
X     */
X    /*
X    list_print(&diff_changed_list);
X    */
X    if (list_open(&diff_changed_list) < 0) {
X	fprintf(stderr, "preen_report: list_open() failed!\n");
X	exit(1);
X    }
X
X    /* print out each added file in sequence */
X    while ((p = list_get(&diff_changed_list)) != NULL) {
X
X	/* copy the filename and expand any escaped characters */
X
X	/* filename, ignore, mode, inode, nlinks, uid, gid, size, access,
X	 * modify, ctime, sig1, sig2
X	 */
X
X	/* read in the new value from the changed_list
X	 *		throw away the new ignorevector -- we use the old one!
X	 */
X	(void) structstat_fill(p->varvalue, &statnew, sigsnew);
X
X	/* read in the list1 value form the hash table */
X	if ((s = list_lookup(p->varname, &filelist)) == NULL) {
X	    fprintf(stderr, "preen_report: list_lookup() failed!\n");
X	    exit(1);
X	}
X
X	(void) structstat_fill(s, &statold, sigsold);
X
X	/* is this file to be ignored? */
X	if (!(list_getflag(p->varname, &diff_changed_list) & FLAG_CHANGED))
X	    continue;
X
X	/* print out the report for this file */
X	direntry_print(p->varname, statnew, DIFF_CHANGED);
X
X    }
X
X    if (list_close(&diff_changed_list) < 0) {
X	fprintf(stderr, "preen_report: list_close() failed!\n");
X	exit(1);
X    }
X
X    /* enumerate specifics of changed files, if long output specified */
X    if (!quiet && unignored != 0) {
X	preen_report_changed_enum();
X    }
X
X    return;
X}
X
X/*
X * preen_report_changed_enum()
X *
X *	enumerate each changed attributed for each of the changed files.
X *	this is treated as yet another pass in the checking process.
X */
X
Xstatic void
Xpreen_report_changed_enum()
X{
X    struct list_elem *p;
X    char *ignorevec;
X    char sigsold[NUM_SIGS][SIG_MAX_LEN], sigsnew[NUM_SIGS][SIG_MAX_LEN];
X    struct stat statnew, statold;
X    char *s;
X    char stime1[64], stime2[64];
X    int ignoremask;
X    int i;
X    char label[50];
X
X    (void) fflush(stdout);
X    fprintf(stderr, "### Phase 5:   Generating observed/expected pairs for changed files\n");
X    fprintf(stderr, "###\n");
X    (void) fflush(stderr);
X
Xprintf("### Attr        Observed (what it is)	      Expected (what it should be)\n");
Xprintf("### =========== ============================= =============================\n");
X    /****
X    st_atime: Mon Aug 31 16:48:57 1992         Mon Aug 31 14:05:49 1992
X    ****/
X
X    /* open the list of changed files */
X    if (list_open(&diff_changed_list) < 0) {
X	fprintf(stderr, "preen_report: list_open() failed!\n");
X	exit(1);
X    }
X
X    /* print out each added file in sequence */
X    while ((p = list_get(&diff_changed_list)) != NULL) {
X
X	/* filename, ignore, mode, inode, nlinks, uid, gid, size, access,
X	 * modify, ctime, sig1, sig2 .. sign
X	 */
X
X	/* read in the list2 value from the changed_list
X	 *		throw away the new ignorevector -- we use the old one!
X	 */
X	(void) structstat_fill(p->varvalue, &statnew, sigsnew);
X
X	/* read in the list1 value form the hash table */
X	if ((s = list_lookup(p->varname, &filelist)) == NULL) {
X	    fprintf(stderr, "preen_report_changed_enum: list_lookup() failed!\n");
X	    exit(1);
X	}
X
X	ignorevec = structstat_fill(s, &statold, sigsold);
X
X	/* get the ignoremask */
X	ignoremask = ignore_vec_to_scalar(ignorevec);
X
X	/* is this file to be ignored? */
X	if (!(list_getflag(p->varname, &diff_changed_list) & FLAG_CHANGED))
X	    continue;
X
X	printf("%s\n", p->varname);
X	/* and then the {expected, received} pairs */
X
X#define STATEQ(x) (statnew.x != statold.x)
X
X	if (!(ignoremask & IGNORE_P))
X	    if (STATEQ(st_mode)) {
X		pair_print_llo("st_mode:", (long) statnew.st_mode,
X			(long) statold.st_mode);
X	    }
X	
X	if (!(ignoremask & IGNORE_I))
X	    if (STATEQ(st_ino)) {
X		pair_print_ll("st_ino:", (long) statnew.st_ino,
X			(long) statold.st_ino);
X	    }
X	
X	if (!(ignoremask & IGNORE_N))
X	    if (STATEQ(st_nlink)) {
X		pair_print_ll("st_nlink:", (long) statnew.st_nlink,
X			(long) statold.st_nlink);
X	    }
X
X	if (!(ignoremask & IGNORE_U))
X	    if (STATEQ(st_uid)) {
X		pair_print_ll("st_uid:", (long) statnew.st_uid,
X			(long) statold.st_uid);
X	    }
X
X	if (!(ignoremask & IGNORE_G))
X	    if (STATEQ(st_gid)) {
X		pair_print_ll("st_gid:", (long) statnew.st_gid,
X			(long) statold.st_gid);
X	    }
X
X	if (!(ignoremask & IGNORE_S))
X	    if (STATEQ(st_size)) {
X		pair_print_ll("st_size:", (long) statnew.st_size,
X			(long) statold.st_size);
X	    }
X
X	if (!(ignoremask & IGNORE_A))
X	    if (STATEQ(st_atime)) {
X		(void) strcpy(stime1, ctime(&statnew.st_atime));
X		(void) strcpy(stime2, ctime(&statold.st_atime));
X		chop(stime1);
X		chop(stime2);
X		pair_print_ss("st_atime:", stime1, stime2);
X	    }
X
X	if (!(ignoremask & IGNORE_M))
X	    if (STATEQ(st_mtime)) {
X		(void) strcpy(stime1, ctime(&statnew.st_mtime));
X		(void) strcpy(stime2, ctime(&statold.st_mtime));
X		chop(stime1);
X		chop(stime2);
X		pair_print_ss("st_mtime:", stime1, stime2);
X	    }
X
X	if (!(ignoremask & IGNORE_C))
X	    if (STATEQ(st_ctime)) {
X		(void) strcpy(stime1, ctime(&statnew.st_ctime));
X		(void) strcpy(stime2, ctime(&statold.st_ctime));
X		chop(stime1);
X		chop(stime2);
X		pair_print_ss("st_ctime:", stime1, stime2);
X	    }
X
X	for (i = 0; i < NUM_SIGS; i++) {
X	    if (!(runtimeignore & (IGNORE_0 << i)) &&
X					!(ignoremask & (IGNORE_0 << i)))
X		if (strcmp(sigsnew[i], sigsold[i]) != 0) {
X		    (void) sprintf(label, "%s (sig%d):", signames[i], i);
X		    pair_print_ss(label, sigsnew[i], sigsold[i]);
X		}
X
X	}
X
X	/* separate entries by a space */
X	printf("\n");
X    }
X
X    if (list_close(&diff_changed_list) < 0) {
X	fprintf(stderr, "preen_report_changed_enum: list_close() failed!\n");
X	exit(1);
X    }
X}
X
X/*
X * preen_change_count()
X *
X *	return the number of files that are changed, according to their
X *	ignore vectors.
X */
X
Xstatic int
Xpreen_change_count()
X{
X    int changed = 0;
X    struct list_elem *p;
X    char sigsold[NUM_SIGS][SIG_MAX_LEN], sigsnew[NUM_SIGS][SIG_MAX_LEN];
X    char vec64_a[50], vec64_m[50], vec64_c[50];
X    char trash[512];
X    struct stat statnew, statold;
X    char *s;
X    int ignoremask;
X    char ignorevec[512];
X    unsigned long mode, ino, nlink, uid, gid, size;
X    int entrynum;
X    int nfields;
X
X    /***** changed ******/
X
X    /*
X     * interate through the list
X     *		get the ignore vector
X     *		foreach each (attribute) {
X     *			if (attribute != attribute')
X     *				if (!ignored) { flag it; }
X     *		}
X     */
X    if (list_open(&diff_changed_list) < 0) {
X	fprintf(stderr, "preen_report: list_open() failed!\n");
X	exit(1);
X    }
X
X    /* print out each added file in sequence */
X    while ((p = list_get(&diff_changed_list)) != NULL) {
X
X	/* filename, ignore, mode, inode, nlinks, uid, gid, size, access,
X	 * modify, ctime, sig1, sig2
X	 */
X
X	/* read in the list2 value from the changed_list
X	 *		throw away the new ignorevector -- we use the old one!
X	 */
X
X	if ((nfields = sscanf(p->varvalue, db_record_format,
X		&entrynum, trash,
X		&mode, &ino, &nlink, &uid, &gid, &size,
X		vec64_a, vec64_m, vec64_c,
X		sigsnew[0], sigsnew[1], sigsnew[2], sigsnew[3], sigsnew[4],
X		sigsnew[5], sigsnew[6], sigsnew[7], sigsnew[8], sigsnew[9]))
X				!= DB_RECORD_FIELDS) {
X	    fprintf(stderr, "preen_change_count: illegal database record (nfields == %d).   Aborting...\n", nfields);
X	    fprintf(stderr, "	'%s'\n", p->varvalue);
X	    exit(1);
X	}
X        statnew.st_mode = (mode_t)mode;
X        statnew.st_ino = (ino_t)ino;
X        statnew.st_nlink = (nlink_t)nlink;
X        statnew.st_uid = (uid_t)uid;
X        statnew.st_gid = (gid_t)gid;
X        statnew.st_size = (off_t)size;
X
X	/* convert from base64 to int */
X	statnew.st_atime = b64tol(vec64_a);
X	statnew.st_mtime = b64tol(vec64_m);
X	statnew.st_ctime = b64tol(vec64_c);
X
X	/* read in the list1 value form the hash table */
X	if ((s = list_lookup(p->varname, &filelist)) == NULL) {
X	    fprintf(stderr, "preen_report: list_lookup() failed!\n");
X	    exit(1);
X	}
X
X	if (sscanf(s, db_record_format,
X		&entrynum, ignorevec,
X		&mode, &ino, &nlink, &uid, &gid, &size,
X		vec64_a, vec64_m, vec64_c,
X		sigsold[0], sigsold[1], sigsold[2], sigsold[3], sigsold[4],
X		sigsold[5], sigsold[6], sigsold[7], sigsold[8], sigsold[9])
X				!= DB_RECORD_FIELDS) {
X	    fprintf(stderr, "preen_change_count: illegal database record! Aborting...\n");
X	    fprintf(stderr, "	'%s'\n", s);
X	    exit(1);
X	}
X        statold.st_mode = (mode_t)mode;
X        statold.st_ino = (ino_t)ino;
X        statold.st_nlink = (nlink_t)nlink;
X        statold.st_uid = (uid_t)uid;
X        statold.st_gid = (gid_t)gid;
X        statold.st_size = (off_t)size;
X
X	/* convert from base64 to int */
X	statold.st_atime = b64tol(vec64_a);
X	statold.st_mtime = b64tol(vec64_m);
X	statold.st_ctime = b64tol(vec64_c);
X
X	/* get the ignoremask */
X	ignoremask = ignore_vec_to_scalar(ignorevec);
X
X	/* and then the {expected, received} pairs */
X
X#define FLAGIT() changed++; list_setflag(p->varname, FLAG_CHANGED, &diff_changed_list); continue
X#define SIGEQ(x) if (strcmp(sigsnew[(x)], sigsold[(x)]) != 0)
X
X	/* note the pain we go through to avoid dangling else's */
X	if (!(ignoremask & IGNORE_P)) { if (STATEQ(st_mode)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_I)) { if (STATEQ(st_ino)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_N)) { if (STATEQ(st_nlink)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_U)) { if (STATEQ(st_uid)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_G)) { if (STATEQ(st_gid)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_S)) { if (STATEQ(st_size)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_A)) { if (STATEQ(st_atime)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_M)) { if (STATEQ(st_mtime)) {FLAGIT();}}
X	if (!(ignoremask & IGNORE_C)) { if (STATEQ(st_ctime)) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_0) && !(ignoremask & IGNORE_0))
X					{ SIGEQ(0) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_1) && !(ignoremask & IGNORE_1))
X					{ SIGEQ(1) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_2) && !(ignoremask & IGNORE_2))
X					{ SIGEQ(2) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_3) && !(ignoremask & IGNORE_3))
X					{ SIGEQ(3) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_4) && !(ignoremask & IGNORE_4))
X					{ SIGEQ(4) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_5) && !(ignoremask & IGNORE_5))
X					{ SIGEQ(5) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_6) && !(ignoremask & IGNORE_6))
X					{ SIGEQ(6) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_7) && !(ignoremask & IGNORE_7))
X					{ SIGEQ(7) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_8) && !(ignoremask & IGNORE_8))
X					{ SIGEQ(8) {FLAGIT();}}
X	if (!(runtimeignore & IGNORE_9) && !(ignoremask & IGNORE_9))
X					{ SIGEQ(9) {FLAGIT();}}
X
X    }
X
X    /* clean up */
X    if (list_close(&diff_changed_list) < 0) {
X	fprintf(stderr, "preen_report: list_close() failed!\n");
X	exit(1);
X    }
X
X    return changed;
X}
X
X/*
X * structstat_fill(char *string, struct stat *statbuf)
X *
X *	given a string from the database, fill in the statbuf structure.
X *	
X *	return the ignore vector (a static system structure)
X */
X
Xstatic char *
Xstructstat_fill (string, statbuf, sigs)
X    char *string;
X    struct stat *statbuf;
X    char sigs[NUM_SIGS][SIG_MAX_LEN];
X{
X    char *ignorevec;
X    static char structstat_fill_string[512];
X    unsigned long        mode, ino, nlink, uid, gid, size;
X    int entrynum;
X    char vec64_a[50], vec64_m[50], vec64_c[50];
X
X    (void) strcpy(structstat_fill_string, string);
X    ignorevec = structstat_fill_string;
X
X    if (sscanf(string, db_record_format,
X		&entrynum, ignorevec,
X		&mode, &ino, &nlink, &uid, &gid, &size,
X		vec64_a, vec64_m, vec64_c,
X		sigs[0], sigs[1], sigs[2], sigs[3], sigs[4],
X		sigs[5], sigs[6], sigs[7], sigs[8], sigs[9])
X				!= DB_RECORD_FIELDS) {
X	fprintf(stderr, "structstat_fill: illegal database record! Aborting...\n");
X	fprintf(stderr, "	'%s'\n", string);
X	exit(1);
X    }
X    statbuf->st_mode = (mode_t)mode;
X    statbuf->st_ino = (ino_t)ino;
X    statbuf->st_nlink = (nlink_t)nlink;
X    statbuf->st_uid = (uid_t)uid;
X    statbuf->st_gid = (gid_t)gid;
X    statbuf->st_size = (off_t)size;
X
X    /* convert from base64 to int */
X    statbuf->st_atime = b64tol(vec64_a);
X    statbuf->st_mtime = b64tol(vec64_m);
X    statbuf->st_ctime = b64tol(vec64_c);
X
X    return ignorevec;
X}
X
X/*
X * pair_print_ss(char *label, char *s1, char *s2)
X *
X *	print {expected,received} table with strings
X */
X
Xstatic void
Xpair_print_ss (label, s1, s2)
X    char *label;
X    char *s1;
X    char *s2;
X{
X    printf("%15s %-30s%-30s\n", label, s1, s2);
X    return;
X}
X
X/*
X * pair_print_ll(char *label, long l1, long l2)
X *
X *	print {expected,received} table with longs
X */
X
Xstatic void
Xpair_print_ll (label, l1, l2)
X    char *label;
X    long l1;
X    long l2;
X{
X    printf("%15s %-30ld%-30ld\n", label, l1, l2);
X    return;
X}
X
X/*
X * pair_print_llo(char *label, long l1, long l2)
X *
X *	print {expected,received} table with longs in octal
X */
X
Xstatic void
Xpair_print_llo (label, l1, l2)
X    char *label;
X    long l1;
X    long l2;
X{
X    printf("%15s %-30lo%-30lo\n", label, l1, l2);
X    return;
X}
X
END_OF_FILE
if test 15903 -ne `wc -c <'tripwire-1.0/src/preen.report.c'`; then
    echo shar: \"'tripwire-1.0/src/preen.report.c'\" unpacked with wrong size!
fi
# end of 'tripwire-1.0/src/preen.report.c'
fi
if test -f 'tripwire-1.0/src/utils.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.0/src/utils.c'\"
else
echo shar: Extracting \"'tripwire-1.0/src/utils.c'\" \(13384 characters\)
sed "s/^X//" >'tripwire-1.0/src/utils.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: utils.c,v 1.27 92/10/20 14:59:01 genek Exp $";
X#endif
X
X/*
X * utils.c
X *
X *	miscellaneous utilities for Tripwire
X *
X * Gene Kim
X * Purdue University
X */
X
X#include "../include/config.h"
X#include <stdio.h>
X#ifdef STDLIBH
X#include <stdlib.h>
X#endif
X#include <ctype.h>
X#ifdef STRINGH
X#include <string.h>
X#else
X#include <strings.h>
X# if (!defined(strchr) && !defined(index))
X#  define strchr(s, c) index(s, c)
X# endif
X# if (!defined(memcpy) && !defined(bcopy))
X#  define memcpy(to, from, n) bcopy(from, to, n)
X# endif
X#endif
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <pwd.h>
X#include <grp.h>
X#include <sys/param.h>
X#include <ctype.h>
X#include <sys/param.h>
X#ifndef MAXHOSTNAMELEN
X#define MAXHOSTNAMELEN 64
X#endif
X#ifndef XENIX
X# include <sys/time.h>
X#else
X# include <time.h>
X#endif 	/* XENIX */
X#ifndef GETHOSTNAME
X# include <sys/utsname.h>
X#endif
X#if (defined(SYSV) && (SYSV < 3))
X# include <limits.h>
X#endif	/* SVR2 */
X#include "../include/list.h"
X#include "../include/tripwire.h"
X
Xstatic void print_perm();
X
X#ifndef S_IRGRP
X#define S_IRGRP	(S_IREAD >> 3)
X#define S_IWGRP (S_IWRITE >> 3)
X#define S_IXGRP (S_IEXEC >> 3)
X#define S_IROTH (S_IREAD >> 6)
X#define S_IWOTH (S_IWRITE >> 6)
X#define S_IXOTH (S_IEXEC >> 6)
X#endif
X
Xvoid warn_with_err(format, name)
X   char *format, *name;
X{
X    extern int  errno;
X    int real_errno = errno;
X    char *string;
X
X    if (!name)
X      string = format;
X    else {
X	string = (char *) malloc((unsigned) (strlen(format)+strlen(name)+1));
X	if (!string) {
X	    fputs("Unexpected malloc() failure in 'warn_with_err'!\n", stderr);
X	    exit(-1);
X	}
X	sprintf(string, format, name);
X	errno = real_errno;
X    }
X
X    perror(string);
X}
X
Xvoid
Xdie_with_err(format, name)
X    char *format, *name;
X{
X    warn_with_err(format, name);
X    exit(1);
X}
X
X/*
X * filename_hostname_expand(char **ps)
X *
X *	expand any '@'s in the specified string to the hostname.
X *
X *	Ex:   "xxx_@_xxx"  ---> "xxx_mentor.cc.purdue.edu_xxx"
X */
X
Xstatic char hostname[MAXHOSTNAMELEN];
X
Xvoid
Xfilename_hostname_expand(ps)
X    char **ps;
X{
X    char *s = *ps;
X    char outpath[MAXPATHLEN];
X    char *pc;
X
X    if (! *hostname) {   /* we only need to do this once */
X#ifndef GETHOSTNAME
X    struct utsname sysinfo;
X
X    if (uname(&sysinfo) < 0)
X	die_with_err("filename_hostname_expand: uname()", (char *) NULL);
X
X    (void) strcpy(hostname, sysinfo.nodename);
X
X#else 	/* GETHOSTNAME */
X
X    /* get the hostname */
X    if (gethostname(hostname, sizeof(hostname)) < 0)
X	die_with_err("filename_hostname_expand: gethostname()", (char *) NULL);
X
X#endif 	/* GETHOSTNAME */
X    }
X
X    /* is there a '@' in the filename? */
X    if ((pc = strchr(s, '@')) == NULL) {
X	return;
X    }
X
X    /* copy the first part of the string */
X    (void) strncpy(outpath, s, pc-s);
X
X    /* strncpy() doesn't guarantee null-terminated strings! */
X    outpath[pc-s] = '\0';
X
X    /* expand the '@' and copy the rest of the string */
X    (void) strcat(outpath, hostname);
X    (void) strcat(outpath, pc+1);
X
X    /* make our pointer point to the expanded string */
X    if ((pc = (char *) malloc((unsigned int) (strlen(outpath) + 1))) == NULL)
X	die_with_err("filename_hostname_expand: malloc()", (char *) NULL);
X
X    (void) strcpy(pc, outpath);
X
X    *ps = pc;
X
X    return;
X}
X
X/*
X * slash_count(char *pathname)
X *
X *	count the number of slashes in a given pathname.  This is used
X * 	to determine the priority of a given file entry when generating
X * 	the list of files.
X */
X
Xint
Xslash_count (pathname)
X    char *pathname;
X{
X	register int count = 0;
X	register char *pc;
X
X	for (pc = pathname; *pc; pc++ )
X		if (*pc == '/')
X			count++;
X	return count;
X}
X
X/*
X * string_split_space(char *string, char *s, char *t)
X *
X * 	given (string), place the first word into (s), and the rest of
X *	into (t).
X */
X
Xvoid
Xstring_split_space (string, s, t)
X    char *string;
X    char *s;
X    char *t;
X{
X    char *sp;
X
X    /*
X     * (char *sp) = the first space.  	s = {string[0..(sp-s-1)]}
X     *			      		t = {sp[1..end]}
X     */
X
X    if ((sp = strchr(string, ' ')) == NULL) {
X	fprintf(stderr, "string_split_space: string doesn't contain space!\n");
X	exit(1);
X	/* XXX - yikes!  this shouldn't be fatal!!!  */
X    }
X
X    /* don't forget to null-terminate the string w/strncpy() */
X    (void) strncpy(s, string, sp-string);
X    s[sp-string] = '\0';
X
X    (void) strcpy(t, sp+1);
X    return;
X}
X
X/*
X * int
X * string_split_ch(char *string, char *s, char *t, char ch)
X *
X * 	given (string), place the first word into (s), and the rest of
X *	into (t), using (ch) as the field separator.  (ala perl).
X */
X
Xint
Xstring_split_ch (string, s, t, ch)
X    char *string;
X    char *s;
X    char *t;
X    char ch;
X{
X    char *sp;
X
X    /*
X     * (char *sp) = the first space.  	s = {string[0..(sp-s-1)]}
X     *			      		t = {sp[1..end]}
X     */
X
X    if ((sp = strchr(string, ch)) == NULL) {
X	(void) strcpy(s, string);
X	t[0] = '\0';
X	return -1;
X    }
X
X    /* don't forget to null-terminate the string w/strncpy() */
X    (void) strncpy(s, string, sp-string);
X    s[sp-string] = '\0';
X
X    (void) strcpy(t, sp+1);
X    return 0;
X}
X
X/*
X * chop (char *s)
X *
X *	chop off the last character in a string, ala Perl.
X */
X
Xvoid
Xchop (s)
X    char *s;
X{
X	int slen;
X
X	slen = strlen(s);
X	s[slen-1] = '\0';
X	return;
X}
X
X/*
X * filename_escape_expand(char *filename)
X *
X *	expand \xxx octal characters, metachacters, and known
X *	C escape sequences.
X */
X
Xvoid
Xfilename_escape_expand (filename)
X    char *filename;
X{
X    int i = 0;
X    char filetmp[MAXPATHLEN];
X    int octal;
X    register char *pcin = filename, *pcout = filetmp;
X
X    /*
X     * case I:	it's not escaped
X     * case II: 	it's a three digit octal number
X     * case III:	it's a standard C escape sequence
X     *				(\n, \r, \', \", \t, \b, \f)
X     *			(from Johnson, Stephen C.,
X     *				"Yacc: Yet Another Compiler-Compiler")
X     * case IV:	it's one of our metacharacters {@#!|&()= }
X     */
X
X    while (*pcin) {
X
X	/* case I: it's not an escape */
X	if (*pcin != '\\')
X		*pcout++ = *pcin++;
X
X	/* case II: it's a three digit octal number */
X	else if (isdigit(*++pcin)) {
X	    /* read in the three characters */
X	    for (octal = i = 0; i < 3 ; i++, pcin++) {
X		octal *= 8;
X		
X		if (*pcin > '7' || *pcin < '0') {
X		    fprintf(stderr,
X			    "filename_escape_expand: bogus octal character (%c) in file `%s'!\n",
X			    *pcin, filename);
X		    exit(1);
X		}
X		else
X		  octal += *pcin-'0';
X	    }
X
X	    /* warn of filenames with null's in them */
X	    if (octal == 0) {
X		fprintf(stderr, "tripwire: warning: null character in file `%s'!\n",  filename);
X		exit(1);
X	    }
X
X	    *pcout++ = octal & 0xff;
X	}
X
X	/* case III: it's a standard C escape sequence */
X	/* case IV: it's one of our escape characters */
X	else
X	    switch(*pcin) {
X	    case 'n':		{ *pcout++ = '\n'; break; }
X	    case 'r':		{ *pcout++ = '\r'; break; }
X	    case 't':		{ *pcout++ = '\t'; break; }
X	    case 'b':		{ *pcout++ = '\b'; break; }
X	    case 'f':		{ *pcout++ = '\f'; break; }
X	    case '\'':		
X	    case '"':		
X	    case '@':
X	    case '!':
X	    case '#':
X	    case '=':
X	    case ' ':
X	    case ')':
X	    case '(':
X	    case '&':
X	    case '|':
X	    case '\\':
X	      /* same as our default case... it's the character itself */
X	    default: 		{ *pcout++ = *pcin++; break; }
X	  }
X    }
X
X
X    /* null terminate the string */
X    *pcout++ = '\0';
X
X    (void) memcpy(filename, filetmp, pcout - filetmp);
X    return;
X}
X
X/*
X * filename_escape(char *filename)
X *
X *	find any characters that must be escaped in the file name.
X */
X
Xvoid
Xfilename_escape (filename)
X    char *filename;
X{
X    char filetmp[MAXPATHLEN];
X    register char *pcin = filename, *pcout = filetmp;
X    static char *octal_array[] = {
X	"000", "001", "002", "003", "004", "005", "006", "007",
X	"010", "011", "012", "013", "014", "015", "016", "017",
X	"020", "021", "022", "023", "024", "025", "026", "027",
X	"030", "031", "032", "033", "034", "035", "036", "037",
X	"040", "041", "042", "043", "044", "045", "046", "047",
X	"050", "051", "052", "053", "054", "055", "056", "057",
X	"060", "061", "062", "063", "064", "065", "066", "067",
X	"070", "071", "072", "073", "074", "075", "076", "077",
X	"100", "101", "102", "103", "104", "105", "106", "107",
X	"110", "111", "112", "113", "114", "115", "116", "117",
X	"120", "121", "122", "123", "124", "125", "126", "127",
X	"130", "131", "132", "133", "134", "135", "136", "137",
X	"140", "141", "142", "143", "144", "145", "146", "147",
X	"150", "151", "152", "153", "154", "155", "156", "157",
X	"160", "161", "162", "163", "164", "165", "166", "167",
X	"170", "171", "172", "173", "174", "175", "176", "177",
X    };
X    register char *pccopy;
X
X    /* these only matter if they are the first character */
X    if (*pcin == '!' || *pcin == '=' || *pcin == '#')	
X	{ *pcout++ = '\\'; *pcout++ = *pcin++; }
X
X    /* these must be replace everywhere in the filename */
X    while (*pcin) {
X	if (isalnum(*pcin))
X	    *pcout++ = *pcin;
X	else
X	    switch(*pcin) {
X	      case '\\':
X	      case '\n':
X	      case '\r':
X	      case '\t':
X	      case '\b':
X	      case '\f':
X	      case '\'':
X	      case '\"':
X	      case '@':
X	      case ' ':
X	      case '(':
X	      case ')':
X	      case '&':
X	      case '|':
X	      case '#':
X		*pcout++ = '\\';
X		*pcout++ = *(pccopy = octal_array[*pcin]);
X		*pcout++ = *++pccopy;
X		*pcout++ = *++pccopy;
X		break;
X	    default:
X		*pcout++ = *pcin;
X		break;
X	    }
X	pcin++;
X    }
X
X    /* null terminate the string */
X    *pcout++ = '\0';
X
X    (void) memcpy(filename, filetmp, pcout - filetmp);
X}
X
X/*
X * lto64(long num, char *vec64)
X *
X *	convert a long integer to a base-64 string.
X *
X *	we return the pointer to the string containing the base-64 number.
X *	the string will always be padded so it is 6 bytes.
X *
X *	REMEMBER: this is also used in the signature routines
X */
X
Xstatic char base64vec[] =
X  "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
X
Xchar *
Xltob64(num, vec64)
X    register unsigned long num;
X    char *vec64;
X{
X    register char *p1 = vec64;
X    register int i;
X
X
X    /* build lsb -> msb */
X    for (i = 5; i >= 0; i--) {
X        p1[i] = base64vec[num & 0x3f];
X	num >>= 6;
X    }
X
X    vec64[6] = 0;
X
X    return vec64;
X}
X
X/*
X * long
X * b64toi(char *vec)
X *
X *	given a base-64 string, convert to a long.
X */
X
Xlong
Xb64tol(vec)
X    char *vec;
X{
X    register char *pc;
X    register long num = 0L;
X
X/*  The following takes advantage of the fact that
X *  the ASCII collating sequence has  . / 0 1 2 3...9
X *  all in sequence.  Your milage may vary on other systems.
X *
X *  The string is interpreted as base 64 even if it isn't :-)
X */
X
X    for (pc = vec; *pc; pc++) {
X	num <<= 6;
X	num += *pc;
X	
X	if (*pc <= '9') 	
X	  num -= '.';
X	else if (*pc <= 'Z')
X	  num -= '5';  /* '5' == 'A' - 12 */
X	else
X	  num -= ';';  /* ';' == 'a' - 38 */
X    }
X
X    return num;
X}
X
X/*
X * direntry_print(char *name, struct stat stabuf))
X *
X *	print out a pretty directory entry for the specified file
X *
X *	this routine was taken from crc_check.c, written by Jon Zeeff
X *	(zeeff@b-tech.ann-arbor.mi.us)
X *
X *	hacked for use in Tripwire by Gene Kim (genek@mentor.cc.purdue.edu).
X */
X
Xvoid
Xdirentry_print (name, statbuf, mode)
X    char *name;
X    struct stat statbuf;
X    int mode;
X{
X	struct passwd *entry;
X	static char owner[20];
X	char    a_time[50];
X
X	static int prev_uid = -9999;
X
X	switch(mode) {
X	case DIFF_ADDED:
X		printf("added:   "); break;
X	case DIFF_CHANGED:
X		printf("changed: "); break;
X	case DIFF_DELETED:
X		printf("deleted: "); break;
X	}
X
X	if (statbuf.st_uid != prev_uid) {
X		entry = (struct passwd *)getpwuid((int) statbuf.st_uid);
X		if (entry)
X			(void) strcpy(owner, entry->pw_name);
X		else
X			(void) sprintf(owner, "%d", statbuf.st_uid);
X		prev_uid = statbuf.st_uid;
X	}
X	/*
X	if (statbuf.st_gid != prev_gid) {
X		group_entry = getgrgid((int) statbuf.st_gid);
X		if (group_entry)
X			(void) strcpy(group, group_entry->gr_name);
X		else
X			(void) sprintf(group, "%d", statbuf.st_gid);
X		prev_gid = statbuf.st_gid;
X	}
X	*/
X
X	(void) strcpy(a_time, ctime(&statbuf.st_mtime));
X	a_time[24] = '\0';
X
X	print_perm((unsigned long)statbuf.st_mode);
X
X	(void) printf(" %-9.9s %7d %s", owner, statbuf.st_size,
X						a_time + 4);
X	printf(" %s\n", name);
X
X}
X
X/*	
X *	This routine was taken from crc_check.c, written by Jon Zeeff
X *	(zeeff@b-tech.ann-arbor.mi.us)
X *
X *	hacked for use in Tripwire by Gene Kim (genek@mentor.cc.purdue.edu).
X */
X
Xstatic void
Xprint_perm(perm)
X    unsigned long perm;
X{
X
X	char    string[20];
X
X	(void) strcpy(string, "----------");
X
X	switch (perm & S_IFMT) {
X
X	case S_IFDIR:
X		string[0] = 'd';
X		break;
X
X	case S_IFBLK:
X		string[0] = 'b';
X		break;
X
X	case S_IFCHR:
X		string[0] = 'c';
X		break;
X
X	case S_IFIFO:
X		string[0] = 'p';
X		break;
X	}
X	if (perm & S_IREAD)
X		string[1] = 'r';
X	if (perm & S_IWRITE)
X		string[2] = 'w';
X	if (perm & S_ISUID && perm & S_IEXEC)
X		string[3] = 's';
X	else if (perm & S_IEXEC)
X		string[3] = 'x';
X	else if (perm & S_ISUID)
X		string[3] = 'S';
X
X	if (perm & S_IRGRP)
X		string[4] = 'r';
X	if (perm & S_IWGRP)
X		string[5] = 'w';
X	if (perm & S_ISUID && perm & S_IXGRP)
X		string[6] = 's';
X	else if (perm & S_IXGRP)
X		string[6] = 'x';
X	else if (perm & S_ISUID)
X		string[6] = 'l';
X
X	if (perm & S_IROTH)
X		string[7] = 'r';
X	if (perm & S_IWOTH)
X		string[8] = 'w';
X	if (perm & S_ISVTX && perm & S_IXOTH)
X		string[9] = 't';
X	else if (perm & S_IXOTH)
X		string[9] = 'x';
X	else if (perm & S_ISVTX)
X		string[9] = 'T';
X
X	(void) printf("%s", string);
X}
END_OF_FILE
if test 13384 -ne `wc -c <'tripwire-1.0/src/utils.c'`; then
    echo shar: \"'tripwire-1.0/src/utils.c'\" unpacked with wrong size!
fi
# end of 'tripwire-1.0/src/utils.c'
fi
if test -f 'tripwire-1.0/src/config.parse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.0/src/config.parse.c'\"
else
echo shar: Extracting \"'tripwire-1.0/src/config.parse.c'\" \(13058 characters\)
sed "s/^X//" >'tripwire-1.0/src/config.parse.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char rcsid[] = "$Id: config.parse.c,v 1.2 92/11/03 02:43:33 genek Exp $";
X#endif
X
X/*
X * config.parse.c
X *
X *	read in the preen.config file
X *
X * Gene Kim
X * Purdue University
X */
X
X#include "../include/config.h"
X#include <stdio.h>
X#ifdef STDLIBH
X#include <stdlib.h>
X#include <unistd.h>
X#endif
X#include <sys/param.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef DIRENT
X# include <dirent.h>
X#else
X# ifndef XENIX
X#  include <sys/dir.h>
X# else		/* XENIX */
X#  include <sys/ndir.h>
X# endif		/* XENIX */
X#endif	/* DIRENT */
X#if (defined(SYSV) && (SYSV < 3))
X# include <limits.h>
X#endif	/* SVR2 */
X#include <ctype.h>
X#ifdef STRINGH
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X#include "../include/list.h"
X#include "../include/tripwire.h"
X
X#if defined(SYSV) && (SYSV < 4)
X#ifndef HAVE_LSTAT
X#  define lstat(x,y) stat(x,y)
X#endif
X#endif		/* SYSV */
X
X#if !defined(major)
X#define major(x)        (((unsigned)(x)>>16)&0xffff)
X#endif
X#if !defined(minor)
X#define minor(x)        ((x)&0xffff)
X#endif
X
X/* prototypes */
Xchar *mktemp();
Xstatic void configfile_descend();
X
X#ifndef L_tmpnam
X# define L_tmpnam (unsigned int) MAXPATHLEN
X#endif
X
X/* global */
X/*		we keep track of all the entry headers */
Xstatic struct list *prune_list = (struct list *) NULL;
X
X/*
X * configfile_read(struct list **pp_list, struct list **pp_entry_list)
X *
X *	open the configuration file, and pulls out the {file/dir,ignore-flag}
X *	pairs.
X *
X *	(**pp_list) is pointer the head of the file list, where all the
X *	files are added to.
X */
X
Xvoid
Xconfigfile_read(pp_list, pp_entry_list)
X    struct list **pp_list;
X    struct list **pp_entry_list;
X{
X    FILE 	*fpin, *fpout;
X    char	filename[MAXPATHLEN];
X    char	ignorestring[1024];
X    char	s[MAXPATHLEN+1024];
X    char	configfile[MAXPATHLEN];
X    char	*tmpfilename;
X    char	number[20];
X    int		entrynum = 0;
X    int		err;
X
X    /* don't print banner if we're in print-preprocessor mode */
X    if (!printpreprocess)
X	fputs("### Phase 1:   Reading configuration file\n", stderr);
X
X    /* generate temporary file name */
X    if ((tmpfilename = (char *) malloc(L_tmpnam)) == NULL) {
X	perror("configfile_read: malloc()");
X	exit(1);
X    };
X    (void) strcpy(tmpfilename, TEMPFILE_TEMPLATE);
X
X    if ((char *) mktemp(tmpfilename) == NULL) {
X	perror("database_build: mktemp()");
X	exit(1);
X    }
X
X    /* generate configuration file name */
X    if (specified_configfile == NULL)
X	sprintf(configfile, "%s/%s", config_path, config_file);
X    else
X	(void) strcpy(configfile, specified_configfile);
X
X    /* open the files */
X    /*		check to see if input is just stdin */
X    if (*configfile == '-' && !configfile[1]) {  /* configfile == "-" */
X	fpin = stdin;
X    }
X    else if ((fpin = fopen(configfile, "r")) == NULL) {
X	perror("configfile_read: fopen()");
X	exit(1);
X    }
X
X    err = umask(077);  /* to protect the tempfile */
X
X    if ((fpout = fopen(tmpfilename, "w+")) == NULL) {
X	perror("configfile_read: fopen()");
X	exit(1);
X    }
X    (void) umask(err);  /* return it to its former state */
X
X    /* The following unlink accomplishes two things:
X     *  1) if the program terminates, we won't leave a temp
X     *     file sitting around with potentially sensitive names
X     *     in it.
X     *  2) the file is "hidden" while we run
X     */
X    if (unlink(tmpfilename) < 0) {
X      	perror("configfile_read: unlink()");
X	exit(1);
X    }
X
X
X    /*
X     * pass 0: preprocess file
X     *		call the yacc hook, located in y.tab.c
X     */
X
X    tw_macro_parse(configfile, fpin, fpout, (struct list **) pp_entry_list);
X
X    if (fpin != stdin)
X	(void) fclose(fpin);
X    if (fflush(fpout) == EOF) {
X        fputs("configfile_read: unknown error on fflush(fpout)\n", stderr);
X	exit(1);
X    }
X    else
X        rewind(fpout);
X
X    fpin = fpout;
X
X    /* do we just print out the file, and then exit? */
X    if (printpreprocess) {
X	int t;
X
X	while ((t = getc(fpin)) != EOF)
X	  putc((char) t, stdout);
X	exit(0);	
X    }
X
X    /* pass 1: get all of the prune entries '!' */
X    while (fgets(s, sizeof(s), fpin) != NULL) {
X
X	int prune_mode;
X
X	/* read in database entry */
X	if ((err = sscanf(s, "%s %s", filename, ignorestring)) == 1) {
X	    (void) strcpy(ignorestring, defaultignore);
X	}
X	else if (err != 2) {
X	    fprintf(stderr, "'%s'\n", s);
X	    fputs("configfile_read: parse error\n", stderr);
X
X	    exit(1);
X	}
X
X	/* check for removeflag (preceding "!" or "=") */
X	switch (*filename) {
X      	case '!':
X	    prune_mode = PRUNE_ALL;
X	    (void) strcpy(filename, filename+1);	/* adjust name */
X  	    break;
X        case '=':
X	    prune_mode = PRUNE_ONE;
X	    (void) strcpy(filename, filename+1);	/* adjust name */
X	    break;
X        default:
X	  continue; /* nothing */
X	}
X
X
X	/* check for fully qualified pathname
X	 */
X	if (*filename != '/') {
X	    fprintf(stderr,
X		"config: %s is not fully qualified!  Skipping...\n" ,
X			filename);
X	    /* XXX -- error handling needed here */
X	    continue;
X	}
X
X	/* expand any escaped octal characters in name */
X	filename_escape_expand(filename);
X
X	/* add to local prune list */
X	list_set(filename, "", 0, &prune_list);
X
X	/* set appropriate prune flag */
X	list_setflag(filename, prune_mode, &prune_list);
X    }
X
X    /* rewind the file for pass 2 */
X    rewind(fpin);
X
X    /* pass 2: build file lists */
X
X    /* it's time for another banner */
X    if (!printpreprocess)
X	fputs("### Phase 2:   Generating file list\n", stderr);
X
X    while (fgets(s, sizeof(s), fpin) != NULL) {
X	int	howdeep;
X	int	prunedir = 0;
X
X	/*
X	 * get {filename,ignore} pair:
X	 * 	if only argument, then apply default ignore-flags
X	 *
X	 *	note that {ignore} used in the tripwire.config file is
X	 *		different than the one stored in the database file!
X	 *
X	 *	humans use the [N|R|L]+/-[pinugsmc3] format.  in the database,
X	 *		we use the old style where any capitalized letter
X	 *		means it's to be ignored.
X	 */
X
X	/* make sure to remember that the ignorestring could be a comment! */
X	if ( ((err = sscanf(s, "%s %s", filename, ignorestring)) == 1) ||
X			(ignorestring[0] == '#')) {
X	    (void) strcpy(ignorestring, defaultignore);
X	}
X	else if (err != 2) {
X	    fprintf(stderr, "'%s'\nconfigfile_read: parse error\n", s);
X
X	    exit(1);
X	}
X
X	/* skip all prune entries (we've already taken care of it) */
X	if (*filename == '!')
X	    continue;
X
X	/* check for leading '=', prune after one recursion */
X	else if (*filename == '=') {
X	    (void) strcpy(filename, filename+1);
X	    prunedir++;
X	}
X
X	/* check for fully qualified pathname
X	 */
X	if (*filename != '/') {
X	    fprintf(stderr,
X		"config: %s is not fully qualified!  Skipping...\n" ,
X			filename);
X	    /* XXX -- error handling needed here */
X	    continue;
X	}
X
X	/* expand any escaped octal characters in name */
X	filename_escape_expand(filename);
X
X	/* pass down the priority -- based on how fully-qualified the
X	 * 	entry was.
X	 */
X	howdeep = slash_count(filename);
X
X	/*
X	 * convert configuration-file style ignore-string to our database
X	 * representation.
X	 */
X	ignore_configvec_to_dvec(ignorestring);
X
X	/*
X	 * add the entry to list of entry headers (used for incremental
X	 * database updates.
X	 */
X	
X	sprintf(number, "%d", entrynum);
X	list_set(filename, number, 0, pp_entry_list);
X
X	configfile_descend(filename, ignorestring, howdeep, prunedir,
X					pp_list, entrynum++);
X    }						/* end reading file */
X
X    /* print out the list, if we're in a debuggin mode */
X    if (debuglevel > 10)
X	list_print(pp_list);
X
X    /* clean up */
X    (void) fclose(fpin);
X
X    return;
X}
X
X/*
X * configfile_descend(char *filename, char *ignorestring, int howdeep,
X *				int prunedir, struct list **pp_list,
X *				int entrynum)
X *
X *	recurses down the specified filename.  when it finally hits a real
X *	file, it is added to the list of files.
X *	
X *	if (prunedir) is set, then we quit after one recursion.
X *
X *	this routine also resolves any multiple instances of a file by
X *	using (howdeep) as a precendence level.
X *
X *	(entrynum) is the unique entry number tag from tw.config.
X */
X
Xstatic void
Xconfigfile_descend (filename, ignorestring, howdeep,
X				prunedir, pp_list, entrynum)
X    char *filename;
X    char *ignorestring;
X    int howdeep;
X    int prunedir;
X    struct list **pp_list;
X    int entrynum;
X{
X    struct stat statbuf;
X    static int	countrecurse = 0;	/* count how many levels deep we are */
X    static int	majordev, minordev;
X    char t[512];
X    extern int  errno;
X
X    countrecurse++;
X
XSPDEBUG(10)
Xprintf("---> %d: %s\n", countrecurse, filename);
X
X    /* check to see if it's on the prune list */
X    if (list_lookup(filename, &prune_list) != NULL) {
X
X	int flag;
X
X	/* return only if it was a '!' directive */
X	if ((flag = list_getflag(filename, &prune_list)) == PRUNE_ALL) {
X	    countrecurse--;
X	    return;
X	}
X	else if (flag == PRUNE_ONE)
X	    prunedir = 1;
X    }
X
X    /* get the stat structure of the (real) file */
X    if (lstat(filename, &statbuf) < 0) {
X	char err[MAXPATHLEN+64];
X        int real_err = errno;  /* in case sprintf clobbers the value */
X		
X	if (debuglevel > 10) {
X	    sprintf(err, "configfile_descend: lstat(%s)", filename);
X	} else {
X	    sprintf(err, "%s: %s", progname, filename);
X	}
X	errno = real_err;
X	perror(err);
X
X	/* so we just skip it */
X	countrecurse--;
X	return;
X    }
X
X    /*
X     * record our {major,minor} device pair if this is our first time
X     * recursing.  then we check if it changes.  if it does, we've crossed
X     * a filesystem, and we prune our tree.
X     */
X    if (countrecurse == 1) {
X
XSPDEBUG(4)
Xprintf("configfile_descend: r=%d: %s\n", countrecurse, filename);
X
X	majordev = major(statbuf.st_dev);
X	minordev = minor(statbuf.st_dev);
X    } else {
X	if (major(statbuf.st_dev) != majordev ||
X					minor(statbuf.st_dev) != minordev) {
X
XSPDEBUG(4)
Xprintf("configfile_descend: pruning '%s' n(%d,%d) != o(%d, %d)\n", filename,
X			major(statbuf.st_dev), minor(statbuf.st_dev),
X			majordev, minordev);
X
X	    countrecurse--;
X	    return;
X	    /* prune */
X	}
X    }
X
X    /*
X     * if it is a directory file, then we read in the directory entries
X     * and then recurse into the directory.
X     *
X     * remember, check to see if it's a symbolic link.  we never traverse
X     * them.
X     */
X    if (((statbuf.st_mode & S_IFMT) == S_IFDIR)
X
X#if !defined(SYSV) || (SYSV > 3)
X	&& !((statbuf.st_mode & S_IFMT) == S_IFLNK))
X#else
X	)
X#endif
X    {
X	DIR *p_dir;
X
X#ifdef DIRENT
X	struct dirent *pd;
X#else
X	struct direct *pd;
X#endif
X
X	char recursefile[MAXPATHLEN];
X
X	/* handle prunedir flag */
X
X	/*
X	 * concatenate entry number to the ignore-string
X	 */
X
X	sprintf(t, "%d %s", entrynum, ignorestring);
X
X	/*
X	 * just nix it from the list?
X	 */
X
X	list_set(filename, t, howdeep, pp_list);
X	(void) list_setflag(filename, FLAG_NOOPEN, pp_list);
X
X	/* if it's a symbolic link, make sure we flag it as such! */
X
X#if !defined(SYSV) || (SYSV > 3)
X	if ((statbuf.st_mode & S_IFMT) == S_IFLNK) {
X	    (void) list_setflag(filename, FLAG_SYMLINK, pp_list);
X	}
X#endif
X
X	if (prunedir) {
X	    countrecurse--;
X	    return;
X	}
X
XSPDEBUG(4)
Xfprintf(stderr, "configfile_descend: %s: it's a directory!\n", filename);
X
X	if ((p_dir = opendir(filename)) == NULL) {
X	    if (debuglevel > 10) {
X		perror("configfile_descend: opendir()");
X	    } else {
X		char err[MAXPATHLEN+64];
X		int real_errno = errno;
X		
X		sprintf(err, "%s: %s", progname, filename);
X		errno = real_errno;
X		perror(err);
X	    }
X	    countrecurse--;
X	    return;
X	}
X
X
X/* broken xenix compiler returns "illegal continue" ?!? */
X#ifdef XENIX
X#define XCONTINUE goto XENIX_CONT
X#else
X#define XCONTINUE continue
X#endif
X
X	for (pd = readdir(p_dir); pd != NULL; pd = readdir(p_dir)) {
X	    /* we could use strcmp in the following, but this is much faster */
X	    if (pd->d_name[0] == '.') {
X	      if (pd->d_name[1] == 0)    /* must be . */
X		XCONTINUE;
X	      else if (pd->d_name[1] == '.') {
X		if (pd->d_name[2] == 0)  /* must be .. */
X		  XCONTINUE;
X	      }
X	    }
X	
XSPDEBUG(4)
Xprintf("--> descend: %s\n", pd->d_name);
X
X	    /* build pathname of file */
X	    sprintf(recursefile, "%s/%s", filename, pd->d_name);
X
X	    /* recurse.  it'll pop right back if it is just a file */
X	    configfile_descend(recursefile, ignorestring, howdeep, 0,
X					pp_list, entrynum);
X
XXENIX_CONT: ;
X	
X	} 					/* end foreach file */
X
X	/* cleanup */
X	closedir(p_dir);
X    }						/* end if dir */
X    else {
X
X	/*
X	 * concatenate entry number to the ignore-string
X	 */
X
X	sprintf(t, "%d %s", entrynum, ignorestring);
X
X	/* add to list */
X	list_set(filename, t, howdeep, pp_list);
X
X	/*
X	 * if it is a special file or device, add it to the list, but
X	 * make sure we don't open it and read from it!
X	 */
X	switch (statbuf.st_mode & S_IFMT) {
X	  case S_IFIFO:
X	  case S_IFCHR:
X	  case S_IFBLK:
X#if !defined(SYSV) || (SYSV > 3)
X	  case S_IFSOCK:
X#endif
X	    (void) list_setflag(filename, FLAG_NOOPEN, pp_list);
X	    break;
X#if !defined(SYSV) || (SYSV > 3)
X	  case S_IFLNK:	/* if it's a symbolic link, make sure we flag it as such! */
X	    (void) list_setflag(filename, FLAG_SYMLINK, pp_list);
X#endif
X	    break;
X	  default:
X	    break;   /* do nothing for regular files */
X	}
X    }						/* end else dir */
X
X    countrecurse--;
X    return;
X}
X
END_OF_FILE
if test 13058 -ne `wc -c <'tripwire-1.0/src/config.parse.c'`; then
    echo shar: \"'tripwire-1.0/src/config.parse.c'\" unpacked with wrong size!
fi
# end of 'tripwire-1.0/src/config.parse.c'
fi
if test -f 'tripwire-1.0/sigs/md5/md5.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.0/sigs/md5/md5.c'\"
else
echo shar: Extracting \"'tripwire-1.0/sigs/md5/md5.c'\" \(10291 characters\)
sed "s/^X//" >'tripwire-1.0/sigs/md5/md5.c' <<'END_OF_FILE'
X/* $Id: md5.c,v 1.1.1.2 92/11/02 18:22:08 genek Exp $ */
X
X/***********************************************************************
X ** md5.c -- the source code for MD5 routines                         **
X ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
X ** Created: 2/17/90 RLR                                              **
X ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                   **
X ** Revised (for MD5): RLR 4/27/91                                    **
X ***********************************************************************
X ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
X ** License to copy and use this software is granted provided that    **
X ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
X ** Digest Algorithm" in all material mentioning or referencing this  **
X ** software or this function.                                        **
X ** License is also granted to make and use derivative works          **
X ** provided that such works are identified as "derived from the RSA  **
X ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
X ** material mentioning or referencing the derived work.              **
X ** RSA Data Security, Inc. makes no representations concerning       **
X ** either the merchantability of this software or the suitability    **
X ** of this software for any particular purpose.  It is provided "as  **
X ** is" without express or implied warranty of any kind.              **
X ** These notices must be retained in any copies of any part of this  **
X ** documentation and/or software.                                    **
X **********************************************************************/
X
X#include "md5.h"
X
X/* forward declaration */
Xstatic void Transform ();
X
Xstatic unsigned char PADDING[64] = {
X  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
X};
X
X/* F, G, H and I are basic MD5 functions */
X#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
X#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
X#define H(x, y, z) ((x) ^ (y) ^ (z))
X#define I(x, y, z) ((y) ^ ((x) | (~z)))
X
X/* ROTATE_LEFT rotates x left n bits */
X#ifdef UNICOS
X# define ROTATE_LEFT(x,n) (((x) << (n)) | (((x) & 0xffffffff) >> (32-(n))))
X#else
X# define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
X#endif 
X
X/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
X/* Rotation is separate from addition to prevent recomputation */
X#define FF(a, b, c, d, x, s, ac) \
X  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
X   (a) = ROTATE_LEFT ((a), (s)); \
X   (a) += (b); \
X  }
X#define GG(a, b, c, d, x, s, ac) \
X  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
X   (a) = ROTATE_LEFT ((a), (s)); \
X   (a) += (b); \
X  }
X#define HH(a, b, c, d, x, s, ac) \
X  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
X   (a) = ROTATE_LEFT ((a), (s)); \
X   (a) += (b); \
X  }
X#define II(a, b, c, d, x, s, ac) \
X  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
X   (a) = ROTATE_LEFT ((a), (s)); \
X   (a) += (b); \
X  }
X
X/* The routine MD5Init initializes the message-digest context
X   mdContext. All fields are set to zero.  */
Xvoid MD5Init (mdContext)
XMD5_CTX *mdContext;
X{
X  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
X
X  /* Load magic initialization constants.
X   */
X  mdContext->buf[0] = (UINT4)0x67452301;
X  mdContext->buf[1] = (UINT4)0xefcdab89;
X  mdContext->buf[2] = (UINT4)0x98badcfe;
X  mdContext->buf[3] = (UINT4)0x10325476;
X}
X
X/* The routine MD5Update updates the message-digest context to
X   account for the presence of each of the characters inBuf[0..inLen-1]
X   in the message whose digest is being computed.  */
Xvoid MD5Update (mdContext, inBuf, inLen)
XMD5_CTX *mdContext;
Xunsigned char *inBuf;
Xunsigned int inLen;
X{
X  UINT4 in[16];
X  int mdi;
X  unsigned int i, ii;
X
X  /* compute number of bytes mod 64 */
X  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
X
X  /* update number of bits */
X#ifndef UNICOS
X  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
X#else
X  if (((mdContext->i[0]+((UINT4)inLen << 3)) & 0xffffffff) < mdContext->i[0])
X#endif
X
X    mdContext->i[1]++;
X
X  mdContext->i[0] += ((UINT4)inLen << 3);
X  mdContext->i[1] += ((UINT4)inLen >> 29);
X
X  while (inLen--) {
X    /* add new character to buffer, increment mdi */
X    mdContext->in[mdi++] = *inBuf++;
X
X    /* transform if necessary */
X    if (mdi == 0x40) {
X      for (i = 0, ii = 0; i < 16; i++, ii += 4)
X        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
X                (((UINT4)mdContext->in[ii+2]) << 16) |
X                (((UINT4)mdContext->in[ii+1]) << 8) |
X                ((UINT4)mdContext->in[ii]);
X      Transform (mdContext->buf, in);
X      mdi = 0;
X    }
X  }
X}
X
X/* The routine MD5Final terminates the message-digest computation and
X   ends with the desired message digest in mdContext->digest[0...15].  */
Xvoid MD5Final (mdContext)
XMD5_CTX *mdContext;
X{
X  UINT4 in[16];
X  int mdi;
X  unsigned int i, ii;
X  unsigned int padLen;
X
X  /* save number of bits */
X  in[14] = mdContext->i[0];
X  in[15] = mdContext->i[1];
X
X  /* compute number of bytes mod 64 */
X  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
X
X  /* pad out to 56 mod 64 */
X  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
X  MD5Update (mdContext, PADDING, padLen);
X
X  /* append length in bits and transform */
X  for (i = 0, ii = 0; i < 14; i++, ii += 4)
X    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
X            (((UINT4)mdContext->in[ii+2]) << 16) |
X            (((UINT4)mdContext->in[ii+1]) << 8) |
X            ((UINT4)mdContext->in[ii]);
X  Transform (mdContext->buf, in);
X
X  /* store buffer in digest */
X  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
X    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
X    mdContext->digest[ii+1] =
X      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
X    mdContext->digest[ii+2] =
X      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
X    mdContext->digest[ii+3] =
X      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
X  }
X}
X
X/* Basic MD5 step. Transforms buf based on in.  */
Xstatic void Transform (buf, in)
XUINT4 *buf;
XUINT4 *in;
X{
X  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
X
X  /* Round 1 */
X#define S11 7
X#define S12 12
X#define S13 17
X#define S14 22
X  FF ( a, b, c, d, in[ 0], S11, 0xd76aa478); /* 1 */
X  FF ( d, a, b, c, in[ 1], S12, 0xe8c7b756); /* 2 */
X  FF ( c, d, a, b, in[ 2], S13, 0x242070db); /* 3 */
X  FF ( b, c, d, a, in[ 3], S14, 0xc1bdceee); /* 4 */
X  FF ( a, b, c, d, in[ 4], S11, 0xf57c0faf); /* 5 */
X  FF ( d, a, b, c, in[ 5], S12, 0x4787c62a); /* 6 */
X  FF ( c, d, a, b, in[ 6], S13, 0xa8304613); /* 7 */
X  FF ( b, c, d, a, in[ 7], S14, 0xfd469501); /* 8 */
X  FF ( a, b, c, d, in[ 8], S11, 0x698098d8); /* 9 */
X  FF ( d, a, b, c, in[ 9], S12, 0x8b44f7af); /* 10 */
X  FF ( c, d, a, b, in[10], S13, 0xffff5bb1); /* 11 */
X  FF ( b, c, d, a, in[11], S14, 0x895cd7be); /* 12 */
X  FF ( a, b, c, d, in[12], S11, 0x6b901122); /* 13 */
X  FF ( d, a, b, c, in[13], S12, 0xfd987193); /* 14 */
X  FF ( c, d, a, b, in[14], S13, 0xa679438e); /* 15 */
X  FF ( b, c, d, a, in[15], S14, 0x49b40821); /* 16 */
X
X  /* Round 2 */
X#define S21 5
X#define S22 9
X#define S23 14
X#define S24 20
X  GG ( a, b, c, d, in[ 1], S21, 0xf61e2562); /* 17 */
X  GG ( d, a, b, c, in[ 6], S22, 0xc040b340); /* 18 */
X  GG ( c, d, a, b, in[11], S23, 0x265e5a51); /* 19 */
X  GG ( b, c, d, a, in[ 0], S24, 0xe9b6c7aa); /* 20 */
X  GG ( a, b, c, d, in[ 5], S21, 0xd62f105d); /* 21 */
X  GG ( d, a, b, c, in[10], S22,  0x2441453); /* 22 */
X  GG ( c, d, a, b, in[15], S23, 0xd8a1e681); /* 23 */
X  GG ( b, c, d, a, in[ 4], S24, 0xe7d3fbc8); /* 24 */
X  GG ( a, b, c, d, in[ 9], S21, 0x21e1cde6); /* 25 */
X  GG ( d, a, b, c, in[14], S22, 0xc33707d6); /* 26 */
X  GG ( c, d, a, b, in[ 3], S23, 0xf4d50d87); /* 27 */
X  GG ( b, c, d, a, in[ 8], S24, 0x455a14ed); /* 28 */
X  GG ( a, b, c, d, in[13], S21, 0xa9e3e905); /* 29 */
X  GG ( d, a, b, c, in[ 2], S22, 0xfcefa3f8); /* 30 */
X  GG ( c, d, a, b, in[ 7], S23, 0x676f02d9); /* 31 */
X  GG ( b, c, d, a, in[12], S24, 0x8d2a4c8a); /* 32 */
X
X  /* Round 3 */
X#define S31 4
X#define S32 11
X#define S33 16
X#define S34 23
X  HH ( a, b, c, d, in[ 5], S31, 0xfffa3942); /* 33 */
X  HH ( d, a, b, c, in[ 8], S32, 0x8771f681); /* 34 */
X  HH ( c, d, a, b, in[11], S33, 0x6d9d6122); /* 35 */
X  HH ( b, c, d, a, in[14], S34, 0xfde5380c); /* 36 */
X  HH ( a, b, c, d, in[ 1], S31, 0xa4beea44); /* 37 */
X  HH ( d, a, b, c, in[ 4], S32, 0x4bdecfa9); /* 38 */
X  HH ( c, d, a, b, in[ 7], S33, 0xf6bb4b60); /* 39 */
X  HH ( b, c, d, a, in[10], S34, 0xbebfbc70); /* 40 */
X  HH ( a, b, c, d, in[13], S31, 0x289b7ec6); /* 41 */
X  HH ( d, a, b, c, in[ 0], S32, 0xeaa127fa); /* 42 */
X  HH ( c, d, a, b, in[ 3], S33, 0xd4ef3085); /* 43 */
X  HH ( b, c, d, a, in[ 6], S34,  0x4881d05); /* 44 */
X  HH ( a, b, c, d, in[ 9], S31, 0xd9d4d039); /* 45 */
X  HH ( d, a, b, c, in[12], S32, 0xe6db99e5); /* 46 */
X  HH ( c, d, a, b, in[15], S33, 0x1fa27cf8); /* 47 */
X  HH ( b, c, d, a, in[ 2], S34, 0xc4ac5665); /* 48 */
X
X  /* Round 4 */
X#define S41 6
X#define S42 10
X#define S43 15
X#define S44 21
X  II ( a, b, c, d, in[ 0], S41, 0xf4292244); /* 49 */
X  II ( d, a, b, c, in[ 7], S42, 0x432aff97); /* 50 */
X  II ( c, d, a, b, in[14], S43, 0xab9423a7); /* 51 */
X  II ( b, c, d, a, in[ 5], S44, 0xfc93a039); /* 52 */
X  II ( a, b, c, d, in[12], S41, 0x655b59c3); /* 53 */
X  II ( d, a, b, c, in[ 3], S42, 0x8f0ccc92); /* 54 */
X  II ( c, d, a, b, in[10], S43, 0xffeff47d); /* 55 */
X  II ( b, c, d, a, in[ 1], S44, 0x85845dd1); /* 56 */
X  II ( a, b, c, d, in[ 8], S41, 0x6fa87e4f); /* 57 */
X  II ( d, a, b, c, in[15], S42, 0xfe2ce6e0); /* 58 */
X  II ( c, d, a, b, in[ 6], S43, 0xa3014314); /* 59 */
X  II ( b, c, d, a, in[13], S44, 0x4e0811a1); /* 60 */
X  II ( a, b, c, d, in[ 4], S41, 0xf7537e82); /* 61 */
X  II ( d, a, b, c, in[11], S42, 0xbd3af235); /* 62 */
X  II ( c, d, a, b, in[ 2], S43, 0x2ad7d2bb); /* 63 */
X  II ( b, c, d, a, in[ 9], S44, 0xeb86d391); /* 64 */
X
X  buf[0] += a;
X  buf[1] += b;
X  buf[2] += c;
X  buf[3] += d;
X}
X
END_OF_FILE
if test 10291 -ne `wc -c <'tripwire-1.0/sigs/md5/md5.c'`; then
    echo shar: \"'tripwire-1.0/sigs/md5/md5.c'\" unpacked with wrong size!
fi
# end of 'tripwire-1.0/sigs/md5/md5.c'
fi
if test -f 'tripwire-1.0/include/tripwire.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.0/include/tripwire.h'\"
else
echo shar: Extracting \"'tripwire-1.0/include/tripwire.h'\" \(7233 characters\)
sed "s/^X//" >'tripwire-1.0/include/tripwire.h' <<'END_OF_FILE'
X/* $Id: tripwire.h,v 1.2 92/11/03 02:47:05 genek Exp $ */
X
X/************************************************************************
X *
X *   All files in the distribution of Tripwire are Copyright 1992 by the
X *   Purdue Research Foundation of Purdue University.  All rights
X *   reserved.  Some individual files in this distribution may be covered
X *   by other copyrights, as noted in their embedded comments.
X *
X *   Redistribution and use in source and binary forms are permitted
X *   provided that this entire copyright notice is duplicated in all such
X *   copies, and that any documentation, announcements, and other
X *   materials related to such distribution and use acknowledge that the
X *   software was developed at Purdue University, W. Lafayette, IN by
X *   Gene Kim and Eugene Spafford.  No charge, other than an "at-cost"
X *   distribution fee, may be charged for copies, derivations, or
X *   distributions of this material without the express written consent
X *   of the copyright holder.  Neither the name of the University nor the
X *   names of the authors may be used to endorse or promote products
X *   derived from this material without specific prior written
X *   permission.  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
X *   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
X *   IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR ANY PARTICULAR
X *   PURPOSE.
X *
X ************************************************************************/
X
X/*
X * tripwire.h
X *
X *	common definitions for Tripwire
X *
X * Gene Kim
X * Purdue University
X * October 18, 1992
X */
X
X/* version information */
X
X#define VERSION_NUM 	"1.0"
X#define DB_VERSION_NUM	1
X
X/* For signature routines prototypes: */
X
X#include "../sigs/snefru/snefru.h"
X#include "../sigs/md5/md5.h"
X#include "../sigs/crc32/crc32.h"
X#include "../sigs/crc/crc.h"
X#include "../sigs/md2/md2.h"
X#include "../sigs/md4/md4.h"
X
X/* essential includes common to all sources files */
X
X#include <errno.h>
X
X
X/* get any missing inode typedefs */
X
X#include "../include/inode.h"
X
X/* database record format */
X/* filename: (entrynumber, ignorevec, st_mode, st_ino, st_nlink,
X *		st_uid, st_gid, st_size,
X *		ltob64(statbuf->st_atime, vec64_a),
X *		ltob64(statbuf->st_mtime, vec64_m),
X *		ltob64(statbuf->st_ctime, vec64_c), sig1, sig2);
X */
X
X# define DB_RECORD_FORMAT "%ld %s %lo %lu %lu %lu %lu %lu %s %s %s %s %s %s %s %s %s %s %s %s %s\n"
X#define DB_RECORD_FIELDS 21
X
X/* system defaults */
X
Xextern int db_version_num;
Xextern char *config_file;	
Xextern char *config_path;	
Xextern char *database_file;	
Xextern char *database_path;	
Xextern char tempdatabase_file[];
Xextern int debuglevel, verbosity, quiet, printpreprocess;
Xextern char *specified_dbasefile, *specified_configfile;
Xextern char *progname;
Xextern char *defaultignore;
Xextern char *db_record_format;
Xextern struct list *filelist;
Xextern struct list *toc_list;
Xextern char *version_num;
Xextern struct list *entry_list;
Xextern char backupfile[];
Xextern int printhex;
Xextern int runtimeignore;
X
X/* debugging verbosity */
X
X#define SPDEBUG(x) if (debuglevel > (x))
X
X#define TRUE 1
X#define FALSE 0
X
X#define SIG_MAX_LEN 200
X
X/* ignore vector flags */
X/*	note:  as an optimization, IGNORE_0 .. IGNORE_9 are ordered.
X *	do not change the ordering of these vectors!
X */
X
X#define IGNORE_P	0x1
X#define IGNORE_I	0x2
X#define IGNORE_N	0x4
X#define IGNORE_U	0x8
X#define IGNORE_G	0x10
X#define IGNORE_S	0x20
X#define IGNORE_A	0x40
X#define IGNORE_M	0x80
X#define IGNORE_C	0x100
X#define IGNORE_0	0x200
X#define IGNORE_1	0x400
X#define IGNORE_2	0x800
X#define IGNORE_3	0x1000
X#define IGNORE_4	0x2000
X#define IGNORE_5	0x4000
X#define IGNORE_6	0x8000
X#define IGNORE_7	0x10000
X#define IGNORE_8	0x20000
X#define IGNORE_9	0x40000
X#define IGNORE_0_9	(IGNORE_0|IGNORE_1|IGNORE_2|IGNORE_3|IGNORE_4|IGNORE_5|IGNORE_6|IGNORE_7|IGNORE_8|IGNORE_9)
X
X/* filelist flags */
X#define FLAG_CHANGED 	1
X#define FLAG_NOOPEN	2
X#define FLAG_SYMLINK	4
X#define FLAG_SEEN	8
X#define FLAG_UPDATE	16
X
X/* prunelist flags */
X#define PRUNE_ALL	1
X#define PRUNE_ONE	2
X
X/* database_build() modes */
X
X#define DBASE_PERMANENT		0
X#define DBASE_TEMPORARY 	1
X#define DBASE_UPDATE 		2
X
X/* diff lists */
Xextern struct list *diff_added_list,
X		   *diff_deleted_list,
X		   *diff_changed_list;
Xextern int 	diff_added_num,
X    		diff_changed_num,
X		diff_deleted_num;
Xextern int	files_scanned_num;
X
X/* diff parsing */
X
Xstruct diff_bucket {
X    int 	arg1, arg2, arg3, arg4;
X    int		diffmode;
X};
X
X/* diff_parsing() types */
X#define DIFF_SAME 	0
X#define DIFF_CHANGED	1
X#define DIFF_ADDED	2
X#define DIFF_DELETED	3
X
X/* signature functions */
X#define NUM_SIGS	10
Xextern int (*pf_signatures[NUM_SIGS]) ();
Xextern char *signames[NUM_SIGS];
X
X/* prototypes */
X
X/*** Do not remove this line.  Protyping depends on it! ***/
X#if defined(__STDC__) || defined(__cplusplus)
X#define P_(s) s
X#else
X#define P_(s) ()
X#endif
X
X/* config.parse.c */
Xvoid configfile_read P_((struct list **pp_list, struct list **pp_entry_list));
X/* main.c */
Xint main P_((int argc, char *argv[]));
X/* list.c */
Xvoid list_set P_((char *pc_name, char *pc_value, int priority, struct list **pp_list));
Xchar *list_lookup P_((char *pc_name, struct list **pp_list));
Xint list_isthere P_((char *pc_name, struct list **pp_list));
Xvoid list_unset P_((char *pc_name, struct list **pp_list));
Xint list_setflag P_((char *pc_name, int flag, struct list **pp_list));
Xint list_getflag P_((char *pc_name, struct list **pp_list));
Xvoid list_print P_((struct list **pp_list));
Xvoid list_reset P_((struct list **pp_list));
Xint list_init P_((void));
Xint list_open P_((struct list **pp_list));
Xstruct list_elem *list_get P_((struct list **pp_list));
Xint list_close P_((struct list **pp_list));
X/* ignorevec.c */
Xint ignore_vec_to_scalar P_((char *s));
Xvoid ignore_configvec_to_dvec P_((char *s));
X/* dbase.build.c */
Xvoid database_build P_((struct list **pp_list, int mode, struct list **pp_entry_list));
X/* utils.c */
Xvoid warn_with_err P_((char *format, char *name));
Xvoid die_with_err P_((char *format, char *name));
Xvoid filename_hostname_expand P_((char **ps));
Xint slash_count P_((char *pathname));
Xvoid string_split_space P_((char *string, char *s, char *t));
Xint string_split_ch P_((char *string, char *s, char *t, int ch));
Xvoid chop P_((char *s));
Xvoid filename_escape_expand P_((char *filename));
Xvoid filename_escape P_((char *filename));
Xchar *ltob64 P_((register unsigned long num, char *vec64));
Xlong b64tol P_((char *vec));
Xvoid direntry_print P_((char *name, struct stat statbuf, int mode));
X/* preen.c */
Xvoid preen_gather P_((void));
Xvoid preen_update P_((char *entry));
X/* preen.interp.c */
Xvoid preen_interp P_((FILE *fpin));
X/* preen.report.c */
Xvoid preen_report P_((void));
X/* nullsig.c */
Xint sig_null_get P_((int fd_in, char *ps_signature, int siglen));
X/* config.prim.c */
Xvoid tw_mac_define P_((char *varname, char *varvalue));
Xchar *tw_mac_dereference P_((char *varname));
Xvoid tw_mac_undef P_((char *varname));
Xint tw_mac_ifdef P_((char *varname));
Xint tw_mac_ifhost P_((char *hostname));
X/* dbase.update.c */
Xvoid database_update_markentries P_((struct list **pp_list, int flagentry));
X/* config.pre.c */
Xvoid tw_macro_parse P_((char *filename, FILE *fpin, FILE *fpout, struct list **pp_entry_list));
END_OF_FILE
if test 7233 -ne `wc -c <'tripwire-1.0/include/tripwire.h'`; then
    echo shar: \"'tripwire-1.0/include/tripwire.h'\" unpacked with wrong size!
fi
# end of 'tripwire-1.0/include/tripwire.h'
fi
if test -f 'tripwire-1.0/sigs/crc/crc.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tripwire-1.0/sigs/crc/crc.h'\"
else
echo shar: Extracting \"'tripwire-1.0/sigs/crc/crc.h'\" \(77 characters\)
sed "s/^X//" >'tripwire-1.0/sigs/crc/crc.h' <<'END_OF_FILE'
X/* $Id: crc.h,v 1.1.1.2 92/11/02 18:20:43 genek Exp $ */
X
Xint sig_crc_get();
END_OF_FILE
if test 77 -ne `wc -c <'tripwire-1.0/sigs/crc/crc.h'`; then
    echo shar: \"'tripwire-1.0/sigs/crc/crc.h'\" unpacked with wrong size!
fi
# end of 'tripwire-1.0/sigs/crc/crc.h'
fi
echo shar: End of archive 4 \(of 8\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 8 archives.
    echo "Now read the README file"
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
