fork download
  1. /*****************************************************//**
  2.  * @brief Prmitive hexadecimal file viewer (pipe it to 'less' or 'more'
  3.  * to make it much less primitive... see Usage below).
  4.  * @file hexview.c
  5.  * @version 0.1A
  6.  * @date 21 Feb, 2012
  7.  * @author migf1 <mig_f1@hotmail.com>
  8.  * @par Language:
  9.  * C (ANSI C89)
  10.  * @par Usage:
  11.  * hexview [-raw] [filename]
  12.  * \n
  13.  * Use -raw as the 1st command-line argument to force raw output
  14.  * (useful for piping, e.g: hexview -raw file | less)
  15.  *
  16.  * @remark Feel free to experiment with the values of the pre-processor
  17.  * constants: FMT_NCOLS, FMT_PGBREAK and FMT_POS. They affect the
  18.  * appearance of the output.
  19.  *********************************************************
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26.  
  27. #define MAXINPUT (1024+1)
  28.  
  29. #define FMT_FPOS 8 /* width in # of chars for the file-pos field */
  30. #define FMT_NCOLS 16 /* # of columns in Bytes area(no more than 16)*/
  31. #define FMT_PGBREAK 20 /* # of lines before page-break appears */
  32.  
  33. #define pressENTER() \
  34. do{ \
  35. char mYcHAr; \
  36. printf( "press ENTER..." ); \
  37. while ( (mYcHAr=getchar()) != '\n' && mYcHAr != EOF ) \
  38. ; \
  39. }while(0)
  40.  
  41. typedef unsigned char Byte;
  42.  
  43. /*********************************************************//**
  44.  * Read a c-string from stdin.
  45.  *************************************************************
  46.  */
  47. char *s_read( char *s, size_t maxlen )
  48. {
  49. size_t len = 0U;
  50.  
  51. if ( !s || !fgets( s, maxlen, stdin) )
  52. return NULL;
  53.  
  54. if ( maxlen > MAXINPUT)
  55. maxlen = MAXINPUT;
  56.  
  57. if ( s[ (len=strlen(s))-1 ] == '\n')
  58. s[ len-1 ] = '\0';
  59.  
  60. return s;
  61. }
  62.  
  63. /*********************************************************//**
  64.  * Return user selection on page-breaks
  65.  *************************************************************
  66.  */
  67. char on_pagebreak(void)
  68. {
  69. char input[ MAXINPUT ] = {'\0'};
  70.  
  71. printf("--- Q to quit, ENTER to continue --- ");
  72. fflush( stdout );
  73.  
  74. if ( !fgets( input, MAXINPUT, stdin ) )
  75. return '\0';
  76.  
  77. return tolower( *input );
  78. }
  79.  
  80. /*********************************************************//**
  81.  * Display text labels and other info on the currently displayed page.
  82.  *************************************************************
  83.  */
  84. void show_header( const char *fname, unsigned long int pg )
  85. {
  86. unsigned short int i;
  87. const unsigned short totalcols = (FMT_FPOS + 1) + (3*FMT_NCOLS) + FMT_NCOLS;
  88.  
  89. if ( !fname || !*fname )
  90. return;
  91.  
  92. /* text labels for Bytes & Chars areas */
  93. printf( "%*s | page %lu\n", totalcols/2,fname, pg);
  94. printf( "%-*c %-*s%-*s\n", FMT_FPOS,' ', (3*FMT_NCOLS),"Bytes area", FMT_NCOLS,"Chars area" );
  95.  
  96. /* text label for file-position */
  97. printf("%-*s ", FMT_FPOS,"Pos");
  98.  
  99. /* hex indicies for Bytes */
  100. for (i=0; i < FMT_NCOLS; i++)
  101. printf( "%-2hX ", i);
  102.  
  103. /* hex indicies for Characters */
  104. for (i=0; i < FMT_NCOLS; i++)
  105. printf( "%hX", i);
  106. putchar('\n');
  107.  
  108. /* separating line */
  109. for (i=0; i < totalcols; i++)
  110. putchar('-');
  111. putchar('\n');
  112.  
  113.  
  114. return;
  115. }
  116.  
  117. /*********************************************************//**
  118.  * List the contents of a file in hex/char tabular format.
  119.  *************************************************************
  120.  */
  121. int file_hexlist( const char *fname, const unsigned short int israw )
  122. {
  123. Byte buffer[ FMT_NCOLS ] = {0}; /* for reading file chunks into memory*/
  124. unsigned long int i, row, pg; /* byte, row and page counters */
  125. FILE *fp = NULL; /* file pointer */
  126.  
  127. if ( !fname || !*fname || NULL == (fp=fopen(fname, "rb")) )
  128. return 0; /* FALSE */
  129.  
  130. pg = 0;
  131. for (i=0,row=0; !feof(fp); row++,i+=FMT_NCOLS )
  132. {
  133. unsigned int j;
  134. size_t n;
  135.  
  136. /* on page break */
  137. if ( !israw && row % FMT_PGBREAK == 0 ) {
  138. if ( row != 0 )
  139. if ( 'q' == on_pagebreak() )
  140. break;
  141. show_header(fname, pg+1);
  142. pg++;
  143. }
  144.  
  145. memset( buffer, 0, FMT_NCOLS * sizeof(Byte) );
  146. n = fread(buffer, sizeof(Byte), FMT_NCOLS, fp);
  147.  
  148. printf( "%08lX ", i);
  149.  
  150. for (j=0; j < n; j++)
  151. printf("%02hX ", buffer[j] );
  152. for (; j < FMT_NCOLS; j++)
  153. printf(" ");
  154.  
  155. for (j=0; j < n; j++)
  156. putchar( isprint(buffer[j]) ? buffer[j] : '.' );
  157. for (; j < FMT_NCOLS; j++)
  158. putchar(' ');
  159. putchar('\n');
  160. }
  161. putchar('\n');
  162.  
  163. fclose(fp);
  164. return 1; /* TRUE */
  165. }
  166.  
  167. /*********************************************************//**
  168.  *
  169.  *************************************************************
  170.  */
  171. int main( int argc, char *argv[] )
  172. {
  173. char fname[ MAXINPUT ] = {'\0'}; /* name of the file to be viewed */
  174. unsigned short int israw = 0; /* FALSE */
  175.  
  176. /* parse the command line */
  177. if ( 1 == argc ) /* no arguments in the command line */
  178. {
  179. printf("Enter name of the file: ");
  180. s_read( fname, MAXINPUT );
  181. }
  182. else /* command line contains arguments */
  183. {
  184. if ( !strcmp(argv[1], "-raw") )
  185. israw = 1; /* TRUE */
  186. else
  187. strncpy( fname, argv[1], MAXINPUT-1 );
  188.  
  189. if ( israw && argc > 2 )
  190. strncpy( fname, argv[2], MAXINPUT-1 );
  191. else if ( israw && argc == 2 ) {
  192. printf("Enter name of the file: ");
  193. s_read( fname, MAXINPUT );
  194. }
  195. }
  196.  
  197. /* list the file contents */
  198. if ( !file_hexlist(fname, israw) ) {
  199. perror(NULL);
  200. goto exit_failure;
  201. }
  202.  
  203. if ( !israw )
  204. pressENTER();
  205. exit( EXIT_SUCCESS );
  206.  
  207. exit_failure:
  208. if ( !israw )
  209. pressENTER();
  210. exit( EXIT_FAILURE );
  211. }
  212.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty