11590Srgrimes/* 21590Srgrimes * Copyright (c) 1989, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 301590Srgrimes#ifndef lint 3187203Smarkmstatic const char sccsid[] = "@(#)conv.c 8.1 (Berkeley) 6/6/93"; 321590Srgrimes#endif /* not lint */ 3391839Sobrien#include <sys/cdefs.h> 3491839Sobrien__FBSDID("$FreeBSD$"); 351590Srgrimes 361590Srgrimes#include <sys/types.h> 371590Srgrimes 38131954Stjr#include <assert.h> 391590Srgrimes#include <ctype.h> 40131954Stjr#include <limits.h> 41132253Sjohan#include <stdio.h> 42131954Stjr#include <stdlib.h> 43132253Sjohan#include <string.h> 44131954Stjr#include <wchar.h> 45131954Stjr#include <wctype.h> 461590Srgrimes#include "hexdump.h" 471590Srgrimes 481590Srgrimesvoid 49131954Stjrconv_c(PR *pr, u_char *p, size_t bufsize) 501590Srgrimes{ 5191839Sobrien char buf[10]; 5291839Sobrien char const *str; 53131954Stjr wchar_t wc; 54131954Stjr size_t clen, oclen; 55131954Stjr int converr, pad, width; 56228636Sdim u_char peekbuf[MB_LEN_MAX]; 571590Srgrimes 58131954Stjr if (pr->mbleft > 0) { 59131954Stjr str = "**"; 60131954Stjr pr->mbleft--; 61131954Stjr goto strpr; 62131954Stjr } 63131954Stjr 641590Srgrimes switch(*p) { 651590Srgrimes case '\0': 6691839Sobrien str = "\\0"; 671590Srgrimes goto strpr; 681590Srgrimes /* case '\a': */ 691590Srgrimes case '\007': 7091839Sobrien str = "\\a"; 711590Srgrimes goto strpr; 721590Srgrimes case '\b': 7391839Sobrien str = "\\b"; 741590Srgrimes goto strpr; 751590Srgrimes case '\f': 7691839Sobrien str = "\\f"; 771590Srgrimes goto strpr; 781590Srgrimes case '\n': 7991839Sobrien str = "\\n"; 801590Srgrimes goto strpr; 811590Srgrimes case '\r': 8291839Sobrien str = "\\r"; 831590Srgrimes goto strpr; 841590Srgrimes case '\t': 8591839Sobrien str = "\\t"; 861590Srgrimes goto strpr; 871590Srgrimes case '\v': 8891839Sobrien str = "\\v"; 891590Srgrimes goto strpr; 901590Srgrimes default: 911590Srgrimes break; 921590Srgrimes } 93131954Stjr /* 94131954Stjr * Multibyte characters are disabled for hexdump(1) for backwards 95131954Stjr * compatibility and consistency (none of its other output formats 96131954Stjr * recognize them correctly). 97131954Stjr */ 98131954Stjr converr = 0; 99131954Stjr if (odmode && MB_CUR_MAX > 1) { 100131954Stjr oclen = 0; 101131954Stjrretry: 102131954Stjr clen = mbrtowc(&wc, p, bufsize, &pr->mbstate); 103131954Stjr if (clen == 0) 104131954Stjr clen = 1; 105131954Stjr else if (clen == (size_t)-1 || (clen == (size_t)-2 && 106228636Sdim p == peekbuf)) { 107131954Stjr memset(&pr->mbstate, 0, sizeof(pr->mbstate)); 108131954Stjr wc = *p; 109131954Stjr clen = 1; 110131954Stjr converr = 1; 111131954Stjr } else if (clen == (size_t)-2) { 112131954Stjr /* 113131954Stjr * Incomplete character; peek ahead and see if we 114131954Stjr * can complete it. 115131954Stjr */ 116131954Stjr oclen = bufsize; 117131954Stjr bufsize = peek(p = peekbuf, MB_CUR_MAX); 118131954Stjr goto retry; 119131954Stjr } 120131954Stjr clen += oclen; 1211590Srgrimes } else { 122131954Stjr wc = *p; 123131954Stjr clen = 1; 124131954Stjr } 125131954Stjr if (!converr && iswprint(wc)) { 126131954Stjr if (!odmode) { 127131954Stjr *pr->cchar = 'c'; 128131954Stjr (void)printf(pr->fmt, (int)wc); 129131954Stjr } else { 130131954Stjr *pr->cchar = 'C'; 131131954Stjr assert(strcmp(pr->fmt, "%3C") == 0); 132131954Stjr width = wcwidth(wc); 133160857Sjkoshy assert(width >= 0); 134131954Stjr pad = 3 - width; 135131954Stjr if (pad < 0) 136131954Stjr pad = 0; 137131954Stjr (void)printf("%*s%C", pad, "", wc); 138131954Stjr pr->mbleft = clen - 1; 139131954Stjr } 140131954Stjr } else { 14191839Sobrien (void)sprintf(buf, "%03o", (int)*p); 14291839Sobrien str = buf; 1431590Srgrimesstrpr: *pr->cchar = 's'; 1441590Srgrimes (void)printf(pr->fmt, str); 1451590Srgrimes } 1461590Srgrimes} 1471590Srgrimes 1481590Srgrimesvoid 149102944Sdwmaloneconv_u(PR *pr, u_char *p) 1501590Srgrimes{ 15191839Sobrien static char const * list[] = { 1521590Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 1531590Srgrimes "bs", "ht", "lf", "vt", "ff", "cr", "so", "si", 154247753Seadler "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 1551590Srgrimes "can", "em", "sub", "esc", "fs", "gs", "rs", "us", 1561590Srgrimes }; 1571590Srgrimes 1581590Srgrimes /* od used nl, not lf */ 1591590Srgrimes if (*p <= 0x1f) { 1601590Srgrimes *pr->cchar = 's'; 16196787Stjr if (odmode && *p == 0x0a) 1621590Srgrimes (void)printf(pr->fmt, "nl"); 1631590Srgrimes else 1641590Srgrimes (void)printf(pr->fmt, list[*p]); 1651590Srgrimes } else if (*p == 0x7f) { 1661590Srgrimes *pr->cchar = 's'; 1671590Srgrimes (void)printf(pr->fmt, "del"); 16896787Stjr } else if (odmode && *p == 0x20) { /* od replaced space with sp */ 1691590Srgrimes *pr->cchar = 's'; 1701590Srgrimes (void)printf(pr->fmt, " sp"); 1711590Srgrimes } else if (isprint(*p)) { 1721590Srgrimes *pr->cchar = 'c'; 1731590Srgrimes (void)printf(pr->fmt, *p); 1741590Srgrimes } else { 1751590Srgrimes *pr->cchar = 'x'; 1761590Srgrimes (void)printf(pr->fmt, (int)*p); 1771590Srgrimes } 1781590Srgrimes} 179