19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #ifndef lint 35c38cc743SMark Murray static const char sccsid[] = "@(#)conv.c 8.1 (Berkeley) 6/6/93"; 369b50d902SRodney W. Grimes #endif /* not lint */ 3795e5dc04SDavid E. O'Brien #include <sys/cdefs.h> 3895e5dc04SDavid E. O'Brien __FBSDID("$FreeBSD$"); 399b50d902SRodney W. Grimes 409b50d902SRodney W. Grimes #include <sys/types.h> 419b50d902SRodney W. Grimes 4240ccfb31STim J. Robbins #include <assert.h> 439b50d902SRodney W. Grimes #include <stdio.h> 449b50d902SRodney W. Grimes #include <ctype.h> 4540ccfb31STim J. Robbins #include <limits.h> 4640ccfb31STim J. Robbins #include <stdlib.h> 4740ccfb31STim J. Robbins #include <wchar.h> 4840ccfb31STim J. Robbins #include <wctype.h> 499b50d902SRodney W. Grimes #include "hexdump.h" 509b50d902SRodney W. Grimes 519b50d902SRodney W. Grimes void 5240ccfb31STim J. Robbins conv_c(PR *pr, u_char *p, size_t bufsize) 539b50d902SRodney W. Grimes { 5495e5dc04SDavid E. O'Brien char buf[10]; 5595e5dc04SDavid E. O'Brien char const *str; 5640ccfb31STim J. Robbins wchar_t wc; 5740ccfb31STim J. Robbins size_t clen, oclen; 5840ccfb31STim J. Robbins int converr, pad, width; 5940ccfb31STim J. Robbins char peekbuf[MB_LEN_MAX]; 6040ccfb31STim J. Robbins 6140ccfb31STim J. Robbins if (pr->mbleft > 0) { 6240ccfb31STim J. Robbins str = "**"; 6340ccfb31STim J. Robbins pr->mbleft--; 6440ccfb31STim J. Robbins goto strpr; 6540ccfb31STim J. Robbins } 669b50d902SRodney W. Grimes 679b50d902SRodney W. Grimes switch(*p) { 689b50d902SRodney W. Grimes case '\0': 6995e5dc04SDavid E. O'Brien str = "\\0"; 709b50d902SRodney W. Grimes goto strpr; 719b50d902SRodney W. Grimes /* case '\a': */ 729b50d902SRodney W. Grimes case '\007': 7395e5dc04SDavid E. O'Brien str = "\\a"; 749b50d902SRodney W. Grimes goto strpr; 759b50d902SRodney W. Grimes case '\b': 7695e5dc04SDavid E. O'Brien str = "\\b"; 779b50d902SRodney W. Grimes goto strpr; 789b50d902SRodney W. Grimes case '\f': 7995e5dc04SDavid E. O'Brien str = "\\f"; 809b50d902SRodney W. Grimes goto strpr; 819b50d902SRodney W. Grimes case '\n': 8295e5dc04SDavid E. O'Brien str = "\\n"; 839b50d902SRodney W. Grimes goto strpr; 849b50d902SRodney W. Grimes case '\r': 8595e5dc04SDavid E. O'Brien str = "\\r"; 869b50d902SRodney W. Grimes goto strpr; 879b50d902SRodney W. Grimes case '\t': 8895e5dc04SDavid E. O'Brien str = "\\t"; 899b50d902SRodney W. Grimes goto strpr; 909b50d902SRodney W. Grimes case '\v': 9195e5dc04SDavid E. O'Brien str = "\\v"; 929b50d902SRodney W. Grimes goto strpr; 939b50d902SRodney W. Grimes default: 949b50d902SRodney W. Grimes break; 959b50d902SRodney W. Grimes } 9640ccfb31STim J. Robbins /* 9740ccfb31STim J. Robbins * Multibyte characters are disabled for hexdump(1) for backwards 9840ccfb31STim J. Robbins * compatibility and consistency (none of its other output formats 9940ccfb31STim J. Robbins * recognize them correctly). 10040ccfb31STim J. Robbins */ 10140ccfb31STim J. Robbins converr = 0; 10240ccfb31STim J. Robbins if (odmode && MB_CUR_MAX > 1) { 10340ccfb31STim J. Robbins oclen = 0; 10440ccfb31STim J. Robbins retry: 10540ccfb31STim J. Robbins clen = mbrtowc(&wc, p, bufsize, &pr->mbstate); 10640ccfb31STim J. Robbins if (clen == 0) 10740ccfb31STim J. Robbins clen = 1; 10840ccfb31STim J. Robbins else if (clen == (size_t)-1 || (clen == (size_t)-2 && 10940ccfb31STim J. Robbins buf == peekbuf)) { 11040ccfb31STim J. Robbins memset(&pr->mbstate, 0, sizeof(pr->mbstate)); 11140ccfb31STim J. Robbins wc = *p; 11240ccfb31STim J. Robbins clen = 1; 11340ccfb31STim J. Robbins converr = 1; 11440ccfb31STim J. Robbins } else if (clen == (size_t)-2) { 11540ccfb31STim J. Robbins /* 11640ccfb31STim J. Robbins * Incomplete character; peek ahead and see if we 11740ccfb31STim J. Robbins * can complete it. 11840ccfb31STim J. Robbins */ 11940ccfb31STim J. Robbins oclen = bufsize; 12040ccfb31STim J. Robbins bufsize = peek(p = peekbuf, MB_CUR_MAX); 12140ccfb31STim J. Robbins goto retry; 12240ccfb31STim J. Robbins } 12340ccfb31STim J. Robbins clen += oclen; 12440ccfb31STim J. Robbins } else { 12540ccfb31STim J. Robbins wc = *p; 12640ccfb31STim J. Robbins clen = 1; 12740ccfb31STim J. Robbins } 12840ccfb31STim J. Robbins if (!converr && iswprint(wc)) { 12940ccfb31STim J. Robbins if (!odmode) { 1309b50d902SRodney W. Grimes *pr->cchar = 'c'; 13140ccfb31STim J. Robbins (void)printf(pr->fmt, (int)wc); 13240ccfb31STim J. Robbins } else { 13340ccfb31STim J. Robbins *pr->cchar = 'C'; 13440ccfb31STim J. Robbins assert(strcmp(pr->fmt, "%3C") == 0); 13540ccfb31STim J. Robbins width = wcwidth(wc); 13640ccfb31STim J. Robbins assert(width > 0); 13740ccfb31STim J. Robbins pad = 3 - width; 13840ccfb31STim J. Robbins if (pad < 0) 13940ccfb31STim J. Robbins pad = 0; 14040ccfb31STim J. Robbins (void)printf("%*s%C", pad, "", wc); 14140ccfb31STim J. Robbins pr->mbleft = clen - 1; 14240ccfb31STim J. Robbins } 1439b50d902SRodney W. Grimes } else { 14495e5dc04SDavid E. O'Brien (void)sprintf(buf, "%03o", (int)*p); 14595e5dc04SDavid E. O'Brien str = buf; 1469b50d902SRodney W. Grimes strpr: *pr->cchar = 's'; 1479b50d902SRodney W. Grimes (void)printf(pr->fmt, str); 1489b50d902SRodney W. Grimes } 1499b50d902SRodney W. Grimes } 1509b50d902SRodney W. Grimes 1519b50d902SRodney W. Grimes void 152f4ac32deSDavid Malone conv_u(PR *pr, u_char *p) 1539b50d902SRodney W. Grimes { 15495e5dc04SDavid E. O'Brien static char const * list[] = { 1559b50d902SRodney W. Grimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 1569b50d902SRodney W. Grimes "bs", "ht", "lf", "vt", "ff", "cr", "so", "si", 1579b50d902SRodney W. Grimes "dle", "dcl", "dc2", "dc3", "dc4", "nak", "syn", "etb", 1589b50d902SRodney W. Grimes "can", "em", "sub", "esc", "fs", "gs", "rs", "us", 1599b50d902SRodney W. Grimes }; 1609b50d902SRodney W. Grimes 1619b50d902SRodney W. Grimes /* od used nl, not lf */ 1629b50d902SRodney W. Grimes if (*p <= 0x1f) { 1639b50d902SRodney W. Grimes *pr->cchar = 's'; 164ca9cbcecSTim J. Robbins if (odmode && *p == 0x0a) 1659b50d902SRodney W. Grimes (void)printf(pr->fmt, "nl"); 1669b50d902SRodney W. Grimes else 1679b50d902SRodney W. Grimes (void)printf(pr->fmt, list[*p]); 1689b50d902SRodney W. Grimes } else if (*p == 0x7f) { 1699b50d902SRodney W. Grimes *pr->cchar = 's'; 1709b50d902SRodney W. Grimes (void)printf(pr->fmt, "del"); 171ca9cbcecSTim J. Robbins } else if (odmode && *p == 0x20) { /* od replaced space with sp */ 1729b50d902SRodney W. Grimes *pr->cchar = 's'; 1739b50d902SRodney W. Grimes (void)printf(pr->fmt, " sp"); 1749b50d902SRodney W. Grimes } else if (isprint(*p)) { 1759b50d902SRodney W. Grimes *pr->cchar = 'c'; 1769b50d902SRodney W. Grimes (void)printf(pr->fmt, *p); 1779b50d902SRodney W. Grimes } else { 1789b50d902SRodney W. Grimes *pr->cchar = 'x'; 1799b50d902SRodney W. Grimes (void)printf(pr->fmt, (int)*p); 1809b50d902SRodney W. Grimes } 1819b50d902SRodney W. Grimes } 182