This is a simple head utility that outputs in hexadecimal format. Characters that are non-printable are replaced with the "." character.
0c5080928e90b08d6d6768e9822e4f8abf096c4a3266af155b8e438d2ed706fb
/**
* hex-head.c hex output of the head command.
*
* Written and Copyright (c) 2009 by Aaron Conole <apconole@yahoo.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the license, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the IMPLIED WARRANTY of MERCHANTIBILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#ifndef BUFSIZ
#define BUFSIZ 8192
#endif
const char hex_head_usage[] = ": [OPTIONS] [FILE]...\n";
int c_gi = 0, c_cnt=0;
long c_len = 0;
int scnt = 0;
char str[17];
int dump(void* b, int len, FILE *dump){
unsigned char *buf = b;
int cnt = 0;
FILE *out = stdout;
if(dump != NULL)
out = dump;
for ( ; c_gi < c_len; c_gi++ ){
if ( c_cnt % 16 == 0 ){
fprintf(out, " %s\n%04X: ", str, c_cnt);
memset(str, 0, 17);
scnt = 0;
}
if ( buf[cnt] < ' ' || buf[cnt] >= 127 )
str[scnt%16] = '.';
else
str[scnt%16] = buf[cnt];
fprintf(out, "%02X ", buf[cnt++]);
c_cnt++; scnt++; --len;
}
fflush(out);
return len;
}
int head(FILE *src, int len, int lines)
{
long lread = 0;
size_t rlen = 0;
int olen = 0;
char buf[BUFSIZ];
c_len = c_gi = c_cnt = 0;
memset(str, 0, 17);
scnt = 0;
lread = ftell(src);
len += lread;
c_len = len;
while((lines > 0) &&
(fgets(buf, sizeof(buf), src) != 0))
{
rlen = ftell(src) - lread;
lread += rlen;
if((len != -1) && (lread > len)) /*last group of bytes*/
{
rlen = rlen - (lread - len);
lines = 0;
}else if(len == -1)
{
c_len = lread;
}
olen = dump(buf, rlen, stdout);
if(buf[rlen - 1] == '\n')
lines--;
}
if(olen == 0)
fprintf(stdout, " %s\n", str);
else
fprintf(stdout, " %*s", 16+(16-olen%16)*2, str);
fflush(stdout);
fprintf(stdout, "\n");
return 0;
}
int main(int argc, char *argv[])
{
char *buf;
char opt;
int len = -1, lines = 10, tmplen, i;
char pr_head = 1;
FILE *fp;
if( argc <= 1 )
{
fprintf(stderr, "%s%s\n", argv[0], hex_head_usage);
return -1;
}
for (i = 1; i < argc; ++i)
{
if(argv[i][0] == '-')
{
opt = argv[i][1];
switch(opt)
{
case 'v':
pr_head = 1;
break;
case 'q':
pr_head = 0;
break;
case '-':
{
if(!strncmp("bytes", argv[i]+2, 5))
{
tmplen = 0;
tmplen = atoi(argv[i]+8);
len = tmplen;
}else if(!strncmp("lines", argv[i]+2, 5))
{
lines = atoi(argv[i]+8);
return -1;
}
else
{
printf("invalid options\n");
return -1;
}
}
break;
case 'c':
tmplen = 0;
if(++i < argc)
tmplen = atoi(argv[i]);
if(tmplen < 1)
{
printf("Invalid length field.\n");
return -1;
}
len = tmplen;
break;
case 'n':
tmplen = 0;
if(++i < argc)
tmplen = atoi(argv[i]);
if(tmplen < 1)
{
printf("Invalid lines field.\n");
return -1;
}
lines = tmplen;
break;
case 'h':
printf("invalid options\n");
return -1;
}
}
else
{
break;
}
}
if(i >= argc)
{
head(stdin, len, lines);
}
else
{
for(;i<argc;++i)
{
FILE *src = fopen(argv[i], "r");
if(src == NULL)
{
fprintf(stderr, "%s: %s: %s\n",
argv[0], argv[i], strerror(errno));
}
else
{
if(pr_head)
{
fprintf(stdout, "==> %s <==\n", argv[i]);
}
if(head(src, len, lines) == -1)
return -1;
if(i < argc - 1)
{
fprintf(stdout, "\n");
}
}
}
}
return 0;
}