/*FILENAME: HEXDUMP.C VERSION: 1.0 PURPOSE: To read file in any format and output it in hexadecimal and ASCII value. FUNCTION USED: GetFile(), Main(), GetBytes(), and DisplayFile() PROGRAM NOTE: There are several debugger ouputs used to help with the development of this source file. The debugger outputs total file size and the actual number of bytes on the last line. DEVELOPER: Jay Suttiruttana COMPILER: GNU C DEVELOPMENT PLATFORM: Linux 5.0 DEPLOYMENT PLATFORM: HP - UNIX COURSE: Computer Engineering 130 (section 1) */ #include //for printf(), fopen(), fclose(), and fread() #include //for iscntrl() int GetFile(char *filename); void DisplayFile(int _GetBytes); unsigned char GetBytes(); FILE *stream; //for storage for file data char buffer[512]; //set buffer for file retreiving int filesize = 0; //initializing file size int line_count = 0; //initializing display line counter void main(int argc, char *argv[1]) { int inputfile; int OutputBytes = 0; printf("hd v1.0 written by Jay Suttiruttana\n"); inputfile = GetFile(argv[1]); if (inputfile == -1) exit(0); printf("Contents in buffer:\n\n"); while (OutputBytes != filesize) { DisplayFile(GetBytes()); OutputBytes++; } fclose(stream); } //GetFile() open and read file into the buffer specified by the developer. //It returns error, if there is problem with opening and reading the file. int GetFile(char *filename) { if (filename == NULL) { printf("Error - missing file name...\n"); printf("To execute program type $hd \n"); return -1; } if ((stream = fopen(filename, "rb")) != NULL) { fseek(stream,0,SEEK_END); filesize = ftell(stream); fseek(stream,0,SEEK_SET); printf("Total bytes in the file = %u\n", filesize); return 1; } else { printf("Error - file could not be open...\n"); return -1; } } // GetBytes() reads data from file and stores it in buffer. unsigned char GetBytes() //int GetBytes() { static int buffer_counter; static int ret_val; static int bytes_in_buffer = 0; if (bytes_in_buffer <= 0) { bytes_in_buffer = fread(buffer, 1, 512, stream); buffer_counter = 0; } ret_val = buffer[buffer_counter]; buffer_counter++; bytes_in_buffer--; return ret_val; } // Display file() outputs data in buffer onto the screen with 1st column showing // 5 digits address, 2nd - 17th columns showing 2 bits hexadecimal value, and // 18th column showing 16 ASCII characters.The nonprintable ASCII characters // are outputs as "." on the screen. void DisplayFile(int outBytes) { int count; int total_line; int lineCheck; static int addr_counter = 0; static int address = 0; static int lastOutput = 0; static int char_count = 0; static int outdata = 0; static int in_ASCII = 0; static char storage[16]; lineCheck = filesize%16; total_line = filesize/16; lastOutput = filesize - (total_line * 16); if (addr_counter == 0) { printf("%05X: ", address * 16); address++; } if (in_ASCII <= 16) { storage[in_ASCII] = (char)outBytes; in_ASCII++; } //**************** Output data stream 16 bytes/line ***************** if (line_count != total_line) { if(outdata < filesize) { //convert to hexadecimal printf("%02X ",outBytes); //convert to ASCII if (in_ASCII == 16) { printf(" "); for (count = 0; count < 16; count++) { if (iscntrl(storage[count]) != 0) printf("."); else printf("%c", storage[count]); } printf("\n"); in_ASCII = 0; line_count++; } } } //************ Output data stream less than 16 bytes/line ************* if ((outdata >= (total_line*16)) && (lineCheck != 0)) { if (outdata != filesize-1) printf("%02X ",outBytes); if (char_count < lastOutput) { //convert to ASCII if (char_count == (lastOutput - 1)) { //output spaces to maintain the display integrity of the row and column for (count = 0; count <= (17-lastOutput); count++) printf(" "); //output the final set of ASCII characters for (count = 0; count != (lastOutput-1); count++) { if (iscntrl(storage[count]) != 0) printf("."); else printf("%c", storage[count]); } printf("\n"); } char_count++; } } addr_counter++; outdata++; if(addr_counter == 16) addr_counter = 0; }