]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - text-utils/hexdump.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[thirdparty/util-linux.git] / text-utils / hexdump.c
index e9fca0294185f4f73b5ba7da62f528da7d7da6bb..d7a54be5bd6f8192ac2305b51aabc9d93f62fe51 100644 (file)
@@ -49,7 +49,9 @@
 #include "list.h"
 #include "nls.h"
 #include "c.h"
+#include "colors.h"
 #include "strutils.h"
+#include "xalloc.h"
 #include "closestream.h"
 
 void hex_free(struct hexdump *);
@@ -58,17 +60,20 @@ int
 parse_args(int argc, char **argv, struct hexdump *hex)
 {
        int ch;
+       int colormode = UL_COLORMODE_UNDEF;
        char *hex_offt = "\"%07.7_Ax\n\"";
 
+
        static const struct option longopts[] = {
                {"one-byte-octal", no_argument, NULL, 'b'},
-               {"one-byte-char", required_argument, NULL, 'c'},
-               {"canonical", required_argument, NULL, 'C'},
+               {"one-byte-char", no_argument, NULL, 'c'},
+               {"canonical", no_argument, NULL, 'C'},
                {"two-bytes-decimal", no_argument, NULL, 'd'},
-               {"two-bytes-octal", required_argument, NULL, 'o'},
+               {"two-bytes-octal", no_argument, NULL, 'o'},
                {"two-bytes-hex", no_argument, NULL, 'x'},
                {"format", required_argument, NULL, 'e'},
                {"format-file", required_argument, NULL, 'f'},
+               {"color", optional_argument, NULL, 'L'},
                {"length", required_argument, NULL, 'n'},
                {"skip", required_argument, NULL, 's'},
                {"no-squeezing", no_argument, NULL, 'v'},
@@ -102,6 +107,12 @@ parse_args(int argc, char **argv, struct hexdump *hex)
                case 'f':
                        addfile(optarg, hex);
                        break;
+               case 'L':
+                       colormode = UL_COLORMODE_AUTO;
+                       if (optarg)
+                               colormode = colormode_or_err(optarg,
+                                               _("unsupported color mode"));
+                        break;
                case 'n':
                        hex->length = strtosize_or_err(optarg, _("failed to parse length"));
                        break;
@@ -119,14 +130,13 @@ parse_args(int argc, char **argv, struct hexdump *hex)
                        add_fmt(hex_offt, hex);
                        add_fmt("\"%07.7_ax \" 8/2 \"   %04x \" \"\\n\"", hex);
                        break;
+
                case 'h':
-                       usage(stdout);
+                       usage();
                case 'V':
-                       printf(UTIL_LINUX_VERSION);
-                       exit(EXIT_SUCCESS);
-                       break;
+                       print_version(EXIT_SUCCESS);
                default:
-                       usage(stderr);
+                       errtryhelp(EXIT_FAILURE);
                }
        }
 
@@ -134,13 +144,19 @@ parse_args(int argc, char **argv, struct hexdump *hex)
                add_fmt(hex_offt, hex);
                add_fmt("\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"", hex);
        }
+       colors_init (colormode, "hexdump");
        return optind;
 }
 
-void __attribute__((__noreturn__)) usage(FILE *out)
+void __attribute__((__noreturn__)) usage(void)
 {
+       FILE *out = stdout;
        fputs(USAGE_HEADER, out);
        fprintf(out, _(" %s [options] <file>...\n"), program_invocation_short_name);
+
+       fputs(USAGE_SEPARATOR, out);
+       fputs(_("Display file contents in hexadecimal, decimal, octal, or ascii.\n"), out);
+
        fputs(USAGE_OPTIONS, out);
        fputs(_(" -b, --one-byte-octal      one-byte octal display\n"), out);
        fputs(_(" -c, --one-byte-char       one-byte character display\n"), out);
@@ -148,39 +164,41 @@ void __attribute__((__noreturn__)) usage(FILE *out)
        fputs(_(" -d, --two-bytes-decimal   two-byte decimal display\n"), out);
        fputs(_(" -o, --two-bytes-octal     two-byte octal display\n"), out);
        fputs(_(" -x, --two-bytes-hex       two-byte hexadecimal display\n"), out);
+       fputs(_(" -L, --color[=<mode>]      interpret color formatting specifiers\n"), out);
+       fprintf(out,
+               "                             %s\n", USAGE_COLORS_DEFAULT);
        fputs(_(" -e, --format <format>     format string to be used for displaying data\n"), out);
        fputs(_(" -f, --format-file <file>  file that contains format strings\n"), out);
        fputs(_(" -n, --length <length>     interpret only length bytes of input\n"), out);
        fputs(_(" -s, --skip <offset>       skip offset bytes from the beginning\n"), out);
        fputs(_(" -v, --no-squeezing        output identical lines\n"), out);
+
        fputs(USAGE_SEPARATOR, out);
-       fputs(USAGE_HELP, out);
-       fputs(USAGE_VERSION, out);
-       fprintf(out, USAGE_MAN_TAIL("hexdump(1)"));
+       printf(USAGE_HELP_OPTIONS(27));
+
+       fputs(USAGE_ARGUMENTS, out);
+       printf(USAGE_ARG_SIZE(_("<length> and <offset>")));
 
-       exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+       printf(USAGE_MAN_TAIL("hexdump(1)"));
+       exit(EXIT_SUCCESS);
 }
 
 int main(int argc, char **argv)
 {
        struct list_head *p;
        struct hexdump_fs *tfs;
-       char *c;
+       int ret;
 
-       struct hexdump *hex = malloc (sizeof (struct hexdump));
+       struct hexdump *hex = xcalloc(1, sizeof (struct hexdump));
        hex->length = -1;
        INIT_LIST_HEAD(&hex->fshead);
 
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
-       atexit(close_stdout);
+       close_stdout_atexit();
 
-       if (!(c = strrchr(argv[0], 'o')) || strcmp(c, "od")) {
-               argv += parse_args(argc, argv, hex);
-       } else
-               errx(EXIT_FAILURE, _("calling hexdump as od has been deprecated "
-                                    "in favour to GNU coreutils od."));
+       argv += parse_args(argc, argv, hex);
 
        /* figure out the data block size */
        hex->blocksize = 0;
@@ -196,22 +214,34 @@ int main(int argc, char **argv)
 
        next(argv, hex);
        display(hex);
+
+       ret = hex->exitval;
        hex_free(hex);
-       return hex->exitval;
+
+       return ret;
 }
 
 void hex_free(struct hexdump *hex)
 {
-       struct list_head *p, *pn, *q, *qn, *r, *rn;
+       struct list_head *p, *pn, *q, *qn, *r, *rn, *s, *sn;
        struct hexdump_fs *fs;
        struct hexdump_fu *fu;
        struct hexdump_pr *pr;
+       struct hexdump_clr *clr;
+
        list_for_each_safe(p, pn, &hex->fshead) {
                fs = list_entry(p, struct hexdump_fs, fslist);
                list_for_each_safe(q, qn, &fs->fulist) {
                        fu = list_entry(q, struct hexdump_fu, fulist);
                        list_for_each_safe(r, rn, &fu->prlist) {
                                pr = list_entry(r, struct hexdump_pr, prlist);
+                               if (pr->colorlist) {
+                                       list_for_each_safe(s, sn, pr->colorlist) {
+                                               clr = list_entry (s, struct hexdump_clr, colorlist);
+                                               free(clr->str);
+                                               free(clr);
+                                       }
+                               }
                                free(pr->fmt);
                                free(pr);
                        }