btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / hd.c
blobdc073bb7aa3e4db9a0272600aa1f5083950093a0
1 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2 //
3 // Copyright (c) 2001-2003, OpenBeOS
4 //
5 // This software is part of the OpenBeOS distribution and is covered
6 // by the MIT License.
7 //
8 //
9 // File: hd.c
10 // Author: Daniel Reinhold (danielre@users.sf.net)
11 // Description: hex dump utility
13 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
15 #include <OS.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <ctype.h>
20 #include <errno.h>
21 #include <sys/stat.h>
24 void display (uint32, uint8 *);
25 void do_hd (char *);
26 void dump_file (FILE *);
27 char *hexbytes (uint8 *);
28 char *printable (uint8 *);
29 void usage (void);
32 static int BytesBetweenSpace = 1;
35 void
36 usage ()
38 printf ("Usage:\thd [-n N] [file]\n");
39 printf("\t-n expects a number between 1 and 16 and specifies\n");
40 printf("\tthe number of bytes between spaces.\n");
41 printf("\n\tIf no file is specified, input is read from stdin\n");
45 int
46 main(int argc, char *argv[])
48 char *arg = NULL;
50 if (argc == 1)
51 dump_file(stdin);
53 else {
54 char *first = *++argv;
56 if (strcmp(first, "--help") == 0) {
57 usage();
58 return 0;
61 if (strcmp(first, "-n") == 0) {
62 if (--argc > 1) {
63 char *num = *++argv;
65 if (!isdigit(*num))
66 printf("-n option needs a numeric argument\n");
67 else {
68 int b = atoi(num);
70 if (b < 1) b = 1;
71 if (b > 16) b = 16;
72 BytesBetweenSpace = b;
74 if (--argc > 1)
75 arg = *++argv;
76 else
77 printf("no file specified\n");
80 else
81 printf("-n option needs a numeric argument\n");
83 else
84 arg = first;
86 if (arg)
87 do_hd(arg);
90 putchar('\n');
91 return 0;
95 void
96 do_hd(char *fname)
98 struct stat e;
100 if (stat(fname, &e) == -1) {
101 fprintf(stderr, "'%s': no such file or directory\n", fname);
102 return;
105 if (S_ISDIR(e.st_mode))
106 fprintf(stderr, "'%s' is a directory\n", fname);
107 else {
108 FILE *fp = fopen(fname, "rb");
109 if (fp) {
110 dump_file(fp);
111 fclose(fp);
113 else
114 fprintf(stderr, "'%s': %s\n", fname, strerror(errno));
119 void
120 dump_file(FILE *fp)
122 size_t got;
123 uint32 offset = 0;
124 uint8 data[16];
126 while ((got = fread(data, 1, 16, fp)) == 16) {
127 display(offset, data);
128 offset += 16;
131 if (got > 0) {
132 memset(data+got, ' ', 16-got);
133 display(offset, data);
138 void
139 display(uint32 offset, uint8 *data)
141 printf("%08" B_PRIx32 " ", offset);
142 printf(" %s ", hexbytes(data));
143 printf("%16s ", printable(data));
145 putchar('\n');
149 char *
150 hexbytes(uint8 *s)
152 static char buf[64];
153 char *p = buf;
154 uint8 c;
155 int i;
156 int n = 0;
158 for (i = 0; i < 16; ++i) {
159 c = *s++;
160 *p++ = "0123456789abcdef"[c/16];
161 *p++ = "0123456789abcdef"[c%16];
163 if (++n == BytesBetweenSpace) {
164 *p++ = ' ';
165 n = 0;
168 if ((i == 7) && (BytesBetweenSpace == 1))
169 *p++ = ' ';
171 *p++ = ' ';
172 *p = 0;
174 return buf;
178 char *
179 printable (uint8 *s)
181 static char buf[16];
182 char *p = buf;
183 uint8 c;
184 int i = 16;
186 while (i--) {
187 c = *s++;
188 *p++ = (isgraph(c) ? c : '.');
190 *p = 0;
192 return buf;