/* procrc.c - display the CRCs of source files of a compiled progress program */ /* Copyright (C) 2000 Grant P. Maizels. All rights reserved * This software is copyrighted work licensed under the terms of the * GNU General Public License. Please consult * http://www.gnu.org/licenses/licenses.html#GPL for details. */ /* Version 1.2 Add support for Rcode ver 909 - 9.1d with many action segments */ /* Version 1.1 last update 02Dec2001 fix for Windows */ /* Version 1.0 19Nov2001 initial verion */ /* Note the code is not nice to read, but it is difficult to write with structures when the data can be byteswapped */ #include #include #include #include #include #define RD_SZ 512 /* R-CODE HEADER */ #define O_MAGIC 0 #define O_TS 4 #define O_HDR1 8 /* v9+ but zero previusly - so there should be no compatitilbity problems */ #define O_RCVER 14 #define O_SEGT_SZ 30 #define HDR_SZ 68 /* SEGMENT LIST */ #define I_SEG_AD 0 /* contents of this addres should always be zero also */ #define DEBUG_SEG_AD 24 #define DEBUG_909_SEG_AD 36 /* Iseg Header */ #define O_PROG_CRC 70 /* DEBUG HEADER */ #define O_SRC_CNT 2 #define O_SRC_LST 4 /* DEBUG SRC LIST */ #define O_DEBSRC_NEXT 0 #define O_DEBSRC_CRC 2 #define O_DEBSRC_PPSZ 4 #define O_DEBSRC_DIRSZ 8 #define O_DEBSRC_FILE 9 int byteswapped; int byteswapped; unsigned char *p, *op; unsigned long gl(int); unsigned short gs(int); unsigned char gb(int); main(argc, argv) int argc; char *argv[]; { int n, i; FILE *fd; unsigned char *prog, *r; int comp_ts, segt_sz, hdr1_sz, debug_offset, i_offset, rcver, prog_crc, srclst, srccnt, crc, addr, dirsz; char *path, *incname; struct stat stbuf; /* The following line of code not to be removed from program */ fprintf(stderr, "*** procrc - Copyright (C) 2000 Grant P. Maizels\n"); if (argc < 2) { fprintf(stderr, "usage: %s r-code-file.r\n", argv[0]); exit(1); } stat(argv[1], &stbuf); prog = (char *) malloc(stbuf.st_size); fd = fopen(argv[1], "rb"); if (fd == NULL) { fprintf(stderr, "%s: file %s not found\n", argv[0], argv[1]); exit(2); } r = prog; i = 0; while ((n = fread(r+i, RD_SZ, 1, fd)) > 0) i += n * RD_SZ; /* p points to whole r-code */ p = prog; if (gl(O_MAGIC) != 0x56ced309) { if (gl(O_MAGIC) == 0x09d3ce56) byteswapped = 1; else { fprintf(stderr, "Not a progress R-code file\n"); exit(4); } } comp_ts = gl(O_TS); rcver = gs(O_RCVER); hdr1_sz = gl(O_HDR1); segt_sz = gl(O_SEGT_SZ); /* p points to segment list */ p = p + HDR_SZ + hdr1_sz; i_offset = gl(I_SEG_AD); if (rcver == 909) debug_offset = gl(DEBUG_909_SEG_AD); else debug_offset = gl(DEBUG_SEG_AD); if (debug_offset == 0) { fprintf(stderr, "No debug segment\n"); exit(5); } op = p; /* p points to i segment */ p = op + segt_sz + i_offset; prog_crc = gs(O_PROG_CRC); /* p points to debug segment */ p = op + segt_sz + debug_offset; srccnt = gs(O_SRC_CNT); srclst = gs(O_SRC_LST); printf("R-Code file: %s \n", argv[1]); printf("Size: %d bytes\n", stbuf.st_size); printf("Compiled on: %d (0x%lx) %s", comp_ts, comp_ts, ctime((time_t *) &comp_ts)); printf("R-Code version: %d\n", rcver); printf("R-Code CRC: %d\n", prog_crc); addr = srclst; for (i = 0 ; i < srccnt ; i++) { crc = gs(addr + O_DEBSRC_CRC); dirsz = gb(addr + O_DEBSRC_PPSZ); incname = (char *) (p + addr + O_DEBSRC_FILE + dirsz); path = (char *) (p + addr + O_DEBSRC_FILE); printf("Source CRC: %s %s %d\n", incname, path, crc); addr = gs(addr + O_DEBSRC_NEXT); } } unsigned long gl(int i) { if (byteswapped) return (((unsigned long) p[i+3] * 256 * 65536) + ((unsigned long) p[i+2] * 65536) + ((unsigned long) p[i+1] * 256) + (unsigned long) p[i]); else return (((unsigned long) p[i] * 256 * 65536) + ((unsigned long) p[i+1] * 65536) + ((unsigned long) p[i+2] * 256) + (unsigned long) p[i+3]); } unsigned short gs(int i) { if (byteswapped) return ((p[i+1] * 256) + p[i]); else return ((p[i] * 256) + p[i+1]); } unsigned char gb(int i) { return (p[i]); }