v06i059: file checker
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Wed Mar 8 11:29:10 AEST 1989
Posting-number: Volume 6, Issue 59
Submitted-by: zeeff at b-tech.ann-arbor.mi.us (Jon Zeeff)
Archive-name: crc-check
[A set of crc programs. This came to me labeled as a "file system checker",
but it's no fsck. ++bsa]
This is a set of programs to check for unexpected file system
corruption or security breaches. It's nice to be able to say that you
know all your files are as they should be.
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Makefile README crc.c crc_check.c find_crc
# Wrapped by zeeff at b-tech on Sun Feb 26 12:10:25 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makefile -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(241 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X
XCC=cc
XCFLAGS = -O
XLDFLAGS =
X
X
XSRCS=crc.c crc_check.c
XOBJS=crc.o crc_check.o
X
Xcrc: $(OBJS)
X $(CC) -o crc crc.o $(CFLAGS) $(LDFLAGS)
X $(CC) -o crc_check crc_check.o $(CFLAGS) $(LDFLAGS)
X
Xclean:
X rm -f crc.tmp crc.files *.o crc crc_check
X
END_OF_Makefile
if test 241 -ne `wc -c <Makefile`; then
echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1283 characters\)
sed "s/^X//" >README <<'END_OF_README'
X
XThis is a set of programs to check for unexpected file system
Xcorruption or security breaches. It's nice to be able to say that you
Xknow all your files are as they should be. Mark Mendel wrote most of
Xcrc.c and I wrote crc_check.c. It's written for Sys V, but BSD
Xshouldn't be hard.
X
X
XTo use it:
X
X1) you first create a crc list with the script find_crc. You can
Xmodify it and add grep -v to the pipe to change the file systems that
Xit checks. The end result is a file "crc.tmp".
X
X2) You can now use crc_check to compare this crc.tmp file to a crc list
Xcreated earlier called crc.files. If everything is ok, you can mv
Xcrc.tmp to crc.files. It is expected that you will want to use grep -v
Xon the output of crc_check to cut down on the noise.
X
XNote that you can use a -i option when running crc to change the
Xinitial crc value. If you don't tell anyone what this is, you can
Xmake it nearly impossible for anyone to modify a file and then adjust
Xthe crc value to the old one. To really do it right, you need to
X
X1) Run find_crc in single user mode (unless you modify the crc source).
X2) Store all crc results offline.
X3) Don't let anyone see your -i value or the crc results.
X
X
XPlease send me any modifications you make.
X
XJon Zeeff
Xzeeff at b-tech.ann-arbor.mi.us
X
X
END_OF_README
if test 1283 -ne `wc -c <README`; then
echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f crc.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"crc.c\"
else
echo shar: Extracting \"crc.c\" \(9918 characters\)
sed "s/^X//" >crc.c <<'END_OF_crc.c'
X/* updcrc(3), crc(1) - calculate crc polynomials
X *
X * Calculate, intelligently, the CRC of a dataset incrementally given a
X * buffer full at a time.
X *
X * Usage:
X * newcrc = updcrc( oldcrc, bufadr, buflen )
X * unsigned int oldcrc, buflen;
X * char *bufadr;
X *
X * Compiling with -DTEST creates a program to print the CRC of stdin to stdout.
X * Compile with -DMAKETAB to print values for crctab to stdout. If you change
X * the CRC polynomial parameters, be sure to do this and change
X * crctab's initial value.
X *
X * Notes:
X * Regards the data stream as an integer whose MSB is the MSB of the first
X * byte recieved. This number is 'divided' (using xor instead of subtraction)
X * by the crc-polynomial P.
X * XMODEM does things a little differently, essentially treating the LSB of
X * the first data byte as the MSB of the integer. Define SWAPPED to make
X * things behave in this manner.
X *
X * Author: Mark G. Mendel, 7/86
X * UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm
X */
X
X#define TEST
X
X/* The CRC polynomial.
X * These 4 values define the crc-polynomial.
X * If you change them, you must change crctab[]'s initial value to what is
X * printed by initcrctab() [see 'compile with -DMAKETAB' above].
X */
X
X/* Value used by: CITT XMODEM ARC */
X#define P 0xA001 /* the poly: 0x1021 0x1021 A001 */
X#define INIT_CRC 0L /* init value: -1 0 0 */
X#define SWAPPED /* bit order: undef defined defined */
X#define W 16 /* bits in CRC:16 16 16 */
X
X/* data type that holds a W-bit unsigned integer */
X#if W <= 16
X# define WTYPE unsigned short
X#else
X# define WTYPE unsigned long
X#endif
X
X/* the number of bits per char: don't change it. */
X#define B 8
X
Xstatic WTYPE crctab[1<<B] = /* as calculated by initcrctab() */ {
X 0x0, 0xc0c1, 0xc181, 0x140, 0xc301, 0x3c0, 0x280, 0xc241,
X 0xc601, 0x6c0, 0x780, 0xc741, 0x500, 0xc5c1, 0xc481, 0x440,
X 0xcc01, 0xcc0, 0xd80, 0xcd41, 0xf00, 0xcfc1, 0xce81, 0xe40,
X 0xa00, 0xcac1, 0xcb81, 0xb40, 0xc901, 0x9c0, 0x880, 0xc841,
X 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
X 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
X 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
X 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
X 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
X 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
X 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
X 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
X 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
X 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
X 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
X 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
X 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
X 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
X 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
X 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
X 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
X 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
X 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
X 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
X 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
X 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
X 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
X 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
X 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
X 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
X 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
X 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
X};
X
X
Xvoid perror();
Xchar *strcpy();
Xvoid exit();
X
XWTYPE
Xupdcrc( icrc, icp, icnt )
XWTYPE icrc;
Xunsigned char *icp;
Xint icnt;
X{
X register WTYPE crc = icrc;
X register unsigned char *cp = icp;
X register int cnt = icnt;
X
X while ( cnt--) {
X#ifndef SWAPPED
X crc = (crc << B) ^ crctab[(crc>>(W-B)) ^ *cp++];
X#else
X crc = (crc >> B) ^ crctab[(crc & ((1<<B)-1)) ^ *cp++];
X#endif
X }
X
X return( crc );
X}
X
X
X#ifdef MAKETAB
X
X#include <stdio.h>
Xmain()
X{
X initcrctab();
X}
X
X
Xinitcrctab()
X{
X register int b, i;
X WTYPE v;
X
X
X for ( b = 0; b <= (1 << B) - 1; ++b ) {
X#ifndef SWAPPED
X for ( v = b << (W - B), i = B; --i >= 0; )
X v = v & ((WTYPE)1 << (W - 1)) ? (v << 1) ^ P : v << 1;
X#else
X for ( v = b, i = B; --i >= 0; )
X v = v & 1 ? (v >> 1) ^ P : v >> 1;
X#endif
X crctab[b] = v;
X
X (void) printf( "0x%lx,", v & ((1L << W) - 1L));
X if ( (b & 7) == 7 )
X (void) printf("\n" );
X else
X (void) printf(" ");
X }
X}
X
X
X#endif
X
X#ifdef TEST
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <pwd.h>
X#include <grp.h>
X#define MAXBUF 4096
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
Xstruct stat stat_buf;
Xint initial_crc = INIT_CRC;
X
Xextern char *optarg;
Xextern int optind;
Xextern int opterr;
X
Xmain( argc, argv )
Xint argc;
Xchar **argv;
X{
X int stats_flag = 0;
X
X int c;
X
X if (argc == 1) {
X print_crc((char *)0, 0);
X return 0;
X }
X
X /* process all arguments */
X
X while ((c = getopt(argc, argv, "VvI:i:")) != EOF) {
X
X switch (c) {
X
X case 'V':
X case 'v':
X stats_flag = 1;
X break;
X
X case 'I':
X case 'i':
X initial_crc = atoi(optarg);
X break;
X
X default:
X (void) fprintf(stderr, "crc: -v (verbose listing)\n");
X (void) fprintf(stderr, " -i value (initial crc value)\n");
X exit(1);
X }
X }
X
X for (; optind < argc ; optind++)
X print_crc(argv[optind], stats_flag);
X
X return 0;
X}
X
X
Xprint_crc(name, stat_flag)
Xchar *name;
Xint stat_flag;
X{
X int fd;
X int nr;
X unsigned char buf[MAXBUF];
X WTYPE crc;
X#ifdef MAGICCHECK
X WTYPE crc2;
X#endif
X
X fd = 0;
X
X /* quietly ignore files we can't stat */
X
X if (name != NULL && stat(name, &stat_buf) != 0)
X return;
X
X /* don't do a crc on strange files */
X
X crc = nr = 0;
X
X if (name == NULL || (stat_buf.st_mode & S_IFMT) == S_IFREG) {
X
X /* open the file and do a crc on it */
X
X if (name != NULL && (fd = open( name, O_RDONLY )) < 0 ) {
X perror( name );
X exit( -1 );
X }
X#ifdef MAGICCHECK
X crc2 =
X#endif
X crc = initial_crc;
X
X while ( (nr = read( fd, (char *)buf, MAXBUF )) > 0 ) {
X crc = updcrc(crc, buf, nr );
X }
X (void) close(fd);
X
X }
X if ( nr != 0 ) {
X perror( "read error" );
X } else {
X (void) printf("%4.4x", (unsigned) crc );
X if (stat_flag)
X stats(name);
X else
X (void) printf("\n");
X
X }
X
X#ifdef MAGICCHECK
X /* tack one's complement of crc onto data stream, and
X continue crc calculation. Should get a constant (magic number)
X dependent only on P, not the data.
X */
X crc2 = crc ^ -1L;
X for ( nr = W - B; nr >= 0; nr -= B ) {
X buf[0] = (crc2 >> nr);
X crc = updcrc(crc, buf, 1);
X }
X
X /* crc should now equal magic */
X buf[0] = buf[1] = buf[2] = buf[3] = 0;
X (void) printf( "magic test: %lx =?= %lx\n", crc, updcrc((WTYPE) - 1, buf, W / B));
X#endif
X
X
X}
X
X
Xstats(name)
Xchar *name;
X{
X
X struct passwd *entry;
X struct group *group_entry;
X static char owner[20];
X static char group[20];
X char a_time[50];
X
X struct passwd *getpwuid();
X struct group *getgrgid();
X char *ctime();
X
X static int prev_uid = -9999;
X static int prev_gid = -9999;
X
X if (stat_buf.st_uid != prev_uid) {
X entry = getpwuid((int)stat_buf.st_uid);
X if (entry)
X (void) strcpy(owner, entry->pw_name);
X else
X (void) sprintf(owner, "%d", stat_buf.st_uid);
X prev_uid = stat_buf.st_uid;
X }
X if (stat_buf.st_gid != prev_gid) {
X group_entry = getgrgid((int)stat_buf.st_gid);
X if (group_entry)
X (void) strcpy(group, group_entry->gr_name);
X else
X (void) sprintf(group, "%d", stat_buf.st_gid);
X prev_gid = stat_buf.st_gid;
X }
X
X (void) strcpy(a_time, ctime(&stat_buf.st_mtime));
X a_time[24] = '\0';
X
X print_perm(stat_buf.st_mode);
X
X (void) printf(" %s\t%s\t%s %s\n", owner, group, a_time + 4, name);
X
X}
X
X
Xprint_perm(perm)
Xunsigned int perm;
X{
X
X char string[20];
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}
X
X#endif
X
END_OF_crc.c
if test 9918 -ne `wc -c <crc.c`; then
echo shar: \"crc.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f crc_check.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"crc_check.c\"
else
echo shar: Extracting \"crc_check.c\" \(4067 characters\)
sed "s/^X//" >crc_check.c <<'END_OF_crc_check.c'
X
X/*
X This progam will compare two crc lists and report the differences.
X
X By Jon Zeeff (zeeff at b-tech.ann-arbor.mi.us)
X
X Permission is granted to use this in any manner provided that
X 1) the copyright notice is left intact,
X 2) you don't hold me responsible for any bugs and
X 3) you mail me any improvements that you make.
X
X
X report:
X corrupt - crc changed w/o date change
X replaced - crc + date changed
X perm - permissions changed
X own/grp - owner or group changed
X removed -
X added -
X
XPrint the info for the new file except for deleted.
X
XUse:
X
Xfind / -print | sort | xargs crc -v > crc_file
X
Xto generate a crc list (crc.c should accompany this source).
X
XAssume that no files have tabs or spaces in the name.
X
X*/
X
X/* max size of line */
X
X#define BUF_SIZE 1124
X
X#include <stdio.h>
X
Xchar *strrchr();
Xvoid exit();
X
Xchar new_line[BUF_SIZE];
Xchar old_line[BUF_SIZE];
X
XFILE *new_file;
XFILE *old_file;
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X /*
X
X If line =, read new line from each file
X else
X If date/perm/crc change, report and read new line from each file
X else
X If old_line < new_line, report file removed, read old line
X else
X report new line as added
X read new_line
X loop
X*/
X
X char *new_ptr;
X char *old_ptr;
X
X if (argc != 3) {
X (void) printf("wrong number of arguments\n");
X (void) printf("crc_check old_crc_file new_crc_file\n");
X exit(1);
X }
X new_file = fopen(argv[2], "r");
X old_file = fopen(argv[1], "r");
X
X if (new_file == NULL || old_file == NULL) {
X (void) printf("can't open input files\n");
X (void) printf("crc_check old_crc_file new_crc_file\n");
X exit(1);
X }
X
X get_line(new_line);
X get_line(old_line);
X
X for (; ; ) {
X
X check_eof();
X
X /* If equal, print nothing and get new lines */
X
X if (strcmp(old_line, new_line) == 0) {
X get_line(new_line);
X get_line(old_line);
X continue;
X }
X
X /* Compare just the file names */
X
X new_ptr = strrchr(new_line, ' ');
X old_ptr = strrchr(old_line, ' ');
X
X if (new_ptr == NULL || old_ptr == NULL) {
X (void) printf("Error in input data\n");
X exit(1);
X }
X
X if (strcmp(old_ptr, new_ptr) == 0) {
X
X new_ptr = strrchr(new_line, '\t');
X old_ptr = strrchr(old_line, '\t');
X
X if (new_ptr == NULL || old_ptr == NULL) {
X (void) printf("Error in input data\n");
X exit(1);
X }
X
X /* check crc change */
X
X if (strncmp(new_line, old_line, 4) != 0)
X if (strcmp(new_ptr, old_ptr) == 0)
X (void) printf("corrupt %s", new_line + 5);
X else
X (void) printf("replaced %s", new_line + 5);
X
X
X /* check permission chenage */
X
X if (strncmp(new_line + 5, old_line + 5, 11) != 0)
X (void) printf("permiss %s", new_line + 5);
X
X /* check owner/group */
X
X if (strncmp(new_line+16, old_line+16, new_ptr - new_line - 15) != 0)
X (void) printf("own/grp %s", new_line + 5);
X
X get_line(new_line);
X get_line(old_line);
X continue;
X }
X
X
X if (strcmp(old_ptr, new_ptr) < 0) {
X (void) printf("removed %s", old_line + 5);
X get_line(old_line);
X continue;
X }
X
X (void) printf("added %s", new_line + 5);
X get_line(new_line);
X
X }
X
X}
X
X
Xget_line(string)
Xchar *string;
X{
X if (string == new_line)
X (void) fgets(string, BUF_SIZE, new_file);
X else
X (void) fgets(string, BUF_SIZE, old_file);
X
X}
X
X
Xcheck_eof()
X{
X
X if (feof(new_file)) {
X
X while (!feof(old_file)) {
X (void) printf("removed %s", old_line + 5);
X (void) fgets(old_line, BUF_SIZE, old_file);
X }
X exit(0);
X } else if (feof(old_file)) {
X while (!feof(new_file)) {
X (void) printf("added %s", new_line + 5);
X (void) fgets(new_line, BUF_SIZE, new_file);
X }
X exit(0);
X }
X
X}
X
X
END_OF_crc_check.c
if test 4067 -ne `wc -c <crc_check.c`; then
echo shar: \"crc_check.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f find_crc -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"find_crc\"
else
echo shar: Extracting \"find_crc\" \(58 characters\)
sed "s/^X//" >find_crc <<'END_OF_find_crc'
X
Xfind / -mount -print | sort | xargs crc -v > crc.tmp
X
X
END_OF_find_crc
if test 58 -ne `wc -c <find_crc`; then
echo shar: \"find_crc\" unpacked with wrong size!
fi
chmod +x find_crc
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
--
Jon Zeeff zeeff at b-tech.ann-arbor.mi.us
Ann Arbor, MI mailrus!b-tech!zeeff
More information about the Comp.sources.misc
mailing list