summaryrefslogtreecommitdiff
path: root/hexdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'hexdump.c')
-rw-r--r--hexdump.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/hexdump.c b/hexdump.c
new file mode 100644
index 0000000..552e4c6
--- /dev/null
+++ b/hexdump.c
@@ -0,0 +1,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;
+}