Files
haiku-beta6/src/bin/hd.c
T

194 lines
3.1 KiB
C
Raw Normal View History

2002-07-09 12:24:59 +00:00
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
//
2002-10-10 19:05:58 +00:00
// Copyright (c) 2001-2003, OpenBeOS
2002-07-09 12:24:59 +00:00
//
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
//
// File: hd.c
// Author: Daniel Reinhold ([email protected])
// Description: hex dump utility
//
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#include <OS.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2002-07-09 12:24:59 +00:00
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
2002-10-10 19:05:58 +00:00
void display (uint32, uint8 *);
void do_hd (char *);
void dump_file (FILE *);
2002-07-09 12:24:59 +00:00
char *hexbytes (uint8 *);
char *printable (uint8 *);
2002-10-10 19:05:58 +00:00
void usage (void);
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
static int BytesBetweenSpace = 1;
2002-07-09 12:24:59 +00:00
void
usage ()
2002-10-10 19:05:58 +00:00
{
printf ("Usage:\thd [-n N] [file]\n");
printf("\t-n expects a number between 1 and 16 and specifies\n");
printf("\tthe number of bytes between spaces.\n");
printf("\n\tIf no file is specified, input is read from stdin\n");
}
2002-07-09 12:24:59 +00:00
int
2002-10-10 19:05:58 +00:00
main(int argc, char *argv[])
{
2002-07-09 12:24:59 +00:00
char *arg = NULL;
if (argc == 1)
2002-10-10 19:05:58 +00:00
dump_file(stdin);
else {
2002-07-09 12:24:59 +00:00
char *first = *++argv;
2002-10-10 19:05:58 +00:00
if (strcmp(first, "--help") == 0) {
usage();
2002-07-09 12:24:59 +00:00
return 0;
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
if (strcmp(first, "-n") == 0) {
if (--argc > 1) {
2002-07-09 12:24:59 +00:00
char *num = *++argv;
2002-10-10 19:05:58 +00:00
if (!isdigit(*num))
printf("-n option needs a numeric argument\n");
else {
int b = atoi(num);
2002-07-09 12:24:59 +00:00
if (b < 1) b = 1;
if (b > 16) b = 16;
2002-10-10 19:05:58 +00:00
BytesBetweenSpace = b;
2002-07-09 12:24:59 +00:00
if (--argc > 1)
arg = *++argv;
else
2002-10-10 19:05:58 +00:00
printf("no file specified\n");
2002-07-09 12:24:59 +00:00
}
}
2002-10-10 19:05:58 +00:00
else
printf("-n option needs a numeric argument\n");
}
2002-07-09 12:24:59 +00:00
else
arg = first;
if (arg)
2002-10-10 19:05:58 +00:00
do_hd(arg);
}
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
putchar('\n');
2002-07-09 12:24:59 +00:00
return 0;
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
void
2002-10-10 19:05:58 +00:00
do_hd(char *fname)
{
2002-07-09 12:24:59 +00:00
struct stat e;
2002-10-10 19:05:58 +00:00
if (stat(fname, &e) == -1) {
fprintf(stderr, "'%s': no such file or directory\n", fname);
2002-07-09 12:24:59 +00:00
return;
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
if (S_ISDIR(e.st_mode))
fprintf(stderr, "'%s' is a directory\n", fname);
else {
FILE *fp = fopen(fname, "rb");
if (fp) {
dump_file(fp);
fclose(fp);
2002-07-09 12:24:59 +00:00
}
2002-10-10 19:05:58 +00:00
else
fprintf(stderr, "'%s': %s\n", fname, strerror(errno));
2002-07-09 12:24:59 +00:00
}
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
void
2002-10-10 19:05:58 +00:00
dump_file(FILE *fp)
{
2002-07-09 12:24:59 +00:00
size_t got;
uint32 offset = 0;
uint8 data[16];
2002-10-10 19:05:58 +00:00
while ((got = fread(data, 1, 16, fp)) == 16) {
display(offset, data);
2002-07-09 12:24:59 +00:00
offset += 16;
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
if (got > 0) {
memset(data+got, ' ', 16-got);
display(offset, data);
2002-07-09 12:24:59 +00:00
}
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
void
2002-10-10 19:05:58 +00:00
display(uint32 offset, uint8 *data)
{
printf("%08lx ", offset);
2002-10-10 19:05:58 +00:00
printf(" %s ", hexbytes(data));
printf("%16s ", printable(data));
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
putchar('\n');
}
2002-07-09 12:24:59 +00:00
char *
2002-10-10 19:05:58 +00:00
hexbytes(uint8 *s)
{
2002-07-09 12:24:59 +00:00
static char buf[64];
char *p = buf;
uint8 c;
int i;
int n = 0;
2002-10-10 19:05:58 +00:00
for (i = 0; i < 16; ++i) {
2002-07-09 12:24:59 +00:00
c = *s++;
*p++ = "0123456789abcdef"[c/16];
*p++ = "0123456789abcdef"[c%16];
2002-10-10 19:05:58 +00:00
if (++n == BytesBetweenSpace) {
2002-07-09 12:24:59 +00:00
*p++ = ' ';
n = 0;
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
if ((i == 7) && (BytesBetweenSpace == 1))
2002-07-09 12:24:59 +00:00
*p++ = ' ';
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
*p++ = ' ';
*p = 0;
return buf;
2002-10-10 19:05:58 +00:00
}
2002-07-09 12:24:59 +00:00
char *
printable (uint8 *s)
2002-10-10 19:05:58 +00:00
{
2002-07-09 12:24:59 +00:00
static char buf[16];
char *p = buf;
uint8 c;
2002-10-10 19:05:58 +00:00
int i = 16;
2002-07-09 12:24:59 +00:00
2002-10-10 19:05:58 +00:00
while (i--) {
2002-07-09 12:24:59 +00:00
c = *s++;
2002-10-10 19:05:58 +00:00
*p++ = (isgraph(c) ? c : '.');
}
2002-07-09 12:24:59 +00:00
*p = 0;
return buf;
2002-10-10 19:05:58 +00:00
}