Dummy commit to test new ssh key
[eleutheria.git] / fileops / hexdump.c
blob186ad5cdd15cb51c4b29c9c50512da7722dbcd5d
1 /*
2 * Compile with:
3 * gcc hexdump.c -o hexdump -Wall -W -Wextra -ansi -pedantic
4 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h> /* for memset() */
9 #include <getopt.h> /* FIXME: make it portable */
11 /* Function prototypes */
12 void diep(const char *s);
13 void dieu(const char *pname);
15 #define BUFSIZE 20 /* Must be dividable by 2 */
17 int main(int argc, char *argv[])
19 unsigned char buf[BUFSIZE + 1]; /* +1 for the '\0' */
20 FILE *fp;
21 int caps, cnt, i, j, len, opt, skip;
22 int readbytes, totalbytes;
23 char *fpath;
25 /* Parse arguments */
26 caps = 0;
27 len = -1;
28 skip = 0;
29 fpath = NULL;
30 while ((opt = getopt(argc, argv, "Cn:s:f:")) != -1) {
31 switch (opt) {
32 case 'C':
33 caps = 1;
34 break;
35 case 'n':
36 len = atoi(optarg);
37 break;
38 case 's':
39 skip = atoi(optarg);
40 break;
41 case 'f':
42 fpath = optarg;
43 break;
44 default: /* '?' */
45 dieu(argv[0]);
49 /* optind shows to the argv[] index of the first non-option element */
50 if (optind < argc) {
51 fprintf(stderr, "non-option argv[]-elements: ");
52 while (optind < argc)
53 fprintf(stderr, "%s ", argv[optind++]);
54 fprintf(stderr, "\n");
55 exit(EXIT_FAILURE);
58 if (fpath == NULL)
59 dieu(argv[0]);
61 /* Open file */
62 if ((fp = fopen(fpath, "r")) == NULL)
63 diep("open");
65 /* Skip `skip' bytes */
66 fseek(fp, skip, SEEK_SET);
68 /* Loop */
69 cnt = 0;
70 totalbytes = 0;
71 while(!feof(fp) && (totalbytes < len || len == -1)) {
72 /* Initialize buffer */
73 memset(buf, 0, BUFSIZE);
75 /* Read `BUFSIZE' elements of 1 byte long from file */
76 readbytes = fread(buf, 1, BUFSIZE, fp);
78 /* Print buffer */
79 printf(caps == 1 ? "%08lX " : "%08lx ", (unsigned long)cnt * BUFSIZE + skip);
80 for (i = 0;
81 i < readbytes && (totalbytes < len || len == -1);
82 i++, totalbytes++) {
83 printf(caps == 1 ? "%02X " : "%02x ", buf[i]);
84 if (i == (BUFSIZE / 2) - 1)
85 printf(" ");
88 /* Fill in the blanks */
89 for (j = 0; j < (BUFSIZE - i); j++) {
90 printf(" ");
91 if (j == (BUFSIZE/2) - 1)
92 printf(" ");
96 * Print the output characters in the default character set.
97 * Nonprinting characters are displayed as a single `.'
99 printf(" |");
100 for (j = 0; j < i; j++) {
101 if (buf[j] >= 32 && buf[j] <= 127)
102 printf("%c", buf[j]);
103 else
104 printf(".");
106 printf("|");
108 /* New line */
109 printf("\n");
111 cnt++;
114 /* Close device file */
115 (void)fclose(fp);
117 return EXIT_SUCCESS;
120 void diep(const char *s)
122 perror(s);
123 exit(EXIT_FAILURE);
126 void dieu(const char *pname)
128 fprintf(stderr, "Usage: %s [-C] [-n length] [-s skip] -f file\n", pname);
129 exit(EXIT_FAILURE);