2 * Copyright (c) 1989 The Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 /* 1999-02-22 Arkadiusz MiĆkiewicz <misiek@pld.ORG.PL>
35 * - added Native Language Support
38 #include <sys/types.h>
55 #include "closestream.h"
57 void hex_free(struct hexdump
*);
60 parse_args(int argc
, char **argv
, struct hexdump
*hex
)
63 int colormode
= UL_COLORMODE_UNDEF
;
64 char *hex_offt
= "\"%07.7_Ax\n\"";
67 static const struct option longopts
[] = {
68 {"one-byte-octal", no_argument
, NULL
, 'b'},
69 {"one-byte-hex", no_argument
, NULL
, 'X'},
70 {"one-byte-char", no_argument
, NULL
, 'c'},
71 {"canonical", no_argument
, NULL
, 'C'},
72 {"two-bytes-decimal", no_argument
, NULL
, 'd'},
73 {"two-bytes-octal", no_argument
, NULL
, 'o'},
74 {"two-bytes-hex", no_argument
, NULL
, 'x'},
75 {"format", required_argument
, NULL
, 'e'},
76 {"format-file", required_argument
, NULL
, 'f'},
77 {"color", optional_argument
, NULL
, 'L'},
78 {"length", required_argument
, NULL
, 'n'},
79 {"skip", required_argument
, NULL
, 's'},
80 {"no-squeezing", no_argument
, NULL
, 'v'},
81 {"help", no_argument
, NULL
, 'h'},
82 {"version", no_argument
, NULL
, 'V'},
83 {NULL
, no_argument
, NULL
, 0}
86 while ((ch
= getopt_long(argc
, argv
, "bXcCde:f:L::n:os:vxhV", longopts
, NULL
)) != -1) {
89 add_fmt(hex_offt
, hex
);
90 add_fmt("\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", hex
);
93 add_fmt("\"%07.7_Ax\n\"", hex
);
94 add_fmt("\"%07.7_ax \" 16/1 \" %02x \" \"\\n\"", hex
);
97 add_fmt(hex_offt
, hex
);
98 add_fmt("\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", hex
);
101 add_fmt("\"%08.8_Ax\n\"", hex
);
102 add_fmt("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ", hex
);
103 add_fmt("\" |\" 16/1 \"%_p\" \"|\\n\"", hex
);
106 add_fmt(hex_offt
, hex
);
107 add_fmt("\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", hex
);
110 add_fmt(optarg
, hex
);
113 addfile(optarg
, hex
);
116 colormode
= UL_COLORMODE_AUTO
;
118 colormode
= colormode_or_err(optarg
,
119 _("unsupported color mode"));
122 hex
->length
= strtosize_or_err(optarg
, _("failed to parse length"));
125 add_fmt(hex_offt
, hex
);
126 add_fmt("\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"", hex
);
129 hex
->skip
= strtosize_or_err(optarg
, _("failed to parse offset"));
135 add_fmt(hex_offt
, hex
);
136 add_fmt("\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", hex
);
142 print_version(EXIT_SUCCESS
);
144 errtryhelp(EXIT_FAILURE
);
148 if (list_empty(&hex
->fshead
)) {
149 if (!strcmp(program_invocation_short_name
, "hd")) {
150 /* Canonical format */
151 add_fmt("\"%08.8_Ax\n\"", hex
);
152 add_fmt("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" ", hex
);
153 add_fmt("\" |\" 16/1 \"%_p\" \"|\\n\"", hex
);
155 add_fmt(hex_offt
, hex
);
156 add_fmt("\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"", hex
);
159 colors_init (colormode
, "hexdump");
163 void __attribute__((__noreturn__
)) usage(void)
166 fputs(USAGE_HEADER
, out
);
167 fprintf(out
, _(" %s [options] <file>...\n"), program_invocation_short_name
);
169 fputs(USAGE_SEPARATOR
, out
);
170 fputs(_("Display file contents in hexadecimal, decimal, octal, or ascii.\n"), out
);
172 fputs(USAGE_OPTIONS
, out
);
173 fputs(_(" -b, --one-byte-octal one-byte octal display\n"), out
);
174 fputs(_(" -X, --one-byte-hex one-byte hexadecimal display\n"), out
);
175 fputs(_(" -c, --one-byte-char one-byte character display\n"), out
);
176 fputs(_(" -C, --canonical canonical hex+ASCII display\n"), out
);
177 fputs(_(" -d, --two-bytes-decimal two-byte decimal display\n"), out
);
178 fputs(_(" -o, --two-bytes-octal two-byte octal display\n"), out
);
179 fputs(_(" -x, --two-bytes-hex two-byte hexadecimal display\n"), out
);
180 fputs(_(" -L, --color[=<mode>] interpret color formatting specifiers\n"), out
);
182 " %s\n", USAGE_COLORS_DEFAULT
);
183 fputs(_(" -e, --format <format> format string to be used for displaying data\n"), out
);
184 fputs(_(" -f, --format-file <file> file that contains format strings\n"), out
);
185 fputs(_(" -n, --length <length> interpret only length bytes of input\n"), out
);
186 fputs(_(" -s, --skip <offset> skip offset bytes from the beginning\n"), out
);
187 fputs(_(" -v, --no-squeezing output identical lines\n"), out
);
189 fputs(USAGE_SEPARATOR
, out
);
190 fprintf(out
, USAGE_HELP_OPTIONS(27));
192 fputs(USAGE_ARGUMENTS
, out
);
193 fprintf(out
, USAGE_ARG_SIZE(_("<length> and <offset>")));
195 fprintf(out
, USAGE_MAN_TAIL("hexdump(1)"));
199 int main(int argc
, char **argv
)
202 struct hexdump_fs
*tfs
;
205 struct hexdump
*hex
= xcalloc(1, sizeof (struct hexdump
));
207 INIT_LIST_HEAD(&hex
->fshead
);
209 setlocale(LC_ALL
, "");
210 bindtextdomain(PACKAGE
, LOCALEDIR
);
212 close_stdout_atexit();
214 argv
+= parse_args(argc
, argv
, hex
);
216 /* figure out the data block size */
218 list_for_each(p
, &hex
->fshead
) {
219 tfs
= list_entry(p
, struct hexdump_fs
, fslist
);
220 if ((tfs
->bcnt
= block_size(tfs
)) > hex
->blocksize
)
221 hex
->blocksize
= tfs
->bcnt
;
224 /* rewrite the rules, do syntax checking */
225 list_for_each(p
, &hex
->fshead
)
226 rewrite_rules(list_entry(p
, struct hexdump_fs
, fslist
), hex
);
237 void hex_free(struct hexdump
*hex
)
239 struct list_head
*p
, *pn
, *q
, *qn
, *r
, *rn
, *s
, *sn
;
240 struct hexdump_fs
*fs
;
241 struct hexdump_fu
*fu
;
242 struct hexdump_pr
*pr
;
243 struct hexdump_clr
*clr
;
245 list_for_each_safe(p
, pn
, &hex
->fshead
) {
246 fs
= list_entry(p
, struct hexdump_fs
, fslist
);
247 list_for_each_safe(q
, qn
, &fs
->fulist
) {
248 fu
= list_entry(q
, struct hexdump_fu
, fulist
);
249 list_for_each_safe(r
, rn
, &fu
->prlist
) {
250 pr
= list_entry(r
, struct hexdump_pr
, prlist
);
252 list_for_each_safe(s
, sn
, pr
->colorlist
) {
253 clr
= list_entry (s
, struct hexdump_clr
, colorlist
);