/* dumper Usage: DUMper [] [] Description: File contents dumping in hex and ASCII format. Currently this program works on direct binary access files only (files created by fput in C, or direct access files in FORTRAN). The user specifies: File - Name of the file to open. [Def: The currently open file (if any) is shown] Seek - Position (byte count from 0) to seek. [Def: Show the value of the current file record pointer] Dump [] [] - Dump to the screen the number of bytes from the next records. [Def: Up to 20 lines (screen full)] [* == Up to MAX_BUFFER] Group [] - Number of record bytes grouped on a dump line. [Def: Show the current grouping value] Continue [] - Continue the dump (for number of records). [Def: 1] [* == until EOF] The user is notified of: File access errors. Dump contents by byte: hex and ASCII equivalents (or '_' if not printable). */ #include #include #include #define DEF_GROUPING 16 static int groups = DEF_GROUPING; #define DEF_WIDTH 80 #define MIN_WIDTH 13 static FILE *file = NULL; static long position = 0L; static int rec_size; static char command[80]; #define MAX_BUFFER 4096 static char buffer[MAX_BUFFER]; main (count, arg) int count; STRING arg[]; { STRING string; int amount, records, group; long atol(), ftell(); if (count >= 2 && isdigit (*arg[1])) { if ((group = atoi (arg[1])) < MIN_WIDTH) group = MIN_WIDTH; } else group = DEF_WIDTH; if (count >= 3 && isdigit (*arg[2])) { groups = atoi (arg[2]); groups = (((group - 10) / (4 * groups)) > 0) ? groups : ((group - 10) / 4); } else groups = (((group - 10) / (4 * groups)) / groups) * groups; if (groups <= 0) groups = DEF_GROUPING; amount = 20 * groups; FOREVER { printf ("Dumper> "); if (! gets (command)) exit (); string = command; switch (toupper (*string)) { case 'F': /* File */ if (*(string = nxtword (string))) { if (file) fclose (file); if (! (file = fopen (string, "ru"))) { printf ("Unable to open the file\n%s (%d)\n", ioerrmsg (IO_ERROR), IO_ERROR); fclose (file); } } else { if (file) printf ("%s\n", fgetname (file, string)); else printf ("No open file.\n"); } break; case 'S': /* Seek */ if (file) { if (isdigit (*(string = nxtword (string)))) { position = atol (string); fseek (file, position, 0); if (IO_ERROR) printf ("%s (%d)\nwhile positioning to %ld\n", ioerrmsg (IO_ERROR), IO_ERROR, position); else break; } else { position = ftell (file); printf ("Record pointer = %ld\n", position); } } else { no_file: printf ("File?\n"); } break; case 'D': /* Dump [] */ if (file) { /* Amount to dump from each record */ if (*(string = nxtword (string)) == '*') amount = MAX_BUFFER; else if (isdigit (*string)) { amount = atoi (string); if (amount <= 0 || amount > MAX_BUFFER) { printf ("Invalid value.\n"); break; } } else amount = 20 * groups; } else goto no_file; case 'C': /* Continue [] */ if (file) { if (*(string = nxtword (string)) == '*') records = -1; else if (isdigit (*string)) { records = atoi (string); if (records <= 0) { printf ("Invalid value.\n"); break; } } else records = 1; /* Continue listing records */ keyin (); /* Set keyboard trap */ while (records--) { /* Get the next amount from the next record into the buffer */ position = ftell (file); rec_size = fget (buffer, amount, file); if (IO_ERROR) { printf ("\ %s (%d)\n\ while attempting to read %d bytes\n\ from position %ld\n\ %d bytes read\n", ioerrmsg (IO_ERROR), IO_ERROR, amount, position, rec_size); break; } else { printf ("\n%d bytes read:\n", rec_size); list (((amount > rec_size) ? rec_size : amount)); } if (keyin ()) break; } keyoff (); } else goto no_file; break; case 'G': /* Group */ if (isdigit (*(string = nxtword (string)))) groups = atoi (string); else printf ("Listing grouped at %d bytes per line.\n", groups); break; default: printf ("\n\ Commands:\n\ File - Name of the file to open.\n\ [Def: The currently open file (if any) is shown]\n\ Seek - Position (byte count from 0) to seek.\n\ [Def: Show the value of the current file record pointer]\n\ Dump [] [] - Dump to the screen the number of bytes\n\ from the next records.\n\ [Def: Up to 20 lines (screen full)]\n\ [* == Up to MAX_BUFFER]\n\ Group [] - Number of record bytes grouped on a dump line.\n\ [Def: Show the current grouping value]\n\ Continue [] - Continue the dump (for number of records).\n\ [Def: 1]\n\ [* == until EOF]\n\ ^Z (exit)\n"); break; } } } /****************************************************************************** Produce a screen listing of the current buffer. */ #define BYTE_MASK 0377 list (amount) int amount; { int count, number, group; count = 0; while (amount) { /* Hex format */ printf ("\n%6ld:", count + position); for ( group = 0; group < groups && amount; group++, count++, amount-- ) printf (" %02X", (buffer[count] & BYTE_MASK)); count -= group; number = group; /* Space forward to the ASCII format area */ while (group++ < groups) printf (" "); /* ASCII format */ printf (" "); for ( group = 0; group < number; group++, count++) printf ("%c", ((buffer[count] >= ' ' && buffer[count] <= '~') ? buffer[count] : '_')); } printf ("\n"); }