#include #include #include #include #include #define DECIMAL 1 #define HEX 2 #define OCTAL 3 #define BINARY 4 #define CHAR 1 /* 1 byte */ #define SHORT 2 /* 2 bytes */ #define LONG 4 /* 4 bytes */ /* * debug - an IBMPC like debug facility for UNIX * * Spits out and accepts data in HEX, DECIMAL, or even OCTAL. * * VERS DATE AUTHOR Description * 1.00 05/17/93 Greg @ Metrolight Studios Initial implementation * 1.10 09/27/02 Greg Ercolano @ Rush K+R -> C++ * */ #define VERSION "1.10" int G_mode = HEX, /* HEX, DECIMAL, OCTAL */ G_width = CHAR, /* CHAR, SHORT, LONG */ G_vpl = 16, /* values per line */ G_more = 0, G_noascii = 0; char **G_filenames = NULL; int G_tfilenames = 0; /*** ***********************************/ /*** ONLINE HELP ***********************************/ /*** ***********************************/ char *cmdline_help[] = { "NAME", " debug - a simple debug facility, V %s", "", "USAGE", " debug -[options] filename [..]", " debug -[options] < filename", "", "OPTIONS:", " -h ;Hex mode (default)", " -d ;Decimal mode", " -o ;Octal mode", " -b ;Binary mode", " -c ;Char [8 bit] mode (default)", " -s ;Short [16 bit] mode", " -l ;Long [32 bit] mode", " -m ;More. Pauses listing every 256 bytes", " -na ;No ascii (don't show ascii conversion column", "", "EXAMPLES", " debug file # hex dump 'file'", " debug -d file # decimal dump 'file'", " debug -d -m file # decimal dump 'file' with MORE prompts", " cat file | debug -m -d # decimal dump 'file' with MORE prompts", " perl -e '$|=1;for($t=0;1;$t++){printf(\"%%c\",($t%%0x100));}'|debug -m", "", "AUTHOR", " erco@3dsite.com 09/27/02", NULL }; void HelpAndExit(char **help, char *errmsg) { for (int t=0; help[t]; t++) { fprintf(stderr, help[t], VERSION); fprintf(stderr, "\n"); } if ( errmsg ) fprintf(stderr, "debug: '%s': bad/missing argument\n", errmsg); exit(1); } #define NEXTARG(t) { if (++t >= argc) HelpAndExit(cmdline_help, argv[--t]); } void ParseArgs(int argc, char **argv) { G_filenames = (char**)malloc(sizeof(char*) * ( argc + 1 ) ); G_tfilenames = 0; for (int t=1; t'~') printf("."); else printf("%c",buf[t]); } printf("\n"); fflush(stdout); } int GetChar() { #ifdef IBMPC char *devname = "con"; #else /*IBMPC*/ char *devname = "/dev/tty"; #endif /*IBMPC*/ FILE *fp; unsigned char c; if ( ( fp = fopen(devname, "r" ) ) == NULL ) return(0); fread(&c, 1, 1, fp); fclose(fp); return((int)c); } int DumpFilename(char *filename, FILE *fp) { unsigned int count, linecount=0; unsigned char buf[1024]; unsigned long address=0; while ( ( count = fread(buf, G_width, G_vpl, fp)) != 0 ) { ShowUlong(address); printf(": "); Dump(buf, 0, ((count-1)*G_width)); address += count; /* MORE THE FILE */ if ( G_more && ((linecount++ % 16) == 15)) { while ( 1 ) { printf("--More--"); fflush(stdout); char c = GetChar(); printf("\33[1A\r%20s\r", ""); switch ( c ) { case 'q': /* q=quit */ return(0); case 7: // ^G = show filename (VI) printf("Filename=%-40s\n", filename); continue; } printf("\n"); // leave a blank line break; } } } return(0); } main( int argc, char **argv ) { ParseArgs(argc, argv); /* NO FILENAMES? READ STDIN */ if ( G_tfilenames == 0 ) return(DumpFilename("[STDIN]", stdin)); int t, err = 0; FILE *fp; for ( t=0; t 1 ) printf("\n:::::::::::::::::\n%s\n:::::::::::::::::\n", G_filenames[t]); if ( ( fp = fopen(G_filenames[t], "r") ) == NULL ) { perror(G_filenames[t]); err = 1; continue; } DumpFilename(G_filenames[t], fp); fclose(fp); } return(err); }