[comp.sources.misc] v07i096: brik: a general-purpose CRC-32 program

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (07/22/89)

Posting-number: Volume 7, Issue 96
Submitted-by: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
Archive-name: brik2/part03

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	brik.1
#	addbfcrc.asm
#	makefile.nix
#	makefile.msc
#	assert.h
#	descrip.mms
#	makefile.tcc
#	addbfcrc.c
#	crc.lst
#	makebrik.com
#	turboc.cfg
#	brik.prj
#	options.opt
# This archive created: Mon Jul 17 01:23:05 1989
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'brik.1'" '(25300 characters)'
if test -f 'brik.1'
then
	echo shar: "will not over-write existing file 'brik.1'"
else
sed 's/^X//' << \SHAR_EOF > 'brik.1'
X.\" ::[[ @(#) brik.1 1.12 89/07/12 00:11:50 ]]::
X.\"
X.TH BRIK 1 "Jul 8, 1989"
X.AT 3
X.\" ******* sh is a sub heading macro
X.de sh
X.br
X.ne 5
X.PP
X\fB\\$1\fR
X.PP
X..
X.\" ******** ex is for indented examples, no fill
X.de ex
X.RS 5
X.nf
X.sp 1
X..
X.\" ******** ef is for indented examples, with fill
X.de ef
X.RS 5
X.fi
X.sp 1
X..
X.\" ******* ee is to end ex and ef
X.de ee
X.fi
X.RE
X.sp 1
X..
X.\"
X.SH NAME
Xbrik \- calculate 32-bit CRC
X.SH SYNOPSIS
X.B brik \-h
X.sp  0
X.B brik \-gcGCbafvsqWHT
X.I file ...
X.SH DESCRIPTION
X.I Brik
Xgenerates and verifies 32-bit CRC values (checksums).  It is
Xdesigned to generate CRCs for text files that are the same on all computer
Xsystems that use the ASCII character set, provided each text file is in the
Xusual text file format for each system.  
X.I Brik
Xwill also optionally use
Xbinary CRCs calculated using every byte in a file.  Such binary CRCs are
Xportable across systems for binary files that are moved from system to system
Xwithout any newline conversion.  
X.I Brik
Xcan be asked to decide by examining
Xeach file whether to calculate a text mode or binary mode CRC for it.
X.PP
XChanges from version 1.0 are summarized at the end of this document.
X.PP
XThe general usage format is:
X.ef
Xbrik -gcGCbafvsqWHT
X[
X.I file
X] ...
X.ee
XThe brackets mean that
X.IR file ,
Xwhich is the name of a file, is optional.  The
Xthree dots indicate that more than one filename may be typed (separated by
Xblanks).  Exactly one of the options
X.BR \-c ,
X.BR \-C ,
X.BR \-g ,
X.BR \-G ,
Xor
X.BR \-h ,
Xis required.  The
X.B \-h
Xoption gives a help screen.
X.PP
XIn addition to
X.BR \-h ,
Xthe 
X.I Brik
Xoptions available (as they appear on the help
Xscreen) are:
X.TP
X.B \-g
Xlook for
X.I Checksum:
Xheader, generate CRC for rest of file
X.TP
X.B \-c
Xget CRC from header, verify CRC of rest of file
X.TP
X.B \-G
Xgenerate CRC for entire file (add
X.B \-b
Xfor binary files)
X.TP
X.B \-C
Xverify all file CRCs from output of
X.B \-G
X.RB ( \-f
Xis not needed)
X.TP
X.B \-b
Xuse binary mode -- read file byte by byte, not line by line
X.TP
X.B \-a
Xautomatically decide whether each file is text or binary
X.TP
X.B \-f
Xread filenames (wildcards ok) from specified files
X.TP
X.B \-v
Xbe verbose, report all results (else only errors are reported)
X.TP
X.B \-s
Xbe silent, say nothing, just return status code
X.TP
X.B \-q
Xbe quiet, don't print header for
X.B \-G
X.TP
X.B \-W
Xafter generating CRC with
X.BR \-g ,
Xwrite it to original header
X.TP
X.B \-H
Xafter generating CRC with
X.BR \-g ,
Xprint header to stdout
X.TP
X.B \-T
Xinclude trailing empty lines, normally ignored (text mode only)
X.sh "VERIFYING CRC HEADERS"
XThe primary intended use of 
X.I Brik
Xis to verify
X.I Checksum:
Xheaders in Usenet
Xpostings and in C and Pascal source files.  A
X.I Checksum:
Xheader looks like
Xthis:
X.ex
X\&Checksum: 9485762645b   (verify with "brik")
X.ee
XThe word
X.I Checksum:
Xmust occur at the beginning of a line.  It is followed by a colon, an
Xoptional blank, a ten-digit decimal 32-bit CRC, and any arbitrary
Xoptional string such as the comment shown above.  The CRC value may
Xbe followed by a one-character suffix identifying the type of the
XCRC.  These suffixes are described later.
X.PP
XWhen 
X.I Brik
Xis invoked with
Xthe syntax
X.ef
Xbrik -c
X.I file ...
X.ee
Xit will search for the
X.I Checksum:
Xheader in each specified
X.I file,
Xread the CRC
Xvalue from that header, calculate the CRC-32 for all lines in the file
X(except trailing empty lines) that occur *after* the header line, and
Xreport an error if the two values do not match.  
X.ne 6
X.sh "CALCULATING CRC HEADERS"
XThe command
X.ef
Xbrik \-g
X.I file ...
X.ee
Xtells 
X.I Brik
Xto look for the
X.I Checksum:
Xheader in each specified
X.I file,
Xcalculate the CRC of the lines in the file following the header, and
Xprint the CRC and filename without changing the file in any way.  You
Xcan also ask 
X.I Brik
Xto update the
X.I Checksum:
Xheader with the following command:
X.ef
Xbrik \-gW
X.I file ...
X.ee
XThis causes 
X.I Brik
Xto update the
X.I Checksum:
Xheader in the file with the newly-calculated CRC.  If there is not
Xenough space for the CRC in the existing header, 
X.I Brik
Xreports an error and does not change the existing header.  To
Xinitially add a
X.I Checksum:
Xheader to a file, insert a line of the following form into the
Xfile with a text editor:
X.ex
X\&Checksum: XXXXXXXXXX  -- this is an optional comment
X.ee
XThe word
X.I Checksum
Xmust be at the beginning of a line.  The ten `X' characters shown can
Xbe any ten characters.  They will be later replaced by the calculated
XCRC value.  They do not need to be `X'.  The comment following them
Xis optional and can be any arbitrary string of characters after the
XCRC field, separated from it by blanks.  As an example, in a C
Xsource file called
X.I main.c,
Xyou might have:
X.ex
X/*
X\&Checksum: XXXXXXXXXX  (verify or update with brik)
X*/
X.ee
XOnce a header like this exists in the file, invoke 
X.I Brik
Xas follows:
X.ex
Xbrik \-gW main.c
X.ee
XThis will cause the ten `X' characters to be replaced with the calculated
Xchecksum, giving something like this:
X.ex
X/*
X\&Checksum: 1922837484  (verify or update with brik)
X*/
X.ee
XLater you can use the command
X.ex
Xbrik \-c main.c
X.ee
Xto verify that the contents of the file following the header have the
Xsame CRC as the stored value.
X.PP
XIf 
X.I Brik
Xis invoked with the
X.B \-c
Xor
X.B \-g
Xoptions and it cannot find a
X.I Checksum:
Xheader in a file, it prints a row of question marks.  If it is invoked
Xwith the
X.B \-gW
Xoption and it does not find enough character positions after the
X.I Checksum:
Xstring to hold the CRC, it does not fill in the CRC and prints an
Xerror message.
X.PP
X.I Brik
Xcan be asked to generate a complete
X.I Checksum:
Xheader but print it to
Xstandard output instead of writing it to the file.  Do this by adding the
X.B \-H
Xoption.  If both
X.B \-W
Xand
X.B \-H
Xare given, the
X.I Checksum:
Xheader will be written both to the file and to standard output.
X.sh "WHOLE-FILE CRCS"
XA "whole-file" CRC calculation is done for the entire contents of a file,
Xwithout looking for a
X.I Checksum:
Xheader.  The command
X.ef
Xbrik \-G
X.I file ...
X.ee
Xasks 
X.I Brik
Xto do this calculation for all specified files.  The output from this
Xcommand is a list of files and their whole-file CRCs.  It is sent to
Xthe standard output stream, which in most cases is your screen.  The
Xoutput should be saved in a file by redirecting it.  For example, the
Xcommand
X.ex
Xbrik \-G *.h *.c > crc.lst
X.ee
Xon an MS-DOS system might yield the following in the output file
X.I crc.lst:
X.ex
X# CRC-32        filename
X# ------        --------
X
X2566277976      getopt.c
X 100594287      brik.c
X1151475469      vms.c
X3929503738      turboc.c
X2424271922      addbfcrc.c
X1943472856      assert.h
X2601923477      brik.h
X.ee
XThe output of the
X.B \-G
Xoption is in free format.  The output file may be edited
Xby hand.  Empty lines and lines beginning with '#' will be ignored by
X.I Brik
Xwhen it is later asked to read this file.
X.PP
XThis list of filenames and whole-file CRCs may be verified by a
Xcommand like this:
X.ex
Xbrik \-C crc.lst
X.ee
XThis makes 
X.I Brik
Xread the file
X.I crc.lst,
Xget the CRCs and filenames from it, do the CRC calculation again for
Xeach file, and report an error if it does not match the CRC recorded
Xinside
X.I crc.lst.
X.PP
X\&**IX and MS-DOS users (and others who can pipe the output of one
Xcommand into another) could use a command like the following to see
Xif 
X.I "Brik's"
X.B \-G
Xand
X.B \-C
Xoptions are working:
X.ex
Xbrik \-G file ... | brik \-C
X.ee
XThis invokes "brik \-G" on some files, sending the output to a pipe
Xwhere it becomes the input of "brik \-C".  If no filename is
Xspecified, 
X.I Brik
Xreads from standard input, so "brik \-C" will read from the pipe and
Xconcurrently verify all the CRCs that are being generated by
X"brik \-G".
X.PP
XWhole-file CRCs are normally generated in text mode, in which a file
Xis treated as lines of text.  You can also generate whole-file CRCs
Xin binary mode.  See below.
X.sh "BINARY VERSUS TEXT MODE"
X.I Brik
Xcan work in two different modes.  The most common mode, used unless
Xyou specify otherwise, is text mode.
X.PP
XIn this mode
X.I Brik
Xreads all files line by line, and forces each line of text to be
Xterminated by a newline character of constant value before doing a CRC
Xcalculation.  Thus, no matter what newline character is used by your system,
Xthe CRC calculation will be unaffected.  This means that whether your
Xoperating system uses linefeeds to terminate lines (e.g. **IX), or a carriage
Xreturn and a linefeed (e.g. MS-DOS) or a carriage return only
X(e.g. Macintosh) or nothing but a record length field (e.g. VAX/VMS),
Xthe CRC calculation in text mode gives the same results.
X.PP
XIf a file is not intended to be a text file, the text mode CRC
Xcalculated by
X.I Brik
Xmay not be reliable and may be different on different systems.  If
X.I Brik
Xis calculating a text mode CRC on a file that appears to contain
Xbinary data, it still calculates the text-mode CRC but adds a "*"
Xcharacter after the CRC to indicate to warn the user.
X.PP
X.I Brik
Xcan be asked to operate in binary mode by adding a
X.B \-b
Xoption.  Binary mode is applicable only to the
X.B \-G
Xcommand, which acts on whole
Xfiles.  Thus
X.ef
Xbrik \-G
X.I file ...
X.ee
Xfinds whole-file CRCs of all specified files in text mode, while
X.ef
Xbrik \-Gb
X.I file ...
X.ee
Xdoes the same in binary mode.  In binary mode 
X.I Brik
Xsimply reads and calculates the CRC for all bytes in a file.  If a
Xfile is moved from one system to another without any newline
Xconversion or any other changes,
X.I Brik
Xshould calculate the same binary mode CRC for it on both systems.
X.PP
XThe output from "brik \-Gb" includes a trailing
X.B b
Xsuffix in each CRC, so "brik \-C" will correctly use binary mode for
Xsuch CRCs and it is never necessary to type "brik \-Cb" instead.
X.PP
XIn its auto-check mode,
X.I Brik
Xwill itself examine each file and determine whether it is a text or
Xbinary file and calculate a CRC accordingly.  To do this, use the
X.B \-a
Xoption.  Although
X.I Brik
Xcan determine the type of each file with a high degree of
Xreliability, it is still possible for it to come to a wrong
Xconclusion about some files.
X.PP
XThe output from "brik \-Ga" will include a trailing
X.B b
Xcharacter in the CRC for those files that appeared to be binary to 
X.I Brik.
X\& You may find both text and binary CRCs in the output.
X.sh "TRAILING EMPTY LINES"
XThe normal behavior of 
X.I Brik
Xin text mode is to ignore any trailing empty lines in a file.  An
Xempty line is a line that contains nothing, not even blanks or
Xtabs.  (Just hitting a carriage return when you are editing a text
Xfile usually produces an empty line.)  If manipulating a text file
Xcauses trailing empty lines to be added or deleted, the CRC
Xcalculated by 
X.I Brik
Xwill be unaffected.  You can override this if necessary with the
X.B \-T
Xoption, which makes 
X.I Brik
Xinclude trailing empty lines in the CRC calculation.  For example,
X.ex
Xbrik \-gWT
X.ee
Xwill update the
X.I Checksum:
Xheader with a CRC that includes all lines in a text file.  Similarly
X.ex
Xbrik \-GT
X.ee
Xwill find whole-file CRCs that include all lines in a text file.
X.PP
XWhen 
X.I Brik
Xis given the
X.B \-T
Xoption, it adds a
X.B T
Xsuffix to each generated CRC.  Then, when the CRC is verified with
X.B \-c
Xor
X.BR \-C ,
X.I Brik
Xwill correctly include trailing empty lines when needed without
Xhaving to be explicitly told to do so.
X.PP
XIn binary mode 
X.I Brik
Xalways reads all bytes in a file, so it does not ignore trailing
Xempty lines, and the
X.B \-T
Xswitch is not needed.
X.PP
XThe effects of the
X.B \-T
Xand
X.B \-b
Xoptions are mutually exclusive.  If both are given, whichever is
Xused later overrides the first.  So
X.B \-bT
Xis equivalent
Xto
X.B \-T
Xand
X.B \-Tb
Xis equivalent to
X.BR \-T .
X.sh "FILENAME CONVENTIONS"
XUnder MS-DOS and VAX/VMS, wildcards are allowed on the command line
Xand will be expanded by 
X.I Brik.
X\& Under **IX, wildcards are expected to be expanded by
Xthe shell and are not expanded by 
X.I Brik.
X\& If no filename is given, 
X.I Brik
Xreads its standard input.  By default this is keyboard input, but it
Xis expected that input will usually be redirected to come from a file
Xor a pipe.  Also, if a filename is explicitly specified as a dash
X("\-"), it stands for standard input.
X.PP
XThe following five commands (valid under the **IX operating system)
X.ex
Xbrik \-c myfile            # "myfile"
Xbrik \-c < myfile          # stdin = "myfile"
Xcat myfile | brik \-c      # stdin = a pipe
Xbrik \-c \- < myfile        # "\-" = stdin = "myfile"
Xcat myfile | brik \-c \-    # "\-" = stdin = a pipe
X.ee
Xall have the effect of verifying the
X.I Checksum:
Xheader in the file
X.I myfile.
X.PP
XStandard input can also be read when using the
X.B \-C
Xoption.  For example, suppose we have already given the command
X.ex
Xbrik \-G *.c *.h > crc.lst
X.ee
Xto create a file called "crc.lst" that contains a list of whole-file
XCRCs.  We can now verify the integrity of these files with any of the
Xfollowing commands:
X.ex
Xbrik \-C crc.lst          # "crc.lst"
Xbrik \-C < crc.lst        # stdin = "crc.lst"
Xbrik \-C \- < crc.lst      # "\-" = stdin = "crc.lst"
Xcat crc.lst | brik \-C    # stdin = a pipe
Xcat crc.lst | brik \-C \-  # "\-" = stdin = a pipe
X.ee
X.sh "INDIRECT FILE NAMING"
XThe
X.B \-f
Xoption allows you to have filenames in a list rather than on the
Xcommand line.  For example, suppose you want to generate whole-file CRCs of
Xfiles whose names are selected by some other program.  You could use
X.I find
X(under **IX) or
X.I Stuff
X(under MS-DOS) to generate a list of filenames.  When
Xthe
X.B \-f
Xoption is given, 
X.I Brik
Xreads filenames, one per line, from the file(s)
Xspecified.  Thus you could do the following:
X.ex
Xfind . \-mtime +3 \-print > flist
Xbrik \-Gf flist > crc.lst
X.ee
XThe first command asks
X.I find
Xto generate a list of names of all files that
Xwere modified more than 3 days ago, and sends the output to the file
X.I flist.
X\& The contents of
X.I flist
Xmight now look like this, as an example:
X.ex
X\&./sez.doc
X\&./brik.doc
X\&./stuff.doc
X\&./looz.doc
X.ee
XThe second command above asks 
X.I Brik
Xto read the file called
X.I flist,
Xget a list of filenames from it, one per line, and generate the
Xwhole-file CRC of each of these files.  We additionally redirect the
Xoutput of "brik \-Gf" to the file called
X.I crc.lst.
X\& Given the above contents
Xof
X.I flist,
Xthe following two commands are exactly equivalent:
X.ex
Xbrik \-Gf flist >crc.lst
Xbrik \-G ./sez.doc ./brik.doc ./stuff.doc ./looz.doc >crc.lst
X.ee
XThe advantage of the
X.B \-f
Xoption is that once you have filenames in a file, you need not type
Xthem again at the command line.  The
X.B \-f
Xoption also allows you to feed 
X.I Brik
Xthrough a pipe filenames generated by another program.  Consider this
Xcommand:
X.ex
Xfind . \-mtime +3 \-print | brik \-Gf \- > crc.lst
X.ee
XUnder **IX this concurrently invokes both
X.I find
Xand 
X.I Brik.
X\& As
X.I find
Xgenerates a filename and sends it to its standard output (a pipe), 
X.I Brik
Xreads the filename from its standard input and generates its
Xwhole-file CRC.  The following pipeline
X.ex
Xfind . \-mtime +3 \-print | brik \-Gf \- | brik \-C \-
X.ee
Xinvokes
X.I find
Xto generate filenames, 
X.I Brik
Xto print the whole-file CRCs of those files, and 
X.I Brik
Xagain to immediately verify them.
X.PP
XUnder MS-DOS and VAX/VMS (and any other operating system under which
X.I Brik
Xhas been installed to expand wildcards itself), a file specified by
Xthe \-f option can itself contain wildcards in the filenames.  For
Xexample, suppose the file "wildfile" contains the following lines:
X.ex
X/bin/*.exe
X/bin/*.com
X/doc/*.doc
X.ee
XNow if we invoke 
X.I Brik
Xwith the command
X.ex
Xbrik \-Gf wildfile
X.ee
Xit will read filespecs from "wildfile," expand wildcards in each
Xfilespec, and generate whole-file CRCs for all matching files.
X.PP
XIf you are checking whole-file CRCs with the
X.B \-C
Xoption, you do not normally need to use the
X.B \-f
Xoption.  When used with
X.BR \-C ,
Xthe
X.B \-f
Xoption introduces an additional level of file naming indirection. For
Xexample, the command
X.ex
Xbrik \-C crc.lst
X.ee
Xtakes a list of CRCs and filenames from "crc.lst" and
Xverifies them.  However, the command
X.ex
Xbrik \-Cf master.lst
X.ee
Xdoes not do the same thing.  Instead, it takes a list of files from
X"master.lst," looks inside each of
X.I those
Xfiles for a list of CRCs and filenames, and verifies them.
X.PP
XAs an example of the use of \-Cf, consider this sequence:
X.ex
Xbrik \-Gb /bin/*.exe > exelist
Xbrik \-Gb /bin/*.com > comlist
Xbrik \-GT /doc/*.doc > doclist
Xbrik \-G  /doc/*.man > manlist
X.ee
XNow we have four files called "exelist," "comlist," "doclist," and
X"manlist" containing whole-file CRCs of various types.  We can test
Xthe integrity of files listed in these in four separate commands like
Xthis:
X.ex
Xbrik \-C exelist
Xbrik \-C comlist
Xbrik \-C doclist
Xbrik \-C manlist
X.ee
XBut we could also do this in a single step by first creating a file
Xcalled "biglist" that contains the names of these four files:
X.ex
Xexelist
Xcomlist
Xdoclist
Xmanlist
X.ee
Xand then use
X.B \-Cf
Xthus:
X.ex
Xbrik \-Cf biglist
X.ee
XThis causes 
X.I Brik
Xto read filenames from "biglist," look inside each of those files
X("exelist," "comlist," "doclist," and "manlist") and check the CRCs
Xfound there.  A **IX example to do the same thing in a more compact
Xway might be:
X.ex
Xcat exelist comlist doclist manlist | brik \-Cf \-
X.ee
XThe above examples are somewhat contrived, however.  We could also use
Xthe following command:
X.ex
Xbrik \-C exelist comlist doclist manlist
X.ee
X.sh "SILENT VERSUS VERBOSE VERSUS QUIET"
X.I Brik
Xaccepts options 
X.BR \-s ,
X.BR \-q ,
Xand
X.B \-v
Xthat control the degree of verbosity.
X.PP
XNormally 
X.I Brik
Xprints a message only if it detects an error.  For example,
Xif you give the command
X.ex
Xbrik \-c *.c *.h
X.ee
Xand 
X.I Brik
Xfinds that all
X.I Checksum:
Xheaders contain CRCs that match the calculated value, it prints nothing.
X.PP
XThe
X.B \-v
Xswitch makes 
X.I Brik
Xprint a message for each file tested that contains the
Xword "ok" if stored and calculated CRCs matched and "BAD" if they did not.
X.PP
XIn all messages reporting file CRCs, 
X.I Brik
Xprints the actual CRC it calculated,
Xor a row of question marks if it could not calculate one.  \fIBrik\fP
Xfails to calculate a CRC if it is trying to calculate a header-based
XCRC (commands
X.B \-c
Xand
X.BR \-g )
Xbut does not find a
X.I Checksum:
Xheader in a file.
X.PP
XThe
X.B \-s
Xswitch tells 
X.I Brik
Xto be silent.  This will cause nothing to be printed if 
X.I Brik
Xdoes not find a
X.I Checksum
Xheader or if CRCs don't match.  However, the
Xstatus code on exit is still set.  The
X.B \-s
Xoption is useful for invoking 
X.I Brik
Xfrom within a shell script (**IX) or a batch file (MS-DOS) and later
Xtesting the error code it returned when it exited.
X.PP
XThe
X.B \-s
Xswitch does not suppress the error message printed if 
X.I Brik
Xis given a filename and the file cannot be found.  For example, if
Xthe command
X.ex
Xbrik \-cs myfile
X.ee
Xis given but "myfile" does not exist, 
X.I Brik
Xwill print an
Xerror message even though the
X.B \-s
Xoption was given.
X.PP
XThe
X.B \-q
Xswitch makes 
X.I Brik
Xslightly quieter.  Its only effect is to suppress the introductory
Xcomments that are otherwise generated by the
X.B \-C
Xoption.
X.PP
X.sh "VAX/VMS BUGS"
X.TP
Xo
XUnder VAX/VMS, file manipulation is unpredictable and the VAX/VMS C
Xruntime library in particular is very unreliable.  One result is that
Xunder VAX/VMS, the
X.B \-gW
Xoption will work only for stream-LF files, which are the only type of
Xfile that VAX/VMS seems to handle correctly.  Fortunately, the
X.B \-c
Xoption will correctly work for VAX/VMS standard text files.
X.TP
Xo
XThe VAX/VMS implementation of 
X.I Brik
Xsimply ignores filenames that correspond to nonexistent files instead
Xof giving an error message.  VMS users are invited to fix this bug
X(probably somewhere in the
X.I nextfile()
Xfunction in the file
X.IR vms.c )
Xand send me the fix.
X.TP
Xo
XTo avoid annoying error messages, 
X.I Brik
Xunder VAX/VMS always exits with
Xa status code of 1.
X.TP
Xo
XDue to a problem in the VAX/VMS command interpreter, if any uppercase
Xoption characters are typed (e.g. \fB\-C\fP,
X.BR \-G ,
X.BR \-T ), 
X.I Brik
Xwill not recognize
Xthem as uppercase unless they are enclosed in double quotes.  An
Xexample of a correct command under VAX/VMS:
X.sp 1
X.nf
X\&  brik "\-GT" *.*
X.sp 1
X.fi
XAn example of a command that won't work:
X.sp 1
X\&  brik \-GT *.*
X.sh "USAGE HINTS"
XThis section discusses some ways of using 
X.I Brik.
X.TP
X\- 
X.I Brik
Xis currently used to create and verify checksums of articles posted
Xon the Usenet newsgroup comp.binaries.ibm.pc.  While reading Usenet
Xnews with
X.I rn,
Xfor example, you can verify the
X.I Checksum:
Xheader of such an article with the command:
X.sp 1
X\&  | brik \-cv
X.sp 1
XThis feeds the current article to 
X.I Brik
Xas standard input and asks it to verbosely verify the checksum.
X.TP
X\-
XC and Pascal source files that are being distributed can be given their own
X.I Checksum:
Xheaders.  The advantage of this over listing CRCs separately is
Xthat each file contains its checksum no matter where it goes.  The
Xrecipient can easily verify that each source file was received
Xintact.  This is especially valuable when source files are being sent
Xby electronic mail through an IBM mainframe-based network, such as
XBITNET, that can cause corruption of text files.
X.sp 1
XCreate the
X.I Checksum
Xheader with a text editor and initialize its value
Xwith the command:
X.sp 1
X\&  brik \-gW file ...
X.sp 1
XThe recipient can verify the checksum with the command:
X.sp 1
X\&  brik \-cv file ...
X.sp 1
X.TP
X\-
XTo keep track of any unexpected filesystem corruption or unauthorized
Xchanges to system files, 
X.I Brik
Xcan be used to create a list of
Xchecksums.  This should be done using the
X.B \-b
Xoption (all binary checksums)
Xor the
X.B \-a
Xoption (use text or binary as appropriate).  Under **IX this
Xcan be done with a command like this one:
X.sp 1
X.nf
X\&  find /bin /usr/bin /lib /usr/lib /usr/new \\
X\&   \-type f \-print | \\
X\&  grep \-v '^/usr/bin/beta' | \\
X\&  grep \-v '^/usr/new/lib/news' | \\
X\&  brik \-Gbf \- > crc.list
X.fi
X.sp 1
XThis example uses 
X.I find
Xto print the pathnames of certain files,
X.I grep
Xto
Xfilter out certain directory subtrees, and then 
X.I Brik
Xto print checksums of
Xall selected files.  Periodically a background job can be run to compare
Xthe file list against current files and report any discrepancies:
X.sp 1
X\&  brik \-C crc.lst | mail \-s 'brik output' postmaster
X.sp 1
XUnder MS-DOS, create a list of checksums with the help of
X.I Stuff,
Xa
X.IR find -like
Xfile finder program that is distributed with
X.I zoo
X2.01:
X.sp 1
X\&  stuff /bin /msdos /turboc | brik \-Gaf \- > crc.list
X.sp 1
XThis is a simple mechanism that can be used to detect unexpected file
Xchanges caused by hardware problems or malicious programs such as
Xviruses and worms.  Be warned, however, that since 
X.I Brik
Xuses a published CRC algorithm, very clever deviant programs are
Xpossible that could change a file without affecting its CRC.
X.sp 1
XTo avoid too many false alarms, only files that do not change much
X(such as system binaries) should be selected.
X.SH CHANGES
XChanges from version 1.0 are as follows.
X.TP
X\-
XThe CRC calculation has been recoded in 8086 assembly code suitable
Xfor Turbo C/MS-DOS.  As a result 
X.I Brik 2.0
Xunder MS-DOS is much faster than version 1.0.
X.TP
X\- 
XThe new 
X.B \-a 
Xflag makes 
X.I Brik
Xautomatically determine for each file whether it is text or binary
Xand calculate the CRC accordingly
X.TP
X\- 
XWhen 
X.I Brik
Xis asked to calculate a text mode CRC but the file appears to be
Xbinary, it now does not print a warning message but instead adds a
X"*" suffix to the calculated CRC to indicate that the CRC may not be
Xreliable.
X.TP
X\- 
XThe new 
X.B \-H 
Xflag makes 
X.I Brik
Xprint the formatted
X.I Checksum:
Xheader to standard output.
X.TP
X\- 
XDetection of binary files is now more reliable under MS-DOS.  If a
Xcontrol Z character occurs near the beginning of a binary file, 
X.I Brik
Xwill not be fooled by the apparent end-of-file but will in most cases
Xreliably detect that the file is binary.
X.TP
X\- 
XThe new 
X.B \-q 
Xflag suppresses the introductory comments from the output of
Xthe \-G command.
X.SH BUGS
X.I Brik
Xis designed to work with computer systems that use the 7-bit ASCII
Xcharacter set and 8-bit bytes with the eighth (parity) bit set to zero.
X.PP
X.I Brik
Xhas not been tested with computer systems that use ASCII characters
Xwith the eighth bit set or those that use EBCDIC
Xcharacters.  Although it will calculate a CRC on such machines, the
Xprobability of this CRC being the same as the one calculated on
Xmachines that use 7-bit ASCII is approximately 0.00000000023.
X.PP
X.ne 4
X.SH DIAGNOSTICS
XError messages are intended to be self-explanatory.
X.PP
XThe exit status returned
Xis 1 if
X.I Brik
Xwas invoked with incorrect arguments, else it is the number of files
Xfound with missing or invalid CRCs, but not greater than an
Xoperating-system-dependent maximum value.
X.SH COPYRIGHT
XBoth this documentation and
X.I Brik
Xare Copyright 1989 Rahul Dhesi, all
Xrights reserved.  Permission is granted to copy, use, and distribute for any
Xcommercial or noncommercial purpose in accordance with the requirements of
Xversion 1.0 of the
X.I GNU General Public license.
X.PP
XNote:  This software has not been endorsed by the Free Software Foundation,
Xthe creator of the GNU license, and I am not affiliated with that
Xorganization.
X.SH AUTHOR
X.nf
XRahul Dhesi
XUUCP: {iuvax,pur-ee}!bsu-cs!dhesi
XInternet: dhesi@bsu-cs.bsu.edu
X.fi
SHAR_EOF
fi
echo shar: "extracting 'addbfcrc.asm'" '(2254 characters)'
if test -f 'addbfcrc.asm'
then
	echo shar: "will not over-write existing file 'addbfcrc.asm'"
else
sed 's/^X//' << \SHAR_EOF > 'addbfcrc.asm'
X; ::[[ @(#) addbfcrc.asm 1.1 89/07/08 10:48:28 ]]::
X; assembly implementation of addbfcrc() for Turbo C 2.0 -- small memory model
X
X; The following code was obtained from compiling addbfcrc.c using
X; Turbo C 2.0, then hand-optimized.  In the interest of making
X; faster CRC-32 calculations available to all, I hereby release
X; the contents of this file to the public domain.  This code is for
X; the small memory model only.  It will probably need to be revised
X; for use with other C compilers.
X;                                    -- Rahul Dhesi 1989/07/08
X
X_DATA   segment word public 'DATA'
X_DATA   ends
X
X        extrn   _crccode:word
X        extrn   _crctab:word
X        public  _addbfcrc
X
X_TEXT   segment byte public 'CODE'
X
XDGROUP  group   _DATA
X        assume  cs:_TEXT,ds:DGROUP,ss:DGROUP
X
X;void addbfcrc (buf, size) char *buf, int size
X
X_addbfcrc       proc    near
X        push    bp
X        mov     bp,sp
X        sub     sp,2
X        push    si
X        push    di
X        mov     cx,word ptr [bp+6]      ;cx = size
X        mov     si,word ptr [bp+4]      ;si = buf
X
X        xor     di,di                   ;i = 0
X
X        jcxz    done                    ;if size = 0, nothing to do
X@loop:
X
X;      crccode = crctab[(int) ((crccode) ^ (buf[i])) & 0xff] ^
X;         (((crccode) >> 8) & 0x00FFFFFFL);
X
X;       (dx,ax) <- ((crccode) >> 8) & 0x00FFFFFFL
X        mov     dx,word ptr DGROUP:_crccode+2
X        mov     ax,word ptr DGROUP:_crccode
X        mov     al,ah
X        mov     ah,dl
X        mov     dl,dh
X        xor     dh,dh
X
X        mov     bx,di                   ;bx <= i
X
X        mov     bl,byte ptr [bx+si]     ;bl <- buf[i]
X
X        xor     bl,byte ptr DGROUP:_crccode ;bl <- (bl ^ crccode) & 0xff
X        xor     bh,bh                   ;bx <- bl
X        shl     bx,1
X        shl     bx,1                    ;bx <- 4 * bx (for subscript)
X
X        xor     ax,word ptr DGROUP:_crctab[bx]
X        xor     dx,word ptr DGROUP:_crctab[bx+2]
X        mov     word ptr DGROUP:_crccode+2,dx
X        mov     word ptr DGROUP:_crccode,ax
X
X        inc     di              ; i++
X        loop    @loop
Xdone:
X
X        pop     di
X        pop     si
X        mov     sp,bp
X        pop     bp
X        ret     
X_addbfcrc       endp
X
X_TEXT   ends
X        end
SHAR_EOF
fi
echo shar: "extracting 'makefile.nix'" '(1242 characters)'
if test -f 'makefile.nix'
then
	echo shar: "will not over-write existing file 'makefile.nix'"
else
sed 's/^X//' << \SHAR_EOF > 'makefile.nix'
X# Makefile for brik
X# ::[[ @(#) makefile.nix 1.2 89/07/08 10:41:32 ]]::
X
X# Please see brik.h for configuration options.
X
X# Make sure this file is called "makefile" (rename it if necessary).  Then
X# type one of the following.
X#
X# "make bsd", "make sys_v", "make ultrix", "make uport"
X#                   -- makes brik in current directory
X# "make install"    -- makes brik, then moves it into DESTDIR defined below
X# "make clean"      -- deletes "core", objects, and executable
X
X# Directory where we want to move executable brik on "make install"
XDESTDIR=/usr/local/bin/.
X
X# CFLAGS and CMORE are flags for the C compiler. 
X# LDFLAGS and LDMORE are flags for the loader.
X
XCFLAGS=-O
XCMORE=
XLDFLAGS=
XLDMORE=
X
XCC=cc
XLD=cc
X
X.c.o :
X	$(CC) -c $(CFLAGS) $(CMORE) $*.c
X
XOBJS = brik.o initcrc.o addbfcrc.o
X
Xall:
X	@echo 'Please type "make sys_v", "make bsd", "make ultrix", or "make uport"'
X
Xsys_v:
X	make "CMORE=-DSYS_V" brik
X
Xbsd:
X	make "CMORE=-DBSD" brik
X
Xuport:
X	make "CMORE=-Ml -DSYS_V" "LDMORE=-Ml" brik
X
Xultrix:
X	make "CMORE=-DBSD -DULTRIX_BUG" brik
X
Xbrik: $(OBJS)
X	$(LD) $(LDFLAGS) $(LDMORE) -o brik $(OBJS)
X
Xbrik.o: brik.c brik.h assert.h
X
Xinitcrc.o: initcrc.c brik.h
X
Xinstall: brik
X	mv brik $(DESTDIR)/brik
X
Xclean:
X	/bin/rm -f $(OBJS) core brik
SHAR_EOF
fi
echo shar: "extracting 'makefile.msc'" '(902 characters)'
if test -f 'makefile.msc'
then
	echo shar: "will not over-write existing file 'makefile.msc'"
else
sed 's/^X//' << \SHAR_EOF > 'makefile.msc'
X# Makefile for Microsoft C 5.1 thanks to Tom Horsley <tom@ssd.harris.com>.
X# Slightly modified.  You will need a good "make" utility.  Not tested.
X#                                   -- Rahul Dhesi
X
X# "make brik.exe"   -- make brik.exe in current directory
X# "make clean"      -- delete brik.exe and *.obj, needs "rm" to be present
X
X# define your library directory below
XLIB = C:\C51\LIB
X
X# see "brik.h" for other optional compile-time symbols
XCFLAGS = -DMSC51
X
XOBJS = brik.obj getopt.obj turboc.obj initcrc.obj addbfcrc.obj
X
Xbrik.exe: $(OBJS)
X	$(CC) -Febrik.exe -F 8000 $(OBJS) $(LIB)\setargv.obj /link /NOE
X
Xturboc.obj: turboc.c brik.h assert.h
X
Xinitcrc.obj: initcrc.c
X
Xbrik.obj: brik.c brik.h assert.h
X
Xgetopt.obj: getopt.c
X
X# there is also addbfcrc.asm for speed, designed to work
X# with Turbo C.  It may need to be revised for MSC.  -- R.D.
X
Xaddbfcrc.obj: addbfcrc.c
X
Xclean:
X	rm -f *.obj brik.exe
SHAR_EOF
fi
echo shar: "extracting 'assert.h'" '(754 characters)'
if test -f 'assert.h'
then
	echo shar: "will not over-write existing file 'assert.h'"
else
sed 's/^X//' << \SHAR_EOF > 'assert.h'
X/* @(#) assert.h 1.5 89/03/08 14:59:02 */
X
X/* I claim no copyright over the contents of this file.  -- Rahul Dhesi */
X
X/*
XChecksum: 3376323427      (check or update this with "brik")
X*/
X
X/*
X**   Assertions are enabled only if NDEBUG is not defined.
X**   Not all compilers define __FILE__ and __LINE__.  If yours
X**   doesn't, you can just let NDEBUG remain #defined in brik.h and no
X**   assertions will be compiled in.  Or, if you want to enable
X**   assertions, redefine the assert() macro so it works with your
X**   compiler.
X*/
X
X#ifndef OK_STDIO
X# include <stdio.h>
X# define OK_STDIO
X#endif
X
X#ifndef NDEBUG
X#define assert(E) \
X{if(!(E))fprintf(stderr,"Assertion error in %s line %d\n",__FILE__,__LINE__);}
X#else
X#define assert(E)
X#endif /* NDEBUG */
SHAR_EOF
fi
echo shar: "extracting 'descrip.mms'" '(712 characters)'
if test -f 'descrip.mms'
then
	echo shar: "will not over-write existing file 'descrip.mms'"
else
sed 's/^X//' << \SHAR_EOF > 'descrip.mms'
X# Makefile for brik -- for VAX/VMS "mms".  If you don't have mms,
X#  use the "makebrik.com" command file instead.
X#
X# Don't forget to define a symbol "brik" like this:
X#  $ brik:==$disk:[dir]brik.exe
X# where "disk" is your device name and "dir" is the directory in which
X# brik.exe is kept.
X
X# ::[[ @(#) descrip.mms 1.2 89/07/08 10:44:01 ]]::
X
X# Please see brik.h for configuration options.
X
XCFLAGS = /define=VMS
XOBJS = brik.obj, addbfcrc.obj, getopt.obj, vms.obj, initcrc.obj
XCC = cc
X
X.c.obj :
X	$(CC) $(CFLAGS) $*.c
X
Xbrik.exe : $(OBJS)
X	link/executable=brik.exe  $(OBJS), options/opt
X
Xbrik.obj : brik.c brik.h assert.h
X
Xaddbfcrc.obj : addbfcrc.c
X
Xvms.obj : vms.c
X
Xgetopt.obj : getopt.c
X
Xinitcrc.obj : initcrc.c
SHAR_EOF
fi
echo shar: "extracting 'makefile.tcc'" '(701 characters)'
if test -f 'makefile.tcc'
then
	echo shar: "will not over-write existing file 'makefile.tcc'"
else
sed 's/^X//' << \SHAR_EOF > 'makefile.tcc'
X# needs NDMAKE (tested with version 4.31), Turbo C 2.0, Turbo Assembler
X# (tested with version 1.0).  Can be easily modified to use Micoroft
X# assembler instead.  Will work with Borland's make program (tested 
X# with version 2.0) if you comment out the .SUFFIXES line.
X
XCC = tcc
XCFLAGS = -c -DTURBOC -DLINT -DNDEBUG
XLD = tcc
XLDFLAGS = -eBRIK
XAS = tasm
XASFLAGS = -mx
X
X# To use Borland's make program, comment out the following line
X.SUFFIXES : .exe .obj .asm .c
X
X.asm.obj :
X	$(AS) $(ASFLAGS) $*.asm
X
X.c.obj :
X	$(CC) $(CFLAGS) $*.c
X
XOBJS = brik.obj initcrc.obj getopt.obj turboc.obj addbfcrc.obj
X
Xbrik.exe: $(OBJS)
X	$(LD) $(LDFLAGS) $(OBJS)
X
Xbrik.obj: brik.c brik.h assert.h
X
Xaddbfcrc.obj: addbfcrc.asm
SHAR_EOF
fi
echo shar: "extracting 'addbfcrc.c'" '(651 characters)'
if test -f 'addbfcrc.c'
then
	echo shar: "will not over-write existing file 'addbfcrc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'addbfcrc.c'
X/* ::[[ @(#) addbfcrc.c 1.10 89/07/08 10:34:48 ]]:: */
X/* Adapted from zmodem source code, which contained Gary Brown's code */
X
X#ifndef LINT
Xstatic char sccsid[]="::[[ @(#) addbfcrc.c 1.10 89/07/08 10:34:48 ]]::";
X#endif
X
Xtypedef unsigned long tcrc;      /* type of crc value -- same as in brik.c */
Xextern tcrc crccode;             /* holds all crc values */
Xextern tcrc crctab[];            /* the crc calculation table */
X
Xvoid addbfcrc (buf, size)
Xregister char *buf;
Xregister int size;
X{
X   int i;
X   for (i = 0;  i < size;  i ++) {
X      crccode = crctab[(int) ((crccode) ^ (buf[i])) & 0xff] ^
X         (((crccode) >> 8) & 0x00FFFFFFL);
X   }
X}
SHAR_EOF
fi
echo shar: "extracting 'crc.lst'" '(646 characters)'
if test -f 'crc.lst'
then
	echo shar: "will not over-write existing file 'crc.lst'"
else
sed 's/^X//' << \SHAR_EOF > 'crc.lst'
X# Whole file CRCs generated by Brik v2.0.  Use "brik -C" to verify them.
X
X# CRC-32        filename
X# ------        --------
X
X1539374499      addbfcrc.asm
X2893546047      addbfcrc.c
X1943472856      assert.h
X2680503236      brik.h
X2417647845      brik.prj
X3056859226      descrip.mms
X2566277976      getopt.c
X1764729989      initcrc.c
X4163595257      makebrik.com
X3874945495      makefile.msc
X 596215296      makefile.nix
X 566402493      makefile.tcc
X 900930479      options.opt
X1446083007      turboc.cfg
X1151475469      vms.c
X4124789894      brik.c
X 775774555      turboc.c
X2597900720      brik.1
X1364707051      brik.doc
X3651763827      install
SHAR_EOF
fi
echo shar: "extracting 'makebrik.com'" '(382 characters)'
if test -f 'makebrik.com'
then
	echo shar: "will not over-write existing file 'makebrik.com'"
else
sed 's/^X//' << \SHAR_EOF > 'makebrik.com'
X$! This command file compiles brik for VAX/VMS and also defines a
X$! symbol so you can type "brik" to execute the program.
X$!
X$ cc /define=VMS brik.c
X$ cc /define=VMS addbfcrc
X$ cc /define=VMS initcrc.c
X$ cc /define=VMS vms.c
X$ cc /define=VMS getopt.c
X$ link/executable=brik.exe  brik,addbfcrc,initcrc,vms,getopt, options/opt
X$ brik:==$'f$trnlnm("sys$disk")''f$directory()'brik.exe
SHAR_EOF
fi
echo shar: "extracting 'turboc.cfg'" '(163 characters)'
if test -f 'turboc.cfg'
then
	echo shar: "will not over-write existing file 'turboc.cfg'"
else
sed 's/^X//' << \SHAR_EOF > 'turboc.cfg'
X-wamp
X-wuse
X-wrvl
X-wsig
X-wamb
X-wstv
X-wpro
X-wnod
X-wucp
X-a
X-f-
X-A
X-N
X-O
X-Z
X-k
X-d
X-Ic:\turboc\include
X-Lc:\turboc\lib
X-eC:\BRIK\BRIK
X-j10
X-g0
X-DTURBOC
X-DLINT
X-DDEBUG
SHAR_EOF
fi
echo shar: "extracting 'brik.prj'" '(93 characters)'
if test -f 'brik.prj'
then
	echo shar: "will not over-write existing file 'brik.prj'"
else
sed 's/^X//' << \SHAR_EOF > 'brik.prj'
Xaddbfcrc.obj
Xbrik.c          (assert.h brik.h)
Xgetopt.c
Xturboc.c        (assert.h)
Xinitcrc.c
SHAR_EOF
fi
echo shar: "extracting 'options.opt'" '(28 characters)'
if test -f 'options.opt'
then
	echo shar: "will not over-write existing file 'options.opt'"
else
sed 's/^X//' << \SHAR_EOF > 'options.opt'
Xsys$share:vaxcrtl.exe/share
SHAR_EOF
fi
exit 0
#	End of shell archive