summaryrefslogtreecommitdiff
path: root/hexdump.c
blob: 552e4c623c9f48339241966394e3a1da01aa6c59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* See LICENSE file for copyright and license details. */
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>

#include "util.h"

static void
usage(void)
{
	eprintf("usage: %s [-C] [file ...]\n", argv0);
}

#define BYTES_PER_LINE 16

int
main(int argc, char *argv[])
{
	int fd;
	char c;
	int nread;
	int pos;
	int lastpos;
	int i;
	char buf[BYTES_PER_LINE];

	ARGBEGIN {
	case 'v':
		break;
	case 'C':
		break;
	default:
		usage();
	} ARGEND

	if (argc < 1 && isatty(STDIN_FILENO)) {
		usage();
	}

	if (isatty(STDIN_FILENO)) {
		if ((fd = open(*argv, O_RDONLY)) < 0) {
			weprintf("open %s:", *argv);
			return 0;
			
		}
	} else {
		fd = STDIN_FILENO;
	}

	lastpos = 0;
	pos = 0;
	while ((nread=read(fd, &c, 1)) >= 0) {
		if (nread > 0) {
			if (pos % BYTES_PER_LINE == 0) {
				printf("%08x ", pos);
			}
			printf(" %02x", c & 0xFF );
			buf[pos%BYTES_PER_LINE] = c;
			pos++;
		} else {
			if (lastpos == 0) {
				lastpos = pos;
			}
			printf("   ");
			pos++;
		}
		if (pos % BYTES_PER_LINE == BYTES_PER_LINE/2) {
			printf(" ");
		}
		if (pos % BYTES_PER_LINE == 0) {
			printf("  |");
			if (nread == 0) {
				pos = lastpos;
			}
			for (i = 0; i <= (pos+BYTES_PER_LINE-1) % BYTES_PER_LINE; i++) {
				if (isprint(buf[i]) ) {
					putchar(buf[i]);
				} else {
					putchar('.');
				}
			}
			puts("|");
			if (nread == 0) {
				goto END;
			}
		}
	}
END:
	printf("%08x\n", pos);


	if (fd > STDERR_FILENO) {
		close(fd);
	}
	
	return 0;
}