How CRCs are Used in Progress R-Code

Grant P. Maizels

Copyright (C) Grant P. Maizels 2001

Introduction

CRCs are used within Progress to provide internal consistency checks so that it can be validated at run time that compiled r-code matches the structure of the database it is run against. There are several ways that CRCs are used for this, they are described below. Two tools, procrc and crc are provided to assist in checking source code matches r-code.

What is a CRC?

The acronym CRC stands for Cyclic Redundancy Checksum. A CRC is a mathematical transformation applied to a series of bytes that produces an integer result that can be used for error detection.

Rather than explaining this in more detail the paper by Ross N. Williams covers both the details and the implementation being used for the programs described here.

More information from Ross is located here . The home location of the paper is here.

CRCs for Database Tables

Each database table has a CRC that is calculated based upon a variety of fields from the _File, _Field, _Index, and _Index field tables. The data contained in these fields is combined somehow with an unpublished algorithm and then processed with a CRC algorithm to produce the CRC for each table. These CRCs are checked at run time to ensure that only compatible programs are run against a database. (If you use progress v6 without -crc, or progress v7 + with -timestamp, then table CRCs are ignored when checking r-code, but timestamps are even more problematic).

The actual fields used in the construction of the CRC vary from version to version and in version 9, the indicies do not influence the CRC.

The value of the CRC can be found by querying the _Crc field of _File.

      for each _File:
	 display _File-Name _CRC.
      end.
   
More information on Table CRCs is available from Peter van Dam's Website .

CRCs for Database Indicies

In Version 9 of Progress a CRC was added to the _Index table, this value is stored in _Index._Idx-CRC.

      for each _Index:
	 display _Index-Name _Idx-CRC.
      end.
   

CRCs of Source Code

The CRC of a source code file is simply the CCITT 16 bit CRC of the source code file. The crc of a source file can be determined using the crc program for which the source is provided .

CRCs of R-Code

An R-Code file contains the CRCs of each table used, the R-Code CRC and a CRC for each source file in the debug segment (If the debug segment exists).

The R-Code CRC is the 16 bit CCITT CRC of the output of compile debug-list with the leading numbers and spaces removed. This can be obtained from the R-Code with the procrc command or from within progress with the following code:

    RCODE-INFO:FILE-NAME = "test.r".
    DISPLAY RCODE-INFO:CRC-value
 
Alternatively this value can be determined from a compile listing with the following command:
    sed 's/^............//' program.lst | crc
 

CRCs for Triggers

File and field triggers were added to Progress in version 7. Each file (table) and field trigger in a Progress database can have an associated CRC. This is the R-Code CRC of the compiled programs that make up the trigger. If these fields have non-unknown values (not ?) then the trigger will not run unless the CRCs match. This is useful to help prevent the used of modified triggers.

The fields are _File-Trig._Trig-Crc and _Field-Trig._Trig-Crc.

Programs

These C programs allow the extraction of the source file CRCs from r-code and also the calculation of the CRC for a source file.

Pre-compiled versions (based on v1.1 Dec 2001)

Win32 console versions are downloadable here: procrc.exe & crc.exe
Here are the HP-UX binaries: hpux_crc and hpux_procrc
Here are the IBM AIX binaries: aix_crc and aix_procrc

Compiling

To compile on UNIX use the following commands:

 cc procrc.c -o procrc
 cc crc.c crcmodel.c -o crc
 
On HP-UX the C standard C compiler will not support ANSI prototypes that are used in the subroutines. You will need gcc or the HP ANSI C Compiler or you could convert the prototypes by hand to K&R. No known problems on Tru64, Solaris, AIX, or Linux.

Examples of procrc and crc

Here is an example of the use of procrc and crc on an UNIX system.

    $ cat abc.p
    bell.
    {abc.i}
    $ cat abc.i
    stop.
    $pro
    

compile abc.p save debug-list abc.lst.
    quit.
    

$ procrc abc.r
    *** procrc - Copyright (C) 2000 Grant P. Maizels
    R-Code file: abc.r 
    Compiled on: 1006131481 (0x3bf85919) Mon Nov 19 11:58:01 2001
    R-Code version: 820
    R-Code CRC: 22477
    Source CRC: abc.lst abc.lst 22477
    Source CRC: abc.p abc.p 33059
    Source CRC: abc.i abc.i 24634
    $ crc abc.p
    abc.p CRC: 33059
    $ crc abc.i
    abc.i CRC: 24634
    $ sed 's/^............//' abc.lst | crc
    stdin CRC: 22477