/* dump.c (10/83) Debug style dump of a file from any starting position. */ #include #include #include #include #define FAIL 1 #define SUCCESS 0 #define TRUE (1) #define FALSE 0 #define FOREVER for (;;) #define STDIN 0 #define STDOUT 1 #define STDERR 2 char *dumpusage[] = { "Usage: dump filespec [block [page]] | [segment:[offset]] [count]\r\n", "Where a block is 64K bytes and a page is 256 bytes.\r\n", "Segment:offset are standard 8086 notation in hexadecimal.\r\n", "Count is the number of bytes to dump in decimal.\r\n", NULL }; char *index(); /* suppress warning about conversion to int */ #define BUFSIZE 512 typedef unsigned ushort; extern int errno; /* DOS 2.0 error number */ long lseek(); static char buffer[BUFSIZE]; /* input buffer */ static ushort block = 0; /* block number ( 64k bytes/block ) */ static ushort page = 0; /* page number ( 256 bytes/page ) */ static ushort segment = 0; static ushort offset = 0; static long filpos = 0; /* beginning file position */ static long count = 0x7FFFFFFFL; /* number of bytes to dump */ void ohw(),ohb(),onib(),dump_abort(); static jmp_buf env; void (*signal())(); void (*oldsig)(); void dumpintr() { signal(SIGINT,SIG_IGN); /* disable interrupts from kbd */ longjmp(env,-1); } int #ifdef MAIN main #else dump #endif (argc,argv) /* DUMP ENTRY */ int argc; char *argv[]; { char c; ushort i, numin, tot, cfrom; int file; char *flag = 0; char *index(); oldsig=signal(SIGINT,dumpintr); if (-1 == setjmp(env)) { /*lint -e530 */ close(file); /*lint +e530 */ write(2,"Interrupted\r\n",13); signal(SIGINT,oldsig); return -1; } if (argc < 2) { char **u = (char **) dumpusage; while(*u) { write (2,*u,strlen(*u)); ++u; } return -1; } if ((file = open( argv[1], 0 )) == -1) dump_abort( "cannot open", argv[1], errno ); if (argc > 2) { if ((flag = index( argv[2], ':' )) != NULL) { i = stch_i( argv[2], &segment ); (void)stch_i( argv[2]+i+1, &offset ); } if (sscanf( argv[2], "%d", &block ) != 1) dump_abort( "invalid block", argv[2], 0 ); } if (argc > 3) if (sscanf( argv[3], "%d", &page ) != 1) dump_abort( "invalid page", argv[3], 0 ); if ( flag ) { filpos = (long)segment*16L + (long)offset; tot = offset; } else { filpos = (block * 65536L) + (page * 256); tot = page * 256; segment = block * 4096; } if (lseek( file, filpos, 0 ) == -1L) dump_abort( "positioning to", argv[2], errno ); if (argc > 4) if (sscanf( argv[4], "%ld", &count ) != 1) dump_abort( "invalid count", argv[4], 0 ); do { /* read & dump BUFSIZE bytes */ numin = read( file, buffer, BUFSIZE ); if (numin == -1) dump_abort( "cannot read", argv[1], errno ); cfrom=0; while (cfrom < numin) { ohw(segment); /* print offset in hex */ putchar(':'); ohw(cfrom+tot); putchar(' '); for (i=0; i < 16; i++) { /* print 16 bytes in hex */ putchar(' '); ohb(buffer[cfrom++]); } putchar(' '); putchar(' '); putchar(' '); cfrom -= 16; for (i=0; i < 16; i++) { /* print 16 bytes in ASCII */ c = buffer[cfrom] & 0x7f; if ( isprint(c) ) /* if printable character */ putchar(c); else putchar('.'); /* else print period */ cfrom++; } putchar('\r'); putchar('\n'); /* print CR/LF */ if ((count -= 16) <= 0) /* is count exhausted? */ exit(0); } /* end of while */ tot += numin; if ( tot == 0 ) segment += 4096; } /* end of do */ while (numin == BUFSIZE); signal(SIGINT,oldsig); /* restore signal */ return 0; } /* end of main */ static void ohb(byt) /* print a byte in hex */ char byt; { onib( (char)((unsigned)byt>>4) ); onib( byt ); } static void ohw(wrd) /* print a word in hex */ ushort wrd; { ohb((char) (wrd>>8) ); ohb( (char)(wrd&0xFF) ); } static void onib(nib) /* print a nibble as a hex character */ char nib; { nib &= 15; putchar((nib >= 10) ? nib-10+'A': nib+'0'); } static void dump_abort( msg1 ,msg2 ,errno) /* print error msg1, msg2, and nbr */ char *msg1,*msg2; /* Does not close files. */ short errno; { char stemp[10]; write( STDERR, "ERR: ", 5 ); if (msg1) write( STDERR, msg1, strlen(msg1) ); if (msg2) write( STDERR, " ", 1 ); write( STDERR, msg2, strlen(msg2) ); if (errno) { sprintf( stemp," #%d", errno ); write( STDERR, stemp, strlen(stemp) ); } write( STDERR, "\r\n", 2 ); longjmp(env,-1); } /** END DUMP **/ static int stch_i(p,r) char *p; unsigned *r; { int count; int acc; int hdtoi(); count = 0; *r = 0; while (-1 != (acc = hdtoi(*p++))) { ++count; *r = (*r << 4) | acc; } return count; } static int hdtoi(c) char c; { c = toupper(c); if (!isxdigit(c)) return -1; if (isdigit(c)) return (c - '0'); return (c - 'A' + 10); }