1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-10 02:00:41 +00:00
Files
rcornwell.sims/SEL32/taptools/ddump.c
2019-07-23 20:37:41 -04:00

221 lines
5.2 KiB
C

/*
ddump - file dump utility for listing files in side-by-side hex
and ascii, plus having the option to modify the file giving
a hexadecimal byte offset into the file and the hex data
which will be written to the supplied address.
Usage is:
ddump file
where:
file1 is the file to dump and/or modify.
written by Rick Beery
modified many times by Jim Bevier
The program fd.c written by M. Kraieski has been incorporated
into this program.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void dodump();
int modify();
void modify_file();
int main(argc,args)
int argc;
char *args[];
{
FILE *fp, *fopen();
int i;
char *tempstring;
if ((argc < 2) || (argc > 3)) {
printf("usage: %s [-r] file\n", args[0]);
printf(" -r uses read-only mode\n");
exit(1);
} /* end of if */
if (argc == 3)
#ifdef mpx
/* open read and unblocked */
if (strcmp("-r",args[1]) == 0) fp = fopen(args[2],"ru");
#else
if (strcmp("-r",args[1]) == 0) fp = fopen(args[2],"r");
#endif
else {
printf("Invalid option %s ignored\n", args[1]);
#ifdef mpx
/* open read/write unblocked */
fp = fopen(args[2],"r+u");
#else
fp = fopen(args[2],"r+");
#endif
}
#ifdef mpx
/* open read/write unblocked */
else fp = fopen(args[1],"r+u");
#else
else fp = fopen(args[1],"r+");
#endif
if (fp == NULL) {
fprintf(stderr,"%s: fopen: unable to open file %s\n", args[0], args[1]);
exit(1);
} /* end of if */
dodump(fp,0);
fclose(fp);
} /* end of main */
#define PRINTABLE(x) ((x < 32) || (x > 126)) ? '.' : x
void dodump(fp, fileadr)
FILE *fp;
int fileadr;
{
char buff[257];
int file_byte_count=0, curchar, buffptr, bufflen;
buffptr = 0;
bufflen = 16;
fseek(fp,fileadr,0);
while ((curchar = getc(fp)) != EOF) {
file_byte_count++;
if (!buffptr) printf(" %06x : ",fileadr);
printf("%02x",curchar);
buff[buffptr++] = PRINTABLE(curchar);
if (!(buffptr % 4)) printf(" ");
if (buffptr >= bufflen) {
buff[buffptr] = 0;
printf(" |%s|\n",buff);
buffptr = 0;
fileadr += bufflen;
if (!(file_byte_count % 256)) {
modify_file(fp);
} /* end of if */
} /* end of if */
} /* end of while */
if (buffptr) {
buff[buffptr] = 0;
while (buffptr++ < bufflen) {
printf(" ");
if (!(buffptr % 4)) printf(" ");
} /* end of while */
printf(" |%s|\n",buff);
} /* end of if */
modify_file(fp);
return;
} /* end of dodump */
int modify(fp1)
FILE *fp1;
{
char hexstring[33];
int num_chars, digit, i, byte=0, stat, file_offset=0, indx=0;
int power();
void gethex_string();
int asciihex_digit_to_decimal();
gethex_string(hexstring);
num_chars = strlen(hexstring);
for (i=num_chars-1; i>=0; i--) {
digit = asciihex_digit_to_decimal(hexstring[indx++]);
file_offset += digit*power(16,i);
} /* end of for */
if ((fseek(fp1,file_offset,0)) != -1) {
/* read characters from the terminal */
printf("\nenter new hex data > ");
gethex_string(hexstring);
num_chars = strlen(hexstring);
/* convert character to numeric field and
new set of data at offset in file specified */
for (i=0; i<num_chars; i++) {
digit = asciihex_digit_to_decimal(hexstring[i]);
if ((i%2)) {
byte = byte*16 + digit;
fputc(byte, fp1);
byte = 0;
}
else {
byte = digit;
}
} /* end of for */
} /* end of "if" part of if - else */
else {
printf("Unable to seek to that address\n");
file_offset = 0;
} /* end of if - else */
return(file_offset);
} /* end of modify */
void gethex_string(hex)
char *hex;
{
char c;
int indx=0;
while ((c=getchar()) != '\n' ) {
if ((c>='0' && c<='9') || (c>='a' && c<='f'))
hex[indx++] = c;
else {
while ((c=getchar()) != '\n' );
indx = 0;
printf("Invalid hex number; please re-enter > ");
}
}
hex[indx] = '\0';
} /* end of gethex_string */
int asciihex_digit_to_decimal(c)
char c;
{
int digit;
if (c >= 'a' && c <= 'f') digit = c - 'a' + 10;
else if (c>= '0' && c <= '9') digit = c -'0';
else digit = -1; /* error */
return(digit);
} /* end of asciihex_digit_to_decimal */
int power(x,n)
int x, n;
{
int p;
for (p=1; n>0; --n)
p = p*x;
return (p);
} /* end of routine power */
void modify_file(fp)
FILE *fp;
{
int ans, modify(),modified_addr;
printf("\n hex address, <cr> - continue, q = quit > ");
ans = getchar();
if ((ans>='0' && ans<='9') || (ans>='a' && ans<='f')) {
ungetc(ans, stdin);
modified_addr = modify(fp);
printf("\n");
dodump(fp, (modified_addr/256)*256);
} /* end of "if" part of if - then */
else {
if (ans == 'q') {
fclose(fp);
exit(1);
}
else {
if (ans != '\n') while ((ans=getchar()) != '\n' );
}
} /* end of if -then */
} /* end of modify_file */