Define _FILE_OFFSET_BITS=64
[tfcrypt.git] / mhexdump.c
1 /*
2  * tfcrypt -- high security Threefish encryption tool.
3  *
4  * tfcrypt is copyrighted:
5  * Copyright (C) 2012-2018 Andrey Rys. All rights reserved.
6  *
7  * tfcrypt is licensed to you under the terms of std. MIT/X11 license:
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  */
28
29 #include <string.h>
30 #include <stdlib.h>
31
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <stdint.h>
35
36 struct mhexdump_args {
37         const void *data;
38         size_t szdata;
39         int group;
40         int hexgroup;
41         int hexstr;
42         int addaddr;
43         int newline;
44         FILE *fp;
45         int closef;
46 };
47
48 #if SIZE_MAX == 0xffffffff
49 #define ADDRFMT "%08x: "
50 #define paddr (mha->addaddr == 2 ? (uint32_t)P+(x*mha->group) : (x*mha->group))
51 #else
52 #define ADDRFMT "%016lx: "
53 #define paddr (mha->addaddr == 2 ? (uint64_t)P+(x*mha->group) : (x*mha->group))
54 #endif
55
56 #define BYTEOUT ((unsigned char)P[y+(x*mha->group)])
57
58 int fmhexdump(const struct mhexdump_args *mha)
59 {
60         const unsigned char *P = mha->data;
61         int x, y;
62
63         if (!mha->fp || !mha->data || mha->szdata == 0) return 0;
64
65         for (x = 0; x < mha->szdata/mha->group; x++) {
66                 if (mha->addaddr) fprintf(mha->fp, ADDRFMT, paddr);
67                 for (y = 0; y < mha->group; y++) {
68                         fprintf(mha->fp, "%02hhx", BYTEOUT);
69                         if (((y+1) % mha->hexgroup) == 0 && (y != (mha->group)-1)) fputc(' ', mha->fp);
70                 }
71                 if (mha->hexstr) fprintf(mha->fp, "  ");
72                 if (mha->hexstr) for (y = 0; y < mha->group; y++) {
73                         if (isprint(BYTEOUT)) fprintf(mha->fp, "%c", BYTEOUT);
74                         else fputc('.', mha->fp);
75                 }
76                 if (mha->szdata/mha->group == 1 && mha->szdata-mha->group == 0) {
77                         if (mha->newline) fputc('\n', mha->fp);
78                 }
79                 else fputc('\n', mha->fp);
80         }
81         if (mha->szdata-(x*mha->group) == 0) goto _ret;
82
83         if (mha->addaddr) fprintf(mha->fp, ADDRFMT, paddr);
84         for (y = 0; y < mha->szdata-(x*mha->group); y++) {
85                 fprintf(mha->fp, "%02hhx", BYTEOUT);
86                 if (((y+1) % mha->hexgroup) == 0) fputc(' ', mha->fp);
87         }
88         if (mha->hexstr) for (; y < mha->group; y++) {
89                 fprintf(mha->fp, "  ");
90                 if (((y+1) % mha->hexgroup) == 0 && (y != mha->group-1)) fputc(' ', mha->fp);
91         }
92         if (mha->hexstr) fprintf(mha->fp, "  ");
93         if (mha->hexstr) for (y = 0; y < mha->szdata-(x*mha->group); y++) {
94                 if (isprint(BYTEOUT)) fprintf(mha->fp, "%c", BYTEOUT);
95                 else fputc('.', mha->fp);
96         }
97
98         if (mha->newline) fputc('\n', mha->fp);
99
100 _ret:   fflush(mha->fp);
101         if (mha->closef) fclose(mha->fp);
102         return 1;
103 }
104
105 #undef BYTEOUT
106
107 int xmhexdump(int to, const void *data, size_t szdata, int hgroup, int hexstr, int newline)
108 {
109         struct mhexdump_args mha;
110
111         if (hgroup == 0) hgroup = 16;
112
113         memset(&mha, 0, sizeof(struct mhexdump_args));
114         mha.fp = (to == 2) ? stderr : stdout;
115         mha.closef = 0;
116         mha.data = data;
117         mha.szdata = szdata;
118         mha.group = hgroup;
119         mha.hexgroup = hgroup;
120         mha.hexstr = hexstr;
121         mha.addaddr = 0;
122         mha.newline = newline;
123
124         return fmhexdump(&mha);
125 }