A hex dump tool.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

166 lines
3.8 KiB

/* This file is part of HEX, the hex dump utility
* ============================================================
* HEX is free software and comes with NO WARRANTY -
* read the file COPYING for details
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#ifndef WINDOWS
#include <sysexits.h>
#else
#define EX_OK 0
#define EX_USAGE -1
#define EX_DATAERR -1
#define EX_NOINPUT -1
#define EX_IOERR -1
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#define PROGRAM_NAME "hex"
#define VERSION "1.00"
int verbose=0;
char ifilename[128];
static void intro() {
puts("*********************************\n"
"* " PROGRAM_NAME " V." VERSION " *\n"
"* (c) Markus Hoffmann 1997-2021 *\n"
"* *\n"
"*********************************\n");
}
static void usage() {
printf(
"Usage: %s [-h -v -q] <filename> \n\n"
" -h, --help\t---\tUsage, Display this information\n"
" -v\t\t---\tbe more verbose\n"
" -q\t\t---\tbe more quiet\n"
,PROGRAM_NAME);
}
static void kommandozeile(int anzahl, char *argumente[]) {
int count,quitflag=0;
/* Kommandozeile bearbeiten */
for(count=1;count<anzahl;count++) {
if(!strcmp(argumente[count],"--help") || !strcmp(argumente[count],"-h")) {
intro();
usage();
quitflag=1;
}
else if(!strcmp(argumente[count],"-v")) verbose++;
else if(!strcmp(argumente[count],"-q")) verbose--;
else strcpy(ifilename,argumente[count]);
}
if(quitflag) exit(EX_OK);
}
/* Helper functions for File I/O */
/* Return 0 if file does not exist. */
static int exist(const char *filename) {
struct stat fstats;
int retc=stat(filename, &fstats);
if(retc==-1) return(0);
return(!0);
}
/* Returns the length of the open file n */
size_t lof(FILE *n) {
long position=ftell(n);
if(position==-1) {
perror("lof");
return(0);
}
if(fseek(n,0,SEEK_END)==0) {
long laenge=ftell(n);
if(laenge<0) perror("ftell");
if(fseek(n,position,0)<0) perror("fseek");
return(laenge);
} else perror("fseek");
return(0);
}
/* loads the file with filename name to a memory location at address adr.
the whole file is read.
RETURNS the number of read bytes or 0 on error.
*/
size_t bload(const char *name,char **adr) {
FILE *fdis=fopen(name,"rb");
if(fdis==NULL) return(0);
size_t len=lof(fdis);
*adr=realloc(*adr,len);
if(len>0) len=fread(*adr,1,len,fdis);
fclose(fdis);
return(len);
}
/* This is a handy helper function which prints out a
hex dump of the memory area pointed to by adr of length l
The output is in magenta and fits on a 80 char screen.
(c) by Markus Hoffmann 1997 */
void memdump(const unsigned char *adr,int l) {
int i,ii;
printf("\033[35m");
ii=0;
while(l>16) {
printf("%08x: ",ii);
for(i=0;i<16;i++) printf("%02x ",adr[i]);
putchar(' ');
for(i=0;i<16;i++) {
if(adr[i]>31) putchar(adr[i]);
else putchar('.');
}
putchar('\n');
adr+=16;
l-=16;
ii+=16;
}
if(l>0) {
printf("%08x: ",ii);
for(i=0;i<16;i++) {
if(i<l) printf("%02x ",adr[i]);
else printf(" ");
}
putchar(' ');
for(i=0;i<l;i++) {
if(adr[i]>31) putchar(adr[i]);
else putchar('.');
}
putchar('\n');
}
printf("\033[m");
}
int main(int anzahl, char *argumente[]) {
if(anzahl<2) { /* Kommandomodus */
intro();
usage();
exit(EX_OK);
} else kommandozeile(anzahl, argumente); /* Kommandozeile bearbeiten */
if(!exist(ifilename)) {
perror(ifilename);
return(EX_NOINPUT);
}
char *adr=NULL;
if(verbose) printf("<-- %s \n",ifilename);
size_t len=bload(ifilename,&adr);
memdump((unsigned char *)adr,(int)len);
return(EX_OK);
}