home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * CONFIG.C
- *
- * (C)Copyright 1988, Matthew Dillon, All Rights Reserved.
- * Permission is granted to distribute for non-profit only.
- *
- * config file1 file2 file3.... filen
- *
- * Configure one or more executables. The executables must conform to
- * the Static User Modifiable Data Standard (SUMDS)
- *
- * This program configures the static parameters of C programs which
- * contain the appropriate structures. Unknown parameters may be
- * configured in raw hex if you know the format.
- */
-
- #include <stdio.h>
-
- #define arysize(array) (sizeof(array)/sizeof(array[0]))
-
- extern void *malloc();
-
- typedef unsigned char ubyte;
- typedef unsigned short uword;
- typedef unsigned long ulong;
-
- char Show;
- char XDebug;
-
- main(ac, av)
- char *av[];
- {
- register short i;
- FILE *fi;
- long pos, len;
-
- puts("CONFIG V1.00, Matthew Dillon.");
- for (i = 1; i < ac; ++i) {
- fi = fopen(av[i], "r+");
- if (fi == NULL) {
- printf("Could not open %s for reading\n", av[i]);
- continue;
- }
- switch(FindData(fi, &pos, &len)) {
- case -2:
- printf("%s contains unknown hunk #%ld\n", av[i], pos);
- break;
- case -1:
- printf("%s is not an executable\n", av[i]);
- break;
- case 0:
- printf("could not find configuration header in %s\n", av[i]);
- break;
- case 1:
- switch(Configure(fi, pos, len*4)) {
- case -3:
- printf("Unable to malloc %ld bytes\n", len);
- break;
- case -2:
- puts("Error reading data block or badly formatted data");
- break;
- case -1:
- puts("No 'END ' entry found in header");
- break;
- case 0:
- puts("No modifications made to file");
- break;
- case 1:
- puts("File updated");
- break;
- }
- break;
- }
- fclose(fi);
- }
- }
-
- /*
- * Search through the beginning of all HUNK_DATA hunks for 'STRT', 0
- *
- * symb: object modules only, not defined here.
- * HUNK_OVERLAY cannot be handled yet.
- */
-
- #define HUNK_UNIT 999 /* N, Nlws of name */
- #define HUNK_NAME 1000 /* N, Nlws of name */
- #define HUNK_CODE 1001 /* N, Nlws of code */
- #define HUNK_DATA 1002 /* N, Nlws of data */
- #define HUNK_BSS 1003 /* N (Nlws of bss) */
- #define HUNK_RELOC32 1004 /* N, (N+1)lws, N ... 0 */
- #define HUNK_RELOC16 1005 /* N, (N+1)lws, N ... 0 */
- #define HUNK_RELOC8 1006 /* N, (N+1)lws, N ... 0 */
- #define HUNK_EXT 1007 /* N, symb,symb... 0 */
- #define HUNK_SYMBOL 1008 /* N, symb,symb... 0 */
- #define HUNK_DEBUG 1009 /* N, Nlws of debug */
- #define HUNK_END 1010 /* - */
- #define HUNK_HEADER 1011 /* N, Nlwsname, N.. 0, tabsize, F, L, F-L+1 sizes */
- #define HUNK_OVERLAY 1013 /* tabsize, M+2,M+1 ... ovr data table */
- #define HUNK_BREAK 1014 /* - */
-
- FindData(fi, ppos, plen)
- FILE *fi;
- long *ppos;
- long *plen;
- {
- long type;
- long len;
- long pos;
- long ary[3];
- static long buf[256];
-
- if (fread(&type, 4, 1, fi) != 1 || type != HUNK_HEADER)
- return(-1);
- for (;;) {
- if (fread(&len, 4, 1, fi) != 1)
- return(-1);
- if (len == 0)
- break;
- fseek(fi, len*4, 1);
- }
- if (fread(ary, 4, 3, fi) != 3)
- return(-1);
- fseek(fi, 4*(ary[2] - ary[1] + 1), 1);
-
- while (fread(&type, 4, 1, fi) == 1) {
- len = 0;
- if (XDebug)
- printf("type: %ld\n", type);
- switch(type) {
- case HUNK_CODE:
- fread(&len, 4, 1, fi);
- break;
- case HUNK_DATA:
- fread(&len, 4, 1, fi); /* # of longwords */
- pos = ftell(fi);
- if (len >= 4) {
- register short i;
- register short j = (len > arysize(buf)) ? arysize(buf) : len;
- register long *ptr;
- fread(buf, j, 4, fi);
- for (i = 0; i < j; ++i) {
- ptr = buf + i;
- if (ptr[0] == 'STRT' && ptr[1] == 0) {
- *ppos = pos+i*4;
- *plen = len - i;
- fseek(fi, *ppos, 0);
- return(1);
- }
- ptr = (long *)((short *)ptr + 1);
- if (ptr[0] == 'STRT' && ptr[1] == 0) {
- *ppos = pos+i*4+2;
- *plen = len - i;
- fseek(fi, *ppos, 0);
- return(1);
- }
- }
- }
- fseek(fi, pos, 0);
- break;
- case HUNK_BSS:
- fread(&len, 4, 1, fi);
- len = 0;
- break;
- case HUNK_RELOC32:
- case HUNK_RELOC16:
- case HUNK_RELOC8:
- for (;;) {
- if (fread(&len, 4, 1, fi) != 1)
- return(-1);
- if (len == 0)
- break;
- ++len;
- fseek(fi, len*4, 1);
- }
- break;
- case HUNK_SYMBOL:
- for (;;) {
- if (fread(&len, 4, 1, fi) != 1)
- return(-1);
- if (len == 0)
- break;
- len = (len + 1) & 0x00FFFFFF;
- if (len <= 32) /* reading is faster */
- fread(buf, len, 4, fi);
- else /* very long name? */
- fseek(fi, len*4, 1);
- }
- break;
- case HUNK_DEBUG:
- if (fread(&len, 4, 1, fi) != 1)
- return(-1);
- break;
- case HUNK_END:
- break;
- default:
- *ppos = type;
- return(-2);
- }
- fseek(fi, len*4, 1);
- }
- return(0);
- }
-
- Configure(fi, pos, len)
- FILE *fi;
- long pos;
- long len; /* bytes */
- {
- register uword *buf = malloc(len+1);
- register long i;
- short j;
- long modified = 0;
- short numentries = 0;
-
- len >>= 1; /* Words */
-
- if (buf == NULL)
- return(-3);
- fseek(fi, pos, 0);
- if (fread(buf, len, 2, fi) != 2)
- return(-2);
- for (i = 4; i < len;) {
- if (buf[i] == 'EN' && buf[i+1] == 'D ' && buf[i+2] == 0)
- break;
- ++numentries;
- i += 4 + ((buf[i+3]+1)>>1);
- }
- if (i > len)
- return(-2);
- if (i == len)
- return(-1);
-
- len = i;
- printf("%ld entries found\n\n", numentries);
-
- for (i = 4; i < len;) {
- register long data = (buf[i]<<16)|buf[i+1];
- long dlen = buf[i+3];
- uword *ptr = buf + i + 4;
-
- printf("----(%c%c%c%c,%2ld): ", data>>24, data>>16, data>>8, data, dlen);
- switch(data) {
- case 'NW ':
- puts("NEW WINDOW STRUCTURE");
- modified += Edit_WINP(ptr, dlen);
- break;
- case 'TEXT':
- puts("TEXT");
- modified += Edit_TEXT(ptr, dlen);
- break;
- default:
- puts("UNKNOWN STRUCTURE, HEX EDIT");
- modified += Edit_Hex(ptr, dlen);
- break;
- }
- i += 4 + ((dlen+1)>>1);
- puts("");
- }
- {
- long response = (modified) ? 0 : 'n';
- char ibuf[64];
-
- while (response != 'y' && response != 'n') {
- printf("Write data back to file (y/n): ");
- fflush(stdout);
- if (gets(ibuf) == NULL)
- break;
- response = ibuf[0] | 0x20;
- }
- if (response == 'y') {
- fseek(fi, pos, 0);
- fwrite(buf, len, 2, fi);
- return(1);
- } else {
- return(0);
- }
- }
- }
-
- Edit_WINP(buf, bytes)
- char *buf;
- short bytes;
- {
- short i;
- short modified = 0;
-
- for (i = 0; i < bytes;) {
- switch(i) {
- case 0: /* LeftEdge */
- modified += strscanvalue(buf+i, 2, "LeftEdge", "(Negative = Relative to Screen Right)");
- i += 2;
- break;
- case 2: /* TopEdge */
- modified += strscanvalue(buf+i, 2, "TopEdge", "(Negative = Relative to Screen Bottom)");
- i += 2;
- break;
- case 4: /* Width */
- modified += strscanvalue(buf+i, 2, "Width", "(0 = Full Width, < 0 = ScreenWidth - (-width)");
- i += 2;
- break;
- case 6: /* Height */
- modified += strscanvalue(buf+i, 2, "Height", "(0 = Full Height, < 0 = ScreenHeight - (-height)");
- i += 2;
- break;
- case 8: /* DetailPen */
- modified += strscanvalue(buf+i, 1, "DetailPen", NULL);
- ++i;
- break;
- case 9: /* BlockPen */
- modified += strscanvalue(buf+i, 1, "BlockPen", NULL);
- ++i;
- break;
- case 10: /* IDCMP */
- modified += strscanvalue(buf+i, 4, "IDCMP", NULL);
- i += 4;
- break;
- case 14: /* Flags */
- modified += strscanvalue(buf+i, 4, "Flags", NULL);
- i += 4;
- break;
- default:
- i = bytes;
- break;
- }
- }
- return(modified);
- }
-
- /*
- * Edit TEXT. The buffer holds a 'type' string, \0, then space for a text
- * string.
- */
-
- Edit_TEXT(lb, len)
- char *lb;
- {
- register short i, slen;
- char buf[256];
- char *prompt = lb;
-
- while (*lb) {
- ++lb;
- --len;
- }
- ++lb;
- --len;
- if (len <= 0) {
- puts("TEXT ERROR: UNTERMINATED BUFFER");
- return(0);
- }
- loop:
- printf("%-15s (%ld chars max) (%15s) :", prompt, len - 1, lb);
- if (gets(buf) == NULL || buf[0] == 0)
- strcpy(buf, lb);
- if (strcmp(buf, lb) != 0) {
- slen = strlen(buf);
- if (slen > len - 1) {
- printf("Maximum of %ld chars!", len - 1);
- goto loop;
- }
- strcpy(lb, buf);
- return(1);
- }
- return(0);
- }
-
- Edit_Extended(i, size, lb)
- short i;
- char *lb;
- {
- printf(" #%ld (Blind entry) ", i);
- return(scanvalue(lb, size));
- }
-
- Edit_Hex(lb, len)
- char *lb;
- long len;
- {
- short modified = 0;
- short i;
-
- puts(" (Unknown Type, blind data entry)");
- for (i = 0; i < len; ++i) {
- printf(" Entry %2ld/%2ld ", i, len-1);
- modified += scanvalue(lb+i, 1);
- }
- return(modified);
- }
-
- strscanvalue(lb, size, prompt, desc)
- char *lb;
- char *prompt;
- char *desc;
- {
- if (desc)
- printf(" note: %s\n", desc);
- printf("%15s ", prompt);
- return(scanvalue(lb, size));
- }
-
- scanvalue(lb, size)
- ubyte *lb;
- {
- register long val;
- register char *str;
- short neg;
- char buf[128];
-
- top:
- switch(size) {
- case 1:
- val = *lb;
- printf("( $%02x %3ld) :", val, (char)val);
- break;
- case 2:
- val = *(uword *)lb;
- printf("( $%04x %6ld) :", val, (short)val);
- break;
- case 4:
- val = *(long *)lb;
- printf("($%08lx %7ld) :", val, val);
- break;
- }
- fflush(stdout);
-
- neg = 1;
- if (gets(buf) && buf[0]) {
- val = 0;
- str = buf;
- if (*str == '-') {
- neg = -1;
- ++str;
- }
- /* hex */
- if (str[0] == '$' || (str[0] == '0' && (str[1]|0x20) == 'x')) {
- if (*str++ != '$')
- ++str;
- for (; *str; ++str) {
- *str |= 0x20;
- if (*str >= '0' && *str <= '9') {
- val = (val << 4) | (*str & 15);
- continue;
- }
- if (*str >= 'a' && *str <= 'f') {
- val = (val << 4) | (*str - 'a' + 10);
- continue;
- }
- break;
- }
- } else
- if (*str == '%') { /* binary */
- for (++str; *str >= '0' && *str <= '1'; ++str)
- val = (val << 1) | (*str & 1);
- } else if (*str) { /* decimal */
- for (; *str >= '0' && *str <= '9'; ++str)
- val = val * 10 + *str - '0';
- }
- if (*str) {
- printf("Illegal char '%c', try again\n ? ", *str);
- goto top;
- }
- }
- if (neg < 0)
- val = -val;
- switch(size) {
- case 1:
- if ((ubyte)val != *lb) {
- *lb = val;
- return(1);
- }
- break;
- case 2:
- if ((uword)val != *(uword *)lb) {
- *(uword *)lb = val;
- return(1);
- }
- break;
- case 4:
- if (val != *(long *)lb) {
- *(long *)lb = val;
- return(1);
- }
- break;
- }
- return(0);
- }
-
-
-