]> git.ipfire.org Git - thirdparty/util-linux.git/blame - text-utils/hexdump.c
Make the ways of using output stream consistent in usage()
[thirdparty/util-linux.git] / text-utils / hexdump.c
CommitLineData
6dbe3af9
KZ
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
20 *
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
31 * SUCH DAMAGE.
32 */
33
b50945d4 34 /* 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
7eda085c
KZ
35 * - added Native Language Support
36 */
37
6dbe3af9 38#include <sys/types.h>
d4646ea4 39#include <unistd.h>
6dbe3af9 40#include <stdio.h>
22853e4a 41#include <string.h>
85bf44b7 42#include <stdlib.h>
d4646ea4
OO
43#include <errno.h>
44#include <err.h>
45#include <limits.h>
46#include <getopt.h>
6dbe3af9 47#include "hexdump.h"
0a080346 48
9db51207 49#include "list.h"
7eda085c 50#include "nls.h"
0a080346 51#include "c.h"
098ab077 52#include "colors.h"
d4646ea4 53#include "strutils.h"
2152af72 54#include "xalloc.h"
b87cbe84 55#include "closestream.h"
6dbe3af9 56
1f77e9c3 57void hex_free(struct hexdump *);
d4646ea4
OO
58
59int
1f77e9c3 60parse_args(int argc, char **argv, struct hexdump *hex)
d4646ea4
OO
61{
62 int ch;
d0c9ddc3 63 int colormode = UL_COLORMODE_UNDEF;
d4646ea4
OO
64 char *hex_offt = "\"%07.7_Ax\n\"";
65
098ab077 66
d4646ea4
OO
67 static const struct option longopts[] = {
68 {"one-byte-octal", no_argument, NULL, 'b'},
bbf5bf8a 69 {"one-byte-hex", no_argument, NULL, 'X'},
925ced83
PR
70 {"one-byte-char", no_argument, NULL, 'c'},
71 {"canonical", no_argument, NULL, 'C'},
d4646ea4 72 {"two-bytes-decimal", no_argument, NULL, 'd'},
925ced83 73 {"two-bytes-octal", no_argument, NULL, 'o'},
d4646ea4
OO
74 {"two-bytes-hex", no_argument, NULL, 'x'},
75 {"format", required_argument, NULL, 'e'},
76 {"format-file", required_argument, NULL, 'f'},
098ab077 77 {"color", optional_argument, NULL, 'L'},
d4646ea4
OO
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}
84 };
85
bbf5bf8a 86 while ((ch = getopt_long(argc, argv, "bXcCde:f:L::n:os:vxhV", longopts, NULL)) != -1) {
d4646ea4
OO
87 switch (ch) {
88 case 'b':
1f77e9c3
OO
89 add_fmt(hex_offt, hex);
90 add_fmt("\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", hex);
d4646ea4 91 break;
bbf5bf8a
TW
92 case 'X':
93 add_fmt("\"%07.7_Ax\n\"", hex);
94 add_fmt("\"%07.7_ax \" 16/1 \" %02x \" \"\\n\"", hex);
95 break;
d4646ea4 96 case 'c':
1f77e9c3
OO
97 add_fmt(hex_offt, hex);
98 add_fmt("\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", hex);
d4646ea4
OO
99 break;
100 case 'C':
1f77e9c3
OO
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);
d4646ea4
OO
104 break;
105 case 'd':
1f77e9c3
OO
106 add_fmt(hex_offt, hex);
107 add_fmt("\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", hex);
d4646ea4
OO
108 break;
109 case 'e':
1f77e9c3 110 add_fmt(optarg, hex);
d4646ea4
OO
111 break;
112 case 'f':
1f77e9c3 113 addfile(optarg, hex);
d4646ea4 114 break;
0caad87f 115 case 'L':
098ab077
OO
116 colormode = UL_COLORMODE_AUTO;
117 if (optarg)
118 colormode = colormode_or_err(optarg,
119 _("unsupported color mode"));
120 break;
d4646ea4 121 case 'n':
1f77e9c3 122 hex->length = strtosize_or_err(optarg, _("failed to parse length"));
d4646ea4
OO
123 break;
124 case 'o':
1f77e9c3
OO
125 add_fmt(hex_offt, hex);
126 add_fmt("\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"", hex);
d4646ea4
OO
127 break;
128 case 's':
1f77e9c3 129 hex->skip = strtosize_or_err(optarg, _("failed to parse offset"));
d4646ea4
OO
130 break;
131 case 'v':
132 vflag = ALL;
133 break;
134 case 'x':
1f77e9c3
OO
135 add_fmt(hex_offt, hex);
136 add_fmt("\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", hex);
d4646ea4 137 break;
2c308875 138
d4646ea4 139 case 'h':
86be6a32 140 usage();
d4646ea4 141 case 'V':
2c308875 142 print_version(EXIT_SUCCESS);
d4646ea4 143 default:
677ec86c 144 errtryhelp(EXIT_FAILURE);
d4646ea4
OO
145 }
146 }
147
1f77e9c3 148 if (list_empty(&hex->fshead)) {
e1da1426
AM
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);
154 } else {
155 add_fmt(hex_offt, hex);
156 add_fmt("\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"", hex);
157 }
d4646ea4 158 }
d0c9ddc3 159 colors_init (colormode, "hexdump");
d4646ea4
OO
160 return optind;
161}
162
86be6a32 163void __attribute__((__noreturn__)) usage(void)
d4646ea4 164{
86be6a32 165 FILE *out = stdout;
d4646ea4
OO
166 fputs(USAGE_HEADER, out);
167 fprintf(out, _(" %s [options] <file>...\n"), program_invocation_short_name);
451dbcfa
BS
168
169 fputs(USAGE_SEPARATOR, out);
170 fputs(_("Display file contents in hexadecimal, decimal, octal, or ascii.\n"), out);
171
d4646ea4
OO
172 fputs(USAGE_OPTIONS, out);
173 fputs(_(" -b, --one-byte-octal one-byte octal display\n"), out);
bbf5bf8a 174 fputs(_(" -X, --one-byte-hex one-byte hexadecimal display\n"), out);
d4646ea4
OO
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);
098ab077 180 fputs(_(" -L, --color[=<mode>] interpret color formatting specifiers\n"), out);
5d51dc2a
KZ
181 fprintf(out,
182 " %s\n", USAGE_COLORS_DEFAULT);
d4646ea4
OO
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);
f1970cc5 188
d4646ea4 189 fputs(USAGE_SEPARATOR, out);
bad4c729 190 fprintf(out, USAGE_HELP_OPTIONS(27));
d4646ea4 191
f1970cc5 192 fputs(USAGE_ARGUMENTS, out);
bad4c729 193 fprintf(out, USAGE_ARG_SIZE(_("<length> and <offset>")));
f1970cc5 194
bad4c729 195 fprintf(out, USAGE_MAN_TAIL("hexdump(1)"));
86be6a32 196 exit(EXIT_SUCCESS);
d4646ea4
OO
197}
198
22853e4a 199int main(int argc, char **argv)
6dbe3af9 200{
9db51207 201 struct list_head *p;
bb8ae572 202 struct hexdump_fs *tfs;
917c3733 203 int ret;
1f77e9c3 204
2152af72 205 struct hexdump *hex = xcalloc(1, sizeof (struct hexdump));
1f77e9c3
OO
206 hex->length = -1;
207 INIT_LIST_HEAD(&hex->fshead);
6dbe3af9 208
7eda085c
KZ
209 setlocale(LC_ALL, "");
210 bindtextdomain(PACKAGE, LOCALEDIR);
211 textdomain(PACKAGE);
2c308875 212 close_stdout_atexit();
7eda085c 213
bf60e9f1 214 argv += parse_args(argc, argv, hex);
6dbe3af9
KZ
215
216 /* figure out the data block size */
1f77e9c3
OO
217 hex->blocksize = 0;
218 list_for_each(p, &hex->fshead) {
bb8ae572 219 tfs = list_entry(p, struct hexdump_fs, fslist);
1f77e9c3
OO
220 if ((tfs->bcnt = block_size(tfs)) > hex->blocksize)
221 hex->blocksize = tfs->bcnt;
6dbe3af9 222 }
9db51207 223
6dbe3af9 224 /* rewrite the rules, do syntax checking */
1f77e9c3
OO
225 list_for_each(p, &hex->fshead)
226 rewrite_rules(list_entry(p, struct hexdump_fs, fslist), hex);
6dbe3af9 227
1f77e9c3
OO
228 next(argv, hex);
229 display(hex);
917c3733
AV
230
231 ret = hex->exitval;
1f77e9c3 232 hex_free(hex);
917c3733
AV
233
234 return ret;
6dbe3af9 235}
d2740b0e 236
1f77e9c3 237void hex_free(struct hexdump *hex)
d2740b0e 238{
098ab077 239 struct list_head *p, *pn, *q, *qn, *r, *rn, *s, *sn;
bb8ae572 240 struct hexdump_fs *fs;
046921da 241 struct hexdump_fu *fu;
4c73d29c 242 struct hexdump_pr *pr;
098ab077
OO
243 struct hexdump_clr *clr;
244
1f77e9c3 245 list_for_each_safe(p, pn, &hex->fshead) {
bb8ae572 246 fs = list_entry(p, struct hexdump_fs, fslist);
d2740b0e 247 list_for_each_safe(q, qn, &fs->fulist) {
046921da 248 fu = list_entry(q, struct hexdump_fu, fulist);
d2740b0e 249 list_for_each_safe(r, rn, &fu->prlist) {
4c73d29c 250 pr = list_entry(r, struct hexdump_pr, prlist);
098ab077
OO
251 if (pr->colorlist) {
252 list_for_each_safe(s, sn, pr->colorlist) {
253 clr = list_entry (s, struct hexdump_clr, colorlist);
254 free(clr->str);
255 free(clr);
256 }
257 }
d2740b0e
OO
258 free(pr->fmt);
259 free(pr);
260 }
261 free(fu->fmt);
262 free(fu);
263 }
264 free(fs);
265 }
1f77e9c3 266 free (hex);
d2740b0e 267}