Merge branch 'exp-hash'
[eleutheria.git] / fileops / hexdump.c
bloba6aa4045359b3b3a2f2384e51b876c177155c619
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h> /* for memset() */
4 #include <getopt.h>
6 /* Function prototypes */
7 void diep(const char *s);
8 void dieu(const char *pname);
10 #define BUFSIZE 20 /* Must be dividable by 2 */
12 int main(int argc, char *argv[])
14 unsigned char buf[BUFSIZE + 1]; /* +1 for the '\0' */
15 FILE *fp;
16 int caps, cnt, i, j, len, opt, skip;
17 int readbytes, totalbytes;
18 char *fpath;
20 /* Parse arguments */
21 caps = 0;
22 len = -1;
23 skip = 0;
24 fpath = NULL;
25 while ((opt = getopt(argc, argv, "Cn:s:f:")) != -1) {
26 switch (opt) {
27 case 'C':
28 caps = 1;
29 break;
30 case 'n':
31 len = atoi(optarg);
32 break;
33 case 's':
34 skip = atoi(optarg);
35 break;
36 case 'f':
37 fpath = optarg;
38 break;
39 default: /* '?' */
40 dieu(argv[0]);
44 /* optind shows to the argv[] index of the first non-option element */
45 if (optind < argc) {
46 fprintf(stderr, "non-option argv[]-elements: ");
47 while (optind < argc)
48 fprintf(stderr, "%s ", argv[optind++]);
49 fprintf(stderr, "\n");
50 exit(EXIT_FAILURE);
53 if (fpath == NULL)
54 dieu(argv[0]);
56 /* Open file */
57 if ((fp = fopen(fpath, "r")) == NULL)
58 diep("open");
60 /* Skip ``skip'' bytes */
61 fseek(fp, skip, SEEK_SET);
63 /* Loop */
64 cnt = 0;
65 totalbytes = 0;
66 while(!feof(fp) && (totalbytes < len || len == -1)) {
67 /* Initialize buffer */
68 memset(buf, 0, BUFSIZE);
70 /* Read ``BUFSIZE'' elements of 1 byte long from file */
71 readbytes = fread(buf, 1, BUFSIZE, fp);
73 /* Print buffer */
74 printf(caps == 1 ? "%08lX " : "%08lx ", (unsigned long)cnt * BUFSIZE + skip);
75 for (i = 0; i < readbytes && (totalbytes < len || len == -1); i++, totalbytes++) {
76 printf(caps == 1 ? "%02X " : "%02x ", buf[i]);
77 if (i == (BUFSIZE / 2) - 1)
78 printf(" ");
81 /* Fill in the blanks */
82 for (j = 0; j < (BUFSIZE - i); j++) {
83 printf(" ");
84 if (j == (BUFSIZE/2) - 1)
85 printf(" ");
89 * Print the output characters in the default character set.
90 * Nonprinting characters are displayed as a single ``.''
92 printf(" |");
93 for (j = 0; j < i; j++) {
94 if (buf[j] >= 32 && buf[j] <= 127)
95 printf("%c", buf[j]);
96 else
97 printf(".");
99 printf("|");
101 /* New line */
102 printf("\n");
104 cnt++;
107 /* Close device file */
108 (void)fclose(fp);
110 return EXIT_SUCCESS;
113 void diep(const char *s)
115 perror(s);
116 exit(EXIT_FAILURE);
119 void dieu(const char *pname)
121 fprintf(stderr, "Usage: %s [-C] [-n length] [-s skip] -f file\n", pname);
122 exit(EXIT_FAILURE);