[comp.sources.misc] v07i095: 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 95
Submitted-by: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
Archive-name: brik2/part02

#! /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.doc
#	initcrc.c
#	install
#	getopt.c
#	vms.c
# This archive created: Mon Jul 17 01:23:04 1989
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'brik.doc'" '(29437 characters)'
if test -f 'brik.doc'
then
	echo shar: "will not over-write existing file 'brik.doc'"
else
sed 's/^X//' << \SHAR_EOF > 'brik.doc'
X
X
X     BRIK(1)                    USER MANUAL                    BRIK(1)
X
X
X     NAME
X          brik - calculate 32-bit CRC
X
X     SYNOPSIS
X          brik -h
X          brik -gcGCbafvsqWHT file ...
X
X     DESCRIPTION
X          Brik generates and verifies 32-bit CRC values (checksums).
X          It is designed to generate CRCs for text files that are the
X          same on all computer systems that use the ASCII character
X          set, provided each text file is in the usual text file
X          format for each system. Brik will also optionally use binary
X          CRCs calculated using every byte in a file.  Such binary
X          CRCs are portable across systems for binary files that are
X          moved from system to system without any newline conversion.
X          Brik can be asked to decide by examining each file whether
X          to calculate a text mode or binary mode CRC for it.
X
X          Changes from version 1.0 are summarized at the end of this
X          document.
X
X          The general usage format is:
X
X               brik -gcGCbafvsqWHT [ file ] ...
X
X          The brackets mean that file, which is the name of a file, is
X          optional.  The three dots indicate that more than one
X          filename may be typed (separated by blanks).  Exactly one of
X          the options -c, -C, -g, -G, or -h, is required.  The -h
X          option gives a help screen.
X
X          In addition to -h, the Brik options available (as they
X          appear on the help screen) are:
X
X          -g   look for Checksum: header, generate CRC for rest of
X               file
X
X          -c   get CRC from header, verify CRC of rest of file
X
X          -G   generate CRC for entire file (add -b for binary files)
X
X          -C   verify all file CRCs from output of -G (-f is not
X               needed)
X
X          -b   use binary mode -- read file byte by byte, not line by
X               line
X
X          -a   automatically decide whether each file is text or
X               binary
X
X          -f   read filenames (wildcards ok) from specified files
X
X          -v   be verbose, report all results (else only errors are
X               reported)
X
X          -s   be silent, say nothing, just return status code
X
X          -q   be quiet, don't print header for -G
X
X          -W   after generating CRC with -g, write it to original
X               header
X
X          -H   after generating CRC with -g, print header to stdout
X
X          -T   include trailing empty lines, normally ignored (text
X               mode only)
X
X          VERIFYING CRC HEADERS
X
X          The primary intended use of Brik is to verify Checksum:
X          headers in Usenet postings and in C and Pascal source files.
X          A Checksum: header looks like this:
X
X               Checksum: 9485762645b   (verify with "brik")
X
X          The word Checksum: must occur at the beginning of a line.
X          It is followed by a colon, an optional blank, a ten-digit
X          decimal 32-bit CRC, and any arbitrary optional string such
X          as the comment shown above.  The CRC value may be followed
X          by a one-character suffix identifying the type of the CRC.
X          These suffixes are described later.
X
X          When Brik is invoked with the syntax
X
X               brik -c file ...
X
X          it will search for the Checksum: header in each specified
X          file, read the CRC value from that header, calculate the
X          CRC-32 for all lines in the file (except trailing empty
X          lines) that occur *after* the header line, and report an
X          error if the two values do not match.
X
X          CALCULATING CRC HEADERS
X
X          The command
X
X               brik -g file ...
X
X          tells Brik to look for the Checksum: header in each
X          specified file, calculate the CRC of the lines in the file
X          following the header, and print the CRC and filename without
X          changing the file in any way.  You can also ask Brik to
X          update the Checksum: header with the following command:
X
X               brik -gW file ...
X
X          This causes Brik to update the Checksum: header in the file
X          with the newly-calculated CRC.  If there is not enough space
X          for the CRC in the existing header, Brik reports an error
X          and does not change the existing header.  To initially add a
X          Checksum: header to a file, insert a line of the following
X          form into the file with a text editor:
X
X               Checksum: XXXXXXXXXX  -- this is an optional comment
X
X          The word Checksum must be at the beginning of a line.  The
X          ten `X' characters shown can be any ten characters.  They
X          will be later replaced by the calculated CRC value.  They do
X          not need to be `X'.  The comment following them is optional
X          and can be any arbitrary string of characters after the CRC
X          field, separated from it by blanks.  As an example, in a C
X          source file called main.c, you might have:
X
X               /*
X               Checksum: XXXXXXXXXX  (verify or update with brik)
X               */
X
X          Once a header like this exists in the file, invoke Brik as
X          follows:
X
X               brik -gW main.c
X
X          This will cause the ten `X' characters to be replaced with
X          the calculated checksum, giving something like this:
X
X               /*
X               Checksum: 1922837484  (verify or update with brik)
X               */
X
X          Later you can use the command
X
X               brik -c main.c
X
X          to verify that the contents of the file following the header
X          have the same CRC as the stored value.
X
X          If Brik is invoked with the -c or -g options and it cannot
X          find a Checksum: header in a file, it prints a row of
X          question marks.  If it is invoked with the -gW option and it
X          does not find enough character positions after the Checksum:
X          string to hold the CRC, it does not fill in the CRC and
X          prints an error message.
X
X          Brik can be asked to generate a complete Checksum: header
X          but print it to standard output instead of writing it to the
X          file.  Do this by adding the -H option.  If both -W and -H
X          are given, the Checksum: header will be written both to the
X          file and to standard output.
X
X          WHOLE-FILE CRCS
X
X          A "whole-file" CRC calculation is done for the entire
X          contents of a file, without looking for a Checksum: header.
X          The command
X
X               brik -G file ...
X
X          asks Brik to do this calculation for all specified files.
X          The output from this command is a list of files and their
X          whole-file CRCs.  It is sent to the standard output stream,
X          which in most cases is your screen.  The output should be
X          saved in a file by redirecting it.  For example, the command
X
X               brik -G *.h *.c > crc.lst
X
X          on an MS-DOS system might yield the following in the output
X          file crc.lst:
X
X               # CRC-32        filename
X               # ------        --------
X
X               2566277976      getopt.c
X                100594287      brik.c
X               1151475469      vms.c
X               3929503738      turboc.c
X               2424271922      addbfcrc.c
X               1943472856      assert.h
X               2601923477      brik.h
X
X          The output of the -G option is in free format.  The output
X          file may be edited by hand.  Empty lines and lines beginning
X          with '#' will be ignored by Brik when it is later asked to
X          read this file.
X
X          This list of filenames and whole-file CRCs may be verified
X          by a command like this:
X
X               brik -C crc.lst
X
X          This makes Brik read the file crc.lst, get the CRCs and
X          filenames from it, do the CRC calculation again for each
X          file, and report an error if it does not match the CRC
X          recorded inside crc.lst.
X
X          **IX and MS-DOS users (and others who can pipe the output of
X          one command into another) could use a command like the
X          following to see if Brik's -G and -C options are working:
X
X               brik -G file ... | brik -C
X
X          This invokes "brik -G" on some files, sending the output to
X          a pipe where it becomes the input of "brik -C".  If no
X          filename is specified, Brik reads from standard input, so
X          "brik -C" will read from the pipe and concurrently verify
X          all the CRCs that are being generated by "brik -G".
X
X          Whole-file CRCs are normally generated in text mode, in
X          which a file is treated as lines of text.  You can also
X          generate whole-file CRCs in binary mode.  See below.
X
X          BINARY VERSUS TEXT MODE
X
X          Brik can work in two different modes.  The most common mode,
X          used unless you specify otherwise, is text mode.
X
X          In this mode Brik reads all files line by line, and forces
X          each line of text to be terminated by a newline character of
X          constant value before doing a CRC calculation.  Thus, no
X          matter what newline character is used by your system, the
X          CRC calculation will be unaffected.  This means that whether
X          your operating system uses linefeeds to terminate lines
X          (e.g. **IX), or a carriage return and a linefeed (e.g. MS-
X          DOS) or a carriage return only (e.g. Macintosh) or nothing
X          but a record length field (e.g. VAX/VMS), the CRC
X          calculation in text mode gives the same results.
X
X          If a file is not intended to be a text file, the text mode
X          CRC calculated by Brik may not be reliable and may be
X          different on different systems.  If Brik is calculating a
X          text mode CRC on a file that appears to contain binary data,
X          it still calculates the text-mode CRC but adds a "*"
X          character after the CRC to indicate to warn the user.
X
X          Brik can be asked to operate in binary mode by adding a -b
X          option.  Binary mode is applicable only to the -G command,
X          which acts on whole files.  Thus
X
X               brik -G file ...
X
X          finds whole-file CRCs of all specified files in text mode,
X          while
X
X               brik -Gb file ...
X
X          does the same in binary mode.  In binary mode Brik simply
X          reads and calculates the CRC for all bytes in a file.  If a
X          file is moved from one system to another without any newline
X          conversion or any other changes, Brik should calculate the
X          same binary mode CRC for it on both systems.
X
X          The output from "brik -Gb" includes a trailing b suffix in
X          each CRC, so "brik -C" will correctly use binary mode for
X          such CRCs and it is never necessary to type "brik -Cb"
X          instead.
X
X          In its auto-check mode, Brik will itself examine each file
X          and determine whether it is a text or binary file and
X          calculate a CRC accordingly.  To do this, use the -a option.
X          Although Brik can determine the type of each file with a
X          high degree of reliability, it is still possible for it to
X          come to a wrong conclusion about some files.
X
X          The output from "brik -Ga" will include a trailing b
X          character in the CRC for those files that appeared to be
X          binary to Brik.  You may find both text and binary CRCs in
X          the output.
X
X          TRAILING EMPTY LINES
X
X          The normal behavior of Brik in text mode is to ignore any
X          trailing empty lines in a file.  An empty line is a line
X          that contains nothing, not even blanks or tabs.  (Just
X          hitting a carriage return when you are editing a text file
X          usually produces an empty line.)  If manipulating a text
X          file causes trailing empty lines to be added or deleted, the
X          CRC calculated by Brik will be unaffected.  You can override
X          this if necessary with the -T option, which makes Brik
X          include trailing empty lines in the CRC calculation.  For
X          example,
X
X               brik -gWT
X
X          will update the Checksum: header with a CRC that includes
X          all lines in a text file.  Similarly
X
X               brik -GT
X
X          will find whole-file CRCs that include all lines in a text
X          file.
X
X          When Brik is given the -T option, it adds a T suffix to each
X          generated CRC.  Then, when the CRC is verified with -c or
X          -C, Brik will correctly include trailing empty lines when
X          needed without having to be explicitly told to do so.
X
X          In binary mode Brik always reads all bytes in a file, so it
X          does not ignore trailing empty lines, and the -T switch is
X          not needed.
X
X          The effects of the -T and -b options are mutually exclusive.
X          If both are given, whichever is used later overrides the
X          first.  So -bT is equivalent to -T and -Tb is equivalent to
X          -T.
X
X          FILENAME CONVENTIONS
X
X          Under MS-DOS and VAX/VMS, wildcards are allowed on the
X          command line and will be expanded by Brik.  Under **IX,
X          wildcards are expected to be expanded by the shell and are
X          not expanded by Brik.  If no filename is given, Brik reads
X          its standard input.  By default this is keyboard input, but
X          it is expected that input will usually be redirected to come
X          from a file or a pipe.  Also, if a filename is explicitly
X          specified as a dash ("-"), it stands for standard input.
X
X          The following five commands (valid under the **IX operating
X          system)
X
X               brik -c myfile            # "myfile"
X               brik -c < myfile          # stdin = "myfile"
X               cat myfile | brik -c      # stdin = a pipe
X               brik -c - < myfile        # "-" = stdin = "myfile"
X               cat myfile | brik -c -    # "-" = stdin = a pipe
X
X          all have the effect of verifying the Checksum: header in the
X          file myfile.
X
X          Standard input can also be read when using the -C option.
X          For example, suppose we have already given the command
X
X               brik -G *.c *.h > crc.lst
X
X          to create a file called "crc.lst" that contains a list of
X          whole-file CRCs.  We can now verify the integrity of these
X          files with any of the following commands:
X
X               brik -C crc.lst          # "crc.lst"
X               brik -C < crc.lst        # stdin = "crc.lst"
X               brik -C - < crc.lst      # "-" = stdin = "crc.lst"
X               cat crc.lst | brik -C    # stdin = a pipe
X               cat crc.lst | brik -C -  # "-" = stdin = a pipe
X
X
X          INDIRECT FILE NAMING
X
X          The -f option allows you to have filenames in a list rather
X          than on the command line.  For example, suppose you want to
X          generate whole-file CRCs of files whose names are selected
X          by some other program.  You could use find (under **IX) or
X          Stuff (under MS-DOS) to generate a list of filenames.  When
X          the -f option is given, Brik reads filenames, one per line,
X          from the file(s) specified.  Thus you could do the
X          following:
X
X               find . -mtime +3 -print > flist
X               brik -Gf flist > crc.lst
X
X          The first command asks find to generate a list of names of
X          all files that were modified more than 3 days ago, and sends
X          the output to the file flist.  The contents of flist might
X          now look like this, as an example:
X
X               ./sez.doc
X               ./brik.doc
X               ./stuff.doc
X               ./looz.doc
X
X          The second command above asks Brik to read the file called
X          flist, get a list of filenames from it, one per line, and
X          generate the whole-file CRC of each of these files.  We
X          additionally redirect the output of "brik -Gf" to the file
X          called crc.lst.  Given the above contents of flist, the
X          following two commands are exactly equivalent:
X
X               brik -Gf flist >crc.lst
X               brik -G ./sez.doc ./brik.doc ./stuff.doc ./looz.doc >crc.lst
X
X          The advantage of the -f option is that once you have
X          filenames in a file, you need not type them again at the
X          command line.  The -f option also allows you to feed Brik
X          through a pipe filenames generated by another program.
X          Consider this command:
X
X               find . -mtime +3 -print | brik -Gf - > crc.lst
X
X          Under **IX this concurrently invokes both find and Brik.  As
X          find generates a filename and sends it to its standard
X          output (a pipe), Brik reads the filename from its standard
X          input and generates its whole-file CRC.  The following
X          pipeline
X
X               find . -mtime +3 -print | brik -Gf - | brik -C -
X
X          invokes find to generate filenames, Brik to print the
X          whole-file CRCs of those files, and Brik again to
X          immediately verify them.
X
X          Under MS-DOS and VAX/VMS (and any other operating system
X          under which Brik has been installed to expand wildcards
X          itself), a file specified by the -f option can itself
X          contain wildcards in the filenames.  For example, suppose
X          the file "wildfile" contains the following lines:
X
X               /bin/*.exe
X               /bin/*.com
X               /doc/*.doc
X
X          Now if we invoke Brik with the command
X
X               brik -Gf wildfile
X
X          it will read filespecs from "wildfile," expand wildcards in
X          each filespec, and generate whole-file CRCs for all matching
X          files.
X
X          If you are checking whole-file CRCs with the -C option, you
X          do not normally need to use the -f option.  When used with
X          -C, the -f option introduces an additional level of file
X          naming indirection. For example, the command
X
X               brik -C crc.lst
X
X          takes a list of CRCs and filenames from "crc.lst" and
X          verifies them.  However, the command
X
X               brik -Cf master.lst
X
X          does not do the same thing.  Instead, it takes a list of
X          files from "master.lst," looks inside each of those files
X          for a list of CRCs and filenames, and verifies them.
X
X          As an example of the use of -Cf, consider this sequence:
X
X               brik -Gb /bin/*.exe > exelist
X               brik -Gb /bin/*.com > comlist
X               brik -GT /doc/*.doc > doclist
X               brik -G  /doc/*.man > manlist
X
X          Now we have four files called "exelist," "comlist,"
X          "doclist," and "manlist" containing whole-file CRCs of
X          various types.  We can test the integrity of files listed in
X          these in four separate commands like this:
X
X               brik -C exelist
X               brik -C comlist
X               brik -C doclist
X               brik -C manlist
X
X          But we could also do this in a single step by first creating
X          a file called "biglist" that contains the names of these
X          four files:
X
X               exelist
X               comlist
X               doclist
X               manlist
X
X          and then use -Cf thus:
X
X               brik -Cf biglist
X
X          This causes Brik to read filenames from "biglist," look
X          inside each of those files ("exelist," "comlist," "doclist,"
X          and "manlist") and check the CRCs found there.  A **IX
X          example to do the same thing in a more compact way might be:
X
X               cat exelist comlist doclist manlist | brik -Cf -
X
X          The above examples are somewhat contrived, however.  We
X          could also use the following command:
X
X               brik -C exelist comlist doclist manlist
X
X
X          SILENT VERSUS VERBOSE VERSUS QUIET
X
X          Brik accepts options -s, -q, and -v that control the degree
X          of verbosity.
X
X          Normally Brik prints a message only if it detects an error.
X          For example, if you give the command
X
X               brik -c *.c *.h
X
X          and Brik finds that all Checksum: headers contain CRCs that
X          match the calculated value, it prints nothing.
X
X          The -v switch makes Brik print a message for each file
X          tested that contains the word "ok" if stored and calculated
X          CRCs matched and "BAD" if they did not.
X
X          In all messages reporting file CRCs, Brik prints the actual
X          CRC it calculated, or a row of question marks if it could
X          not calculate one.  Brik fails to calculate a CRC if it is
X          trying to calculate a header-based CRC (commands -c and -g)
X          but does not find a Checksum: header in a file.
X
X          The -s switch tells Brik to be silent.  This will cause
X          nothing to be printed if Brik does not find a Checksum
X          header or if CRCs don't match.  However, the status code on
X          exit is still set.  The -s option is useful for invoking
X          Brik from within a shell script (**IX) or a batch file (MS-
X          DOS) and later testing the error code it returned when it
X          exited.
X
X          The -s switch does not suppress the error message printed if
X          Brik is given a filename and the file cannot be found.  For
X          example, if the command
X
X               brik -cs myfile
X
X          is given but "myfile" does not exist, Brik will print an
X          error message even though the -s option was given.
X
X          The -q switch makes Brik slightly quieter.  Its only effect
X          is to suppress the introductory comments that are otherwise
X          generated by the -C option.
X
X          VAX/VMS BUGS
X
X          o    Under VAX/VMS, file manipulation is unpredictable and
X               the VAX/VMS C runtime library in particular is very
X               unreliable.  One result is that under VAX/VMS, the -gW
X               option will work only for stream-LF files, which are
X               the only type of file that VAX/VMS seems to handle
X               correctly.  Fortunately, the -c option will correctly
X               work for VAX/VMS standard text files.
X
X          o    The VAX/VMS implementation of Brik simply ignores
X               filenames that correspond to nonexistent files instead
X               of giving an error message.  VMS users are invited to
X               fix this bug (probably somewhere in the nextfile()
X               function in the file vms.c) and send me the fix.
X
X          o    To avoid annoying error messages, Brik under VAX/VMS
X               always exits with a status code of 1.
X
X          o    Due to a problem in the VAX/VMS command interpreter, if
X               any uppercase option characters are typed (e.g. -C, -G,
X               -T), Brik will not recognize them as uppercase unless
X               they are enclosed in double quotes.  An example of a
X               correct command under VAX/VMS:
X
X                 brik "-GT" *.*
X
X               An example of a command that won't work:
X
X                 brik -GT *.*
X
X          USAGE HINTS
X
X          This section discusses some ways of using Brik.
X
X          -    Brik is currently used to create and verify checksums
X               of articles posted on the Usenet newsgroup
X               comp.binaries.ibm.pc.  While reading Usenet news with
X               rn, for example, you can verify the Checksum: header of
X               such an article with the command:
X
X                 | brik -cv
X
X               This feeds the current article to Brik as standard
X               input and asks it to verbosely verify the checksum.
X
X          -    C and Pascal source files that are being distributed
X               can be given their own Checksum: headers.  The
X               advantage of this over listing CRCs separately is that
X               each file contains its checksum no matter where it
X               goes.  The recipient can easily verify that each source
X               file was received intact.  This is especially valuable
X               when source files are being sent by electronic mail
X               through an IBM mainframe-based network, such as BITNET,
X               that can cause corruption of text files.
X
X               Create the Checksum header with a text editor and
X               initialize its value with the command:
X
X                 brik -gW file ...
X
X               The recipient can verify the checksum with the command:
X
X                 brik -cv file ...
X
X          -    To keep track of any unexpected filesystem corruption
X               or unauthorized changes to system files, Brik can be
X               used to create a list of checksums.  This should be
X               done using the -b option (all binary checksums) or the
X               -a option (use text or binary as appropriate).  Under
X               **IX this can be done with a command like this one:
X
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
X               This example uses find to print the pathnames of
X               certain files, grep to filter out certain directory
X               subtrees, and then Brik to print checksums of all
X               selected files.  Periodically a background job can be
X               run to compare the file list against current files and
X               report any discrepancies:
X
X                 brik -C crc.lst | mail -s 'brik output' postmaster
X
X               Under MS-DOS, create a list of checksums with the help
X               of Stuff, a find-like file finder program that is
X               distributed with zoo 2.01:
X
X                 stuff /bin /msdos /turboc | brik -Gaf - > crc.list
X
X               This is a simple mechanism that can be used to detect
X               unexpected file changes caused by hardware problems or
X               malicious programs such as viruses and worms.  Be
X               warned, however, that since Brik uses a published CRC
X               algorithm, very clever deviant programs are possible
X               that could change a file without affecting its CRC.
X
X               To avoid too many false alarms, only files that do not
X               change much (such as system binaries) should be
X               selected.
X
X     CHANGES
X          Changes from version 1.0 are as follows.
X
X          -    The CRC calculation has been recoded in 8086 assembly
X               code suitable for Turbo C/MS-DOS.  As a result Brik 2.0
X               under MS-DOS is much faster than version 1.0.
X
X          -    The new -a flag makes Brik automatically determine for
X               each file whether it is text or binary and calculate
X               the CRC accordingly
X
X          -    When Brik is asked to calculate a text mode CRC but the
X               file appears to be binary, it now does not print a
X               warning message but instead adds a "*" suffix to the
X               calculated CRC to indicate that the CRC may not be
X               reliable.
X
X          -    The new -H flag makes Brik print the formatted
X               Checksum: header to standard output.
X
X          -    Detection of binary files is now more reliable under
X               MS-DOS.  If a control Z character occurs near the
X               beginning of a binary file, Brik will not be fooled by
X               the apparent end-of-file but will in most cases
X               reliably detect that the file is binary.
X
X          -    The new -q flag suppresses the introductory comments
X               from the output of the -G command.
X
X     BUGS
X          Brik is designed to work with computer systems that use the
X          7-bit ASCII character set and 8-bit bytes with the eighth
X          (parity) bit set to zero.
X
X          Brik has not been tested with computer systems that use
X          ASCII characters with the eighth bit set or those that use
X          EBCDIC characters.  Although it will calculate a CRC on such
X          machines, the probability of this CRC being the same as the
X          one calculated on machines that use 7-bit ASCII is
X          approximately 0.00000000023.
X
X     DIAGNOSTICS
X          Error messages are intended to be self-explanatory.
X
X          The exit status returned is 1 if Brik was invoked with
X          incorrect arguments, else it is the number of files found
X          with missing or invalid CRCs, but not greater than an
X          operating-system-dependent maximum value.
X
X     COPYRIGHT
X          Both this documentation and Brik are Copyright 1989 Rahul
X          Dhesi, all rights reserved.  Permission is granted to copy,
X          use, and distribute for any commercial or noncommercial
X          purpose in accordance with the requirements of version 1.0
X          of the GNU General Public license.
X
X          Note:  This software has not been endorsed by the Free
X          Software Foundation, the creator of the GNU license, and I
X          am not affiliated with that organization.
X
X     AUTHOR
X          Rahul Dhesi
X          UUCP: {iuvax,pur-ee}!bsu-cs!dhesi
X          Internet: dhesi@bsu-cs.bsu.edu
X
X     BRIK(1)                    USER MANUAL                (1989/07/11)
SHAR_EOF
fi
echo shar: "extracting 'initcrc.c'" '(7919 characters)'
if test -f 'initcrc.c'
then
	echo shar: "will not over-write existing file 'initcrc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'initcrc.c'
X/* ::[[ @(#) initcrc.c 1.1 89/07/08 10:49:00 ]]:: */
X/* Some of the following CRC-32 stuff is from zmodem source code */
X
X#ifndef LINT
Xstatic char sccsid[]="::[[ @(#) initcrc.c 1.1 89/07/08 10:49:00 ]]::";
X#endif
X
X/*
XI claim no copyright over the contents of this file.  However,
Xyou are requested to preserve all author attributions.
X
X                                     -- Rahul Dhesi
X
XChecksum: 2467278882      (check or update this with "brik")
X*/
X
X#include "brik.h"
X#define TABSIZE         256        /* no of entries in table */
Xtypedef unsigned long tcrc;       /* type of crc value -- same as in brik.c */
X
Xtcrc crccode;                     /* holds all crc values */
X
X/*
X * Copyright (C) 1986 Gary S. Brown.  You may use this program, or
X * code or tables extracted from it, as desired without restriction.
X */
X
X/* First, the polynomial itself and its table of feedback terms.  The  */
X/* polynomial is                                                       */
X/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
X/* Note that we take it "backwards" and put the highest-order term in  */
X/* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
X/* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
X/* the MSB being 1.                                                    */
X
X/* Note that the usual hardware shift register implementation, which   */
X/* is what we're using (we're merely optimizing it by doing eight-bit  */
X/* chunks at a time) shifts bits into the lowest-order term.  In our   */
X/* implementation, that means shifting towards the right.  Why do we   */
X/* do it this way?  Because the calculated CRC must be transmitted in  */
X/* order from highest-order term to lowest-order term.  UARTs transmit */
X/* characters in order from LSB to MSB.  By storing the CRC this way,  */
X/* we hand it to the UART in the order low-byte to high-byte; the UART */
X/* sends each low-bit to hight-bit; and the result is transmission bit */
X/* by bit from highest- to lowest-order term without requiring any bit */
X/* shuffling on our part.  Reception works similarly.                  */
X
X/* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
X/*                                                                     */
X/*     The table can be generated at runtime if desired; code to do so */
X/*     is shown later.  It might not be obvious, but the feedback      */
X/*     terms simply represent the results of eight shift/xor opera-    */
X/*     tions for all combinations of data and CRC register values.     */
X/*                                                                     */
X/*     The values must be right-shifted by eight bits by the "updcrc"  */
X/*     logic; the shift must be unsigned (bring in zeroes).  On some   */
X/*     hardware you could probably optimize the shift in assembler by  */
X/*     using byte-swap instructions.                                   */
X
X/* if GENTAB is not defined, a static CRC table is used */
X#ifndef GENTAB
Xtcrc crctab[] = { /* CRC polynomial 0xedb88320 */
X      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
X      0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
X      0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
X      0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
X      0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
X      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
X      0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
X      0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
X      0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
X      0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
X      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
X      0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
X      0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
X      0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
X      0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
X      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
X      0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
X      0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
X      0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
X      0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
X      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
X      0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
X      0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
X      0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
X      0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
X      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
X      0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
X      0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
X      0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
X      0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
X      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
X      0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
X      0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
X      0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
X      0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
X      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
X      0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
X      0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
X      0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
X      0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
X      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
X      0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
X      0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
X      0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
X      0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
X      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
X      0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
X      0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
X      0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
X      0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
X      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
X      0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
X      0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
X      0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
X      0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
X      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
X      0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
X      0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
X      0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
X      0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
X      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
X      0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
X      0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
X      0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
X};
X#else
Xtcrc crctab[TABSIZE];      /* to be filled in below */
X#endif /* GENTAB */
X
X/* If GENTAB is defined, we generate the CRC table at runtime */
X#ifdef GENTAB
X/*
XThe function mkcrctab() generates a CRC-32 table at runtime.  The table
Xgenerated is identical to that shown above.
X
XBased on explanation and code in "C Programmer's Guide to Serial
XCommunications" by Joe Campbell.
X
XRahul Dhesi, 28 March 1989.
X*/
X
X#define CRC_32          0xedb88320L    /* CRC-32 polynomial */
X
X/* calculates CRC of one item */
Xtcrc onecrc (item)
Xint item;
X{
X   int i;
X   tcrc accum = 0;
X   item <<= 1;
X   for (i = 8;  i > 0;  i--) {
X      item >>= 1;
X      if ((item ^ accum) & 0x0001)
X         accum = (accum >> 1) ^ CRC_32;
X      else
X         accum >>= 1;
X   }
X   return (accum);
X}
X
X#ifdef ANSIPROTO
Xtcrc onecrc (int);
X#endif
X
X/* generates CRC table, calling onecrc() to make each term */
Xvoid mkcrctab()
X{
X   int i;
X   for (i = 0;  i < TABSIZE;  i++)
X      crctab[i] = onecrc (i);
X}
X
X#ifdef TESTTAB
X/* test code -- prints entire table to standard output */
X
X#include <stdio.h>
X
Xmain()
X{
X   int i;
X   mkcrctab();       /* make CRC table */
X
X   /* now print it */
X   for (i = 0;  i < TABSIZE;  i ++) {
X      if ((i % 4) == 0 && i > 0)
X         printf ("\n");
X      printf ("0x%08lx   ", (unsigned long) crctab[i]);
X   }
X   printf ("\n");
X}
X#endif /* TESTTAB */
X
X#endif /* GENTAB */
SHAR_EOF
fi
echo shar: "extracting 'install'" '(4069 characters)'
if test -f 'install'
then
	echo shar: "will not over-write existing file 'install'"
else
sed 's/^X//' << \SHAR_EOF > 'install'
X                          
X                             INSTALLING BRIK 2.0
X
XThe following files should be in this package.
X
X  name             description
X  -----------      -----------
X  addbfcrc.c       (generic) brik C source
X  assert.h         (generic) brik C source
X  brik.c           (generic) brik C source
X  brik.h           (generic) brik C source
X  initcrc.c        (generic) brik C source
X  getopt.c         (generic) getopt function C source
X
X  install          (generic) installation instructions
X  brik.doc         (generic) formatted user manual
X  crc.lst          (generic) CRCs -- verify with "brik -Cv"
X
X  makefile.nix     (**IX) make file
X  brik.1           (**IX) manual for formatting with "nroff -man"
X
X  addbfcrc.asm     (MS-DOS/Turbo C) 8086 assembly code
X  brik.prj         (MS-DOS/Turbo C) project file for tc.exe
X  makefile.tcc     (MS-DOS/Turbo C) make file
X  turboc.c         (MS-DOS/Turbo C) brik C source
X  turboc.cfg       (MS-DOS/Turbo C) configuration file for tcc.exe
X
X  descrip.mms      (VAX/VMS) make file
X  makebrik.com     (VAX/VMS) script to compile and link
X  options.opt      (VAX/VMS) options for linker
X  vms.c            (VAX/VMS) brik C source
X
X  makefile.msc     (MS-DOS/MSC) make file (not tested)
X
XBrik is believed to compile and execute in the following environments:
X
X1.   Turbo C 2.0, MS-DOS 2.x or higher
X2.   VAX/VMS 4.7 with VAX/VMS C 2.4
X3.   4.3BSD from Berkeley on a VAX-11/785
X4.   Microport System V/AT version 2.2
X
XMake sure all the needed files are in the current directory.  Then follow
Xinstructions below for your specific type of system.  If doing so doesn't
Xgive you a running copy of brik, read brik.h and experiment with the various
Xcompilation options.
X
X1.   MS-DOS, Turbo C 2.0
X
XExamine the files "makefile.tcc" and "turboc.cfg".  Edit them if necessary
Xto make sure they have the correct names for your include and library
Xdirectories.
X
XTo use the command-line compiler, you will need a good make program such as
XNDMAKE (tested with version 4.31).  Rename the file "makefile.tcc" to
X"makefile" and follow instructions in it.
X
XTo use the Turbo C integrated environment, first convert the supplied
Xconfiguration file "turboc.cfg" to "tcconfig.tc" using the "tcconfig.exe"
Xprogram supplied with Turbo C.  A project file "brik.prj" is supplied. 
XAssemble addbfcrc.asm using either Microsoft's assembler or Borland's Turbo
Xassembler (be sure to use the /mx switch).  Then compile as usual with the
Xintegrated environment.
X
X2.   VAX/VMS
X
X2.1.   If you have DEC's make utility called "mms", proceed as follows:
X
X     a.   Delete "makefile" so mms won't get confused
X     b.   Type "mms" at the VMS prompt
X     c.   If all goes well, mms will compile and link the necessary files,
X          yielding "brik.exe" in the current directory.
X     d.   Move "brik.exe" wherever you want it and define a symbol with
X          a command line of the following type:
X
X               $ brik :== $my$disk:[bindir]brik.exe
X
X         where my$disk is the name of your device and bindir is the name
X         of the directory in which "brik.exe" is kept.
X
X2.2.  If you don't have "mms", use the command file supplied.  Invoke it as:
X
X     $ @makebrik
X
XWhen it exits, brik.exe should have been created in your current
Xdirectory, and the symbol "brik" should also have been defined for
Xyou.  If you move brik.exe to another directory be sure to redefine the
Xsymbol "brik" correctly as described above in part I.
X
XBe sure to read the section in the manual on VAX/VMS bugs.
X
X3.   4.xBSD, System V, and other **IX-like environments
X
XRename the file "makefile.nix" to "makefile".
X
XGive the command "make sys_v" or "make bsd" as appropriate.
X
XIf you are using Ultrix, you may wish to type "make ultrix" rather than "make
Xbsd" to get around an Ultrix bug described in "brik.h".
X
XIf you wish to use the large model library under Microport System V/AT, type
X"make uport".  To use the default small model library, type "make sys_v".
X
X                                  -- Rahul Dhesi
X                                     1989/07/11
SHAR_EOF
fi
echo shar: "extracting 'getopt.c'" '(2808 characters)'
if test -f 'getopt.c'
then
	echo shar: "will not over-write existing file 'getopt.c'"
else
sed 's/^X//' << \SHAR_EOF > 'getopt.c'
X/* ::[[ @(#) getopt.c 1.5 89/03/11 05:40:23 ]]:: */
X#ifndef LINT
Xstatic char sccsid[]="::[[ @(#) getopt.c 1.5 89/03/11 05:40:23 ]]::";
X#endif
X
X/*
XChecksum: 1099544938      (check or update this with "brik")
X*/
X
X/*
X * Here's something you've all been waiting for:  the AT&T public domain
X * source for getopt(3).  It is the code which was given out at the 1985
X * UNIFORUM conference in Dallas.  I obtained it by electronic mail
X * directly from AT&T.  The people there assure me that it is indeed
X * in the public domain.
X *
X * There is no manual page.  That is because the one they gave out at
X * UNIFORUM was slightly different from the current System V Release 2
X * manual page.  The difference apparently involved a note about the
X * famous rules 5 and 6, recommending using white space between an option
X * and its first argument, and not grouping options that have arguments.
X * Getopt itself is currently lenient about both of these things White
X * space is allowed, but not mandatory, and the last option in a group can
X * have an argument.  That particular version of the man page evidently
X * has no official existence, and my source at AT&T did not send a copy.
X * The current SVR2 man page reflects the actual behavor of this getopt.
X * However, I am not about to post a copy of anything licensed by AT&T.
X */
X
X/*
XMinor modifications by Rahul Dhesi 1989/03/06
X*/
X
X#include "brik.h"
X
X#ifdef ANSIPROTO
Xint strcmp (char *, char *);
Xchar *strchr (char *, char);
X#endif
X
X#include <stdio.h>
X
X/* Avoid possible compiler warning if we simply redefine NULL or EOF */
X#define XNULL   0
X#define XEOF (-1)
X
X#define ERR(szz,czz) if(opterr){fprintf(stderr,"%s%s%c\n",argv[0],szz,czz);}
X
Xextern int strcmp();
Xextern char *strchr();
X
Xint   opterr = 1;
Xint   optind = 1;
Xint   optopt;
Xchar  *optarg;
X
Xint
Xgetopt(argc, argv, opts)
Xint   argc;
Xchar  **argv, *opts;
X{
X   static int sp = 1;
X   register int c;
X   register char *cp;
X
X   if(sp == 1)
X      if(optind >= argc ||
X         argv[optind][0] != '-' || argv[optind][1] == '\0')
X         return(XEOF);
X      else if(strcmp(argv[optind], "--") == XNULL) {
X         optind++;
X         return(XEOF);
X      }
X   optopt = c = argv[optind][sp];
X   if(c == ':' || (cp=strchr(opts, c)) == XNULL) {
X      ERR(": illegal option -- ", c);
X      if(argv[optind][++sp] == '\0') {
X         optind++;
X         sp = 1;
X      }
X      return('?');
X   }
X   if(*++cp == ':') {
X      if(argv[optind][sp+1] != '\0')
X         optarg = &argv[optind++][sp+1];
X      else if(++optind >= argc) {
X         ERR(": option requires an argument -- ", c);
X         sp = 1;
X         return('?');
X      } else
X         optarg = argv[optind++];
X      sp = 1;
X   } else {
X      if(argv[optind][++sp] == '\0') {
X         sp = 1;
X         optind++;
X      }
X      optarg = XNULL;
X   }
X   return(c);
X}
SHAR_EOF
fi
echo shar: "extracting 'vms.c'" '(2419 characters)'
if test -f 'vms.c'
then
	echo shar: "will not over-write existing file 'vms.c'"
else
sed 's/^X//' << \SHAR_EOF > 'vms.c'
X/*
X**   A wildcard expansion function for VAX/VMS
X**   -- Rahul Dhesi
X*/
X/* ::[[ @(#) vms.c 1.5 89/03/10 19:09:28 ]]:: */
X#ifndef LINT
Xstatic char sccsid[]="::[[ @(#) vms.c 1.5 89/03/10 19:09:28 ]]::";
X#endif
X
X/*
XChecksum: 3221488897     (verify or update with "brik")
X*/
X
X#include <descrip.h>
X
X#define  FMAX  3        /* Number of different filename patterns */
X#define  PATHSIZE 1024  /* buffer area to store pathname */
X
Xchar *nextfile (what, filespec, fileset)
Xint what;                        /* whether to initialize or match      */
Xregister char *filespec;         /* filespec to match if initializing   */
Xregister int fileset;            /* which set of files                  */
X{
X   int status;
X   char *p;                      /* temp ptr */
X   struct dsc$descriptor_s d_fwild, d_ffound;
X   static int first_time [FMAX+1];
X   static char saved_fspec [FMAX+1][PATHSIZE];  /* our own copy of filespec */
X   static char found_fspec [FMAX+1][PATHSIZE];  /* matched filename */
X   static unsigned long context [FMAX+1]; /* needed by VMS */
X   if (what == 0) {
X      strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
X      first_time[fileset] = 1;
X      return (0);
X   }
X
X   /* Reach here if what is not 0, so it must be 1 */
X
X   /* Create a descriptor for the wildcarded filespec */
X   d_fwild.dsc$w_length = strlen (saved_fspec[fileset]);
X   d_fwild.dsc$a_pointer = saved_fspec[fileset];
X   d_fwild.dsc$b_class = DSC$K_CLASS_S;
X   d_fwild.dsc$b_dtype = DSC$K_DTYPE_T;
X
X   d_ffound.dsc$w_length = sizeof (found_fspec[fileset]);
X   d_ffound.dsc$a_pointer = found_fspec[fileset];
X   d_ffound.dsc$b_class = DSC$K_CLASS_S;
X   d_ffound.dsc$b_dtype = DSC$K_DTYPE_T;
X
X   if (first_time[fileset]) {
X      first_time[fileset] = 0;
X      context[fileset] = 0L;   /* tell VMS this is first search */
X   }
X   status = LIB$FIND_FILE (&d_fwild, &d_ffound, &context[fileset]);
X   status = status & 1; /* use only lowest bit */
X
X   if (status == 0) {
X      LIB$FIND_FILE_END (&context[fileset]);
X      return ((char *) 0);
X   } else {
X      found_fspec[fileset][d_ffound.dsc$w_length] = '\0'; /* just in case */
X      p = found_fspec[fileset];
X      while (*p != ' ' && *p != '\0')
X         p++;
X      if (*p != '\0')
X         *p = '\0';
X      return (found_fspec[fileset]);
X   }
X}
X
X/* Compensate for bug in VAX/VMS C exit() function */
X
X#ifdef exit
X# undef exit
X#endif
X
Xint bugexit (n)
Xint n;
X{
X   exit (1);
X}
SHAR_EOF
fi
exit 0
#	End of shell archive