xref: /freebsd/crypto/heimdal/lib/roken/unvis.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
15e9cd1aeSAssar Westerlund /*	$NetBSD: unvis.c,v 1.19 2000/01/22 22:19:13 mycroft Exp $	*/
25e9cd1aeSAssar Westerlund 
35e9cd1aeSAssar Westerlund /*-
45e9cd1aeSAssar Westerlund  * Copyright (c) 1989, 1993
55e9cd1aeSAssar Westerlund  *	The Regents of the University of California.  All rights reserved.
65e9cd1aeSAssar Westerlund  *
75e9cd1aeSAssar Westerlund  * Redistribution and use in source and binary forms, with or without
85e9cd1aeSAssar Westerlund  * modification, are permitted provided that the following conditions
95e9cd1aeSAssar Westerlund  * are met:
105e9cd1aeSAssar Westerlund  * 1. Redistributions of source code must retain the above copyright
115e9cd1aeSAssar Westerlund  *    notice, this list of conditions and the following disclaimer.
125e9cd1aeSAssar Westerlund  * 2. Redistributions in binary form must reproduce the above copyright
135e9cd1aeSAssar Westerlund  *    notice, this list of conditions and the following disclaimer in the
145e9cd1aeSAssar Westerlund  *    documentation and/or other materials provided with the distribution.
15c19800e8SDoug Rabson  * 3. Neither the name of the University nor the names of its contributors
165e9cd1aeSAssar Westerlund  *    may be used to endorse or promote products derived from this software
175e9cd1aeSAssar Westerlund  *    without specific prior written permission.
185e9cd1aeSAssar Westerlund  *
195e9cd1aeSAssar Westerlund  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
205e9cd1aeSAssar Westerlund  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
215e9cd1aeSAssar Westerlund  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
225e9cd1aeSAssar Westerlund  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
235e9cd1aeSAssar Westerlund  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
245e9cd1aeSAssar Westerlund  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
255e9cd1aeSAssar Westerlund  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
265e9cd1aeSAssar Westerlund  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
275e9cd1aeSAssar Westerlund  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
285e9cd1aeSAssar Westerlund  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
295e9cd1aeSAssar Westerlund  * SUCH DAMAGE.
305e9cd1aeSAssar Westerlund  */
315e9cd1aeSAssar Westerlund 
325e9cd1aeSAssar Westerlund #if 1
335e9cd1aeSAssar Westerlund #include <config.h>
34c19800e8SDoug Rabson #include "roken.h"
355e9cd1aeSAssar Westerlund #ifndef _DIAGASSERT
365e9cd1aeSAssar Westerlund #define _DIAGASSERT(X)
375e9cd1aeSAssar Westerlund #endif
385e9cd1aeSAssar Westerlund #else
395e9cd1aeSAssar Westerlund #include <sys/cdefs.h>
405e9cd1aeSAssar Westerlund #if defined(LIBC_SCCS) && !defined(lint)
415e9cd1aeSAssar Westerlund #if 0
425e9cd1aeSAssar Westerlund static char sccsid[] = "@(#)unvis.c	8.1 (Berkeley) 6/4/93";
435e9cd1aeSAssar Westerlund #else
445e9cd1aeSAssar Westerlund __RCSID("$NetBSD: unvis.c,v 1.19 2000/01/22 22:19:13 mycroft Exp $");
455e9cd1aeSAssar Westerlund #endif
465e9cd1aeSAssar Westerlund #endif /* LIBC_SCCS and not lint */
475e9cd1aeSAssar Westerlund 
485e9cd1aeSAssar Westerlund #define __LIBC12_SOURCE__
495e9cd1aeSAssar Westerlund 
505e9cd1aeSAssar Westerlund #include "namespace.h"
515e9cd1aeSAssar Westerlund #endif
525e9cd1aeSAssar Westerlund #include <sys/types.h>
535e9cd1aeSAssar Westerlund 
545e9cd1aeSAssar Westerlund #include <assert.h>
555e9cd1aeSAssar Westerlund #include <ctype.h>
565e9cd1aeSAssar Westerlund #include <stdio.h>
575e9cd1aeSAssar Westerlund #include <vis.h>
585e9cd1aeSAssar Westerlund 
595e9cd1aeSAssar Westerlund #if 0
605e9cd1aeSAssar Westerlund #ifdef __weak_alias
615e9cd1aeSAssar Westerlund __weak_alias(strunvis,_strunvis)
625e9cd1aeSAssar Westerlund __weak_alias(unvis,_unvis)
635e9cd1aeSAssar Westerlund #endif
645e9cd1aeSAssar Westerlund 
655e9cd1aeSAssar Westerlund __warn_references(unvis,
665e9cd1aeSAssar Westerlund     "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
675e9cd1aeSAssar Westerlund #endif
685e9cd1aeSAssar Westerlund 
695e9cd1aeSAssar Westerlund /*
705e9cd1aeSAssar Westerlund  * decode driven by state machine
715e9cd1aeSAssar Westerlund  */
725e9cd1aeSAssar Westerlund #define	S_GROUND	0	/* haven't seen escape char */
735e9cd1aeSAssar Westerlund #define	S_START		1	/* start decoding special sequence */
745e9cd1aeSAssar Westerlund #define	S_META		2	/* metachar started (M) */
755e9cd1aeSAssar Westerlund #define	S_META1		3	/* metachar more, regular char (-) */
765e9cd1aeSAssar Westerlund #define	S_CTRL		4	/* control char started (^) */
775e9cd1aeSAssar Westerlund #define	S_OCTAL2	5	/* octal digit 2 */
785e9cd1aeSAssar Westerlund #define	S_OCTAL3	6	/* octal digit 3 */
795e9cd1aeSAssar Westerlund 
805e9cd1aeSAssar Westerlund #define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
815e9cd1aeSAssar Westerlund 
82*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
83c19800e8SDoug Rabson 	rk_strunvis (char *, const char *);
84*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
85c19800e8SDoug Rabson 	rk_unvis (char *, int, int *, int);
86c19800e8SDoug Rabson 
875e9cd1aeSAssar Westerlund /*
885e9cd1aeSAssar Westerlund  * unvis - decode characters previously encoded by vis
895e9cd1aeSAssar Westerlund  */
90c19800e8SDoug Rabson 
91*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rk_unvis(char * cp,int c,int * astate,int flag)92c19800e8SDoug Rabson rk_unvis(char *cp, int c, int *astate, int flag)
935e9cd1aeSAssar Westerlund {
945e9cd1aeSAssar Westerlund 
955e9cd1aeSAssar Westerlund 	_DIAGASSERT(cp != NULL);
965e9cd1aeSAssar Westerlund 	_DIAGASSERT(astate != NULL);
975e9cd1aeSAssar Westerlund 
985e9cd1aeSAssar Westerlund 	if (flag & UNVIS_END) {
995e9cd1aeSAssar Westerlund 		if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
1005e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1015e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1025e9cd1aeSAssar Westerlund 		}
1035e9cd1aeSAssar Westerlund 		return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
1045e9cd1aeSAssar Westerlund 	}
1055e9cd1aeSAssar Westerlund 
1065e9cd1aeSAssar Westerlund 	switch (*astate) {
1075e9cd1aeSAssar Westerlund 
1085e9cd1aeSAssar Westerlund 	case S_GROUND:
1095e9cd1aeSAssar Westerlund 		*cp = 0;
1105e9cd1aeSAssar Westerlund 		if (c == '\\') {
1115e9cd1aeSAssar Westerlund 			*astate = S_START;
1125e9cd1aeSAssar Westerlund 			return (0);
1135e9cd1aeSAssar Westerlund 		}
1145e9cd1aeSAssar Westerlund 		*cp = c;
1155e9cd1aeSAssar Westerlund 		return (UNVIS_VALID);
1165e9cd1aeSAssar Westerlund 
1175e9cd1aeSAssar Westerlund 	case S_START:
1185e9cd1aeSAssar Westerlund 		switch(c) {
1195e9cd1aeSAssar Westerlund 		case '\\':
1205e9cd1aeSAssar Westerlund 			*cp = c;
1215e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1225e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1235e9cd1aeSAssar Westerlund 		case '0': case '1': case '2': case '3':
1245e9cd1aeSAssar Westerlund 		case '4': case '5': case '6': case '7':
1255e9cd1aeSAssar Westerlund 			*cp = (c - '0');
1265e9cd1aeSAssar Westerlund 			*astate = S_OCTAL2;
1275e9cd1aeSAssar Westerlund 			return (0);
1285e9cd1aeSAssar Westerlund 		case 'M':
129*ae771770SStanislav Sedov 			*cp = (u_char)0200;
1305e9cd1aeSAssar Westerlund 			*astate = S_META;
1315e9cd1aeSAssar Westerlund 			return (0);
1325e9cd1aeSAssar Westerlund 		case '^':
1335e9cd1aeSAssar Westerlund 			*astate = S_CTRL;
1345e9cd1aeSAssar Westerlund 			return (0);
1355e9cd1aeSAssar Westerlund 		case 'n':
1365e9cd1aeSAssar Westerlund 			*cp = '\n';
1375e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1385e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1395e9cd1aeSAssar Westerlund 		case 'r':
1405e9cd1aeSAssar Westerlund 			*cp = '\r';
1415e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1425e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1435e9cd1aeSAssar Westerlund 		case 'b':
1445e9cd1aeSAssar Westerlund 			*cp = '\b';
1455e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1465e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1475e9cd1aeSAssar Westerlund 		case 'a':
1485e9cd1aeSAssar Westerlund 			*cp = '\007';
1495e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1505e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1515e9cd1aeSAssar Westerlund 		case 'v':
1525e9cd1aeSAssar Westerlund 			*cp = '\v';
1535e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1545e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1555e9cd1aeSAssar Westerlund 		case 't':
1565e9cd1aeSAssar Westerlund 			*cp = '\t';
1575e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1585e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1595e9cd1aeSAssar Westerlund 		case 'f':
1605e9cd1aeSAssar Westerlund 			*cp = '\f';
1615e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1625e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1635e9cd1aeSAssar Westerlund 		case 's':
1645e9cd1aeSAssar Westerlund 			*cp = ' ';
1655e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1665e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1675e9cd1aeSAssar Westerlund 		case 'E':
1685e9cd1aeSAssar Westerlund 			*cp = '\033';
1695e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1705e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
1715e9cd1aeSAssar Westerlund 		case '\n':
1725e9cd1aeSAssar Westerlund 			/*
1735e9cd1aeSAssar Westerlund 			 * hidden newline
1745e9cd1aeSAssar Westerlund 			 */
1755e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1765e9cd1aeSAssar Westerlund 			return (UNVIS_NOCHAR);
1775e9cd1aeSAssar Westerlund 		case '$':
1785e9cd1aeSAssar Westerlund 			/*
1795e9cd1aeSAssar Westerlund 			 * hidden marker
1805e9cd1aeSAssar Westerlund 			 */
1815e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1825e9cd1aeSAssar Westerlund 			return (UNVIS_NOCHAR);
1835e9cd1aeSAssar Westerlund 		}
1845e9cd1aeSAssar Westerlund 		*astate = S_GROUND;
1855e9cd1aeSAssar Westerlund 		return (UNVIS_SYNBAD);
1865e9cd1aeSAssar Westerlund 
1875e9cd1aeSAssar Westerlund 	case S_META:
1885e9cd1aeSAssar Westerlund 		if (c == '-')
1895e9cd1aeSAssar Westerlund 			*astate = S_META1;
1905e9cd1aeSAssar Westerlund 		else if (c == '^')
1915e9cd1aeSAssar Westerlund 			*astate = S_CTRL;
1925e9cd1aeSAssar Westerlund 		else {
1935e9cd1aeSAssar Westerlund 			*astate = S_GROUND;
1945e9cd1aeSAssar Westerlund 			return (UNVIS_SYNBAD);
1955e9cd1aeSAssar Westerlund 		}
1965e9cd1aeSAssar Westerlund 		return (0);
1975e9cd1aeSAssar Westerlund 
1985e9cd1aeSAssar Westerlund 	case S_META1:
1995e9cd1aeSAssar Westerlund 		*astate = S_GROUND;
2005e9cd1aeSAssar Westerlund 		*cp |= c;
2015e9cd1aeSAssar Westerlund 		return (UNVIS_VALID);
2025e9cd1aeSAssar Westerlund 
2035e9cd1aeSAssar Westerlund 	case S_CTRL:
2045e9cd1aeSAssar Westerlund 		if (c == '?')
2055e9cd1aeSAssar Westerlund 			*cp |= 0177;
2065e9cd1aeSAssar Westerlund 		else
2075e9cd1aeSAssar Westerlund 			*cp |= c & 037;
2085e9cd1aeSAssar Westerlund 		*astate = S_GROUND;
2095e9cd1aeSAssar Westerlund 		return (UNVIS_VALID);
2105e9cd1aeSAssar Westerlund 
2115e9cd1aeSAssar Westerlund 	case S_OCTAL2:	/* second possible octal digit */
2125e9cd1aeSAssar Westerlund 		if (isoctal(c)) {
2135e9cd1aeSAssar Westerlund 			/*
2145e9cd1aeSAssar Westerlund 			 * yes - and maybe a third
2155e9cd1aeSAssar Westerlund 			 */
2165e9cd1aeSAssar Westerlund 			*cp = (*cp << 3) + (c - '0');
2175e9cd1aeSAssar Westerlund 			*astate = S_OCTAL3;
2185e9cd1aeSAssar Westerlund 			return (0);
2195e9cd1aeSAssar Westerlund 		}
2205e9cd1aeSAssar Westerlund 		/*
2215e9cd1aeSAssar Westerlund 		 * no - done with current sequence, push back passed char
2225e9cd1aeSAssar Westerlund 		 */
2235e9cd1aeSAssar Westerlund 		*astate = S_GROUND;
2245e9cd1aeSAssar Westerlund 		return (UNVIS_VALIDPUSH);
2255e9cd1aeSAssar Westerlund 
2265e9cd1aeSAssar Westerlund 	case S_OCTAL3:	/* third possible octal digit */
2275e9cd1aeSAssar Westerlund 		*astate = S_GROUND;
2285e9cd1aeSAssar Westerlund 		if (isoctal(c)) {
2295e9cd1aeSAssar Westerlund 			*cp = (*cp << 3) + (c - '0');
2305e9cd1aeSAssar Westerlund 			return (UNVIS_VALID);
2315e9cd1aeSAssar Westerlund 		}
2325e9cd1aeSAssar Westerlund 		/*
2335e9cd1aeSAssar Westerlund 		 * we were done, push back passed char
2345e9cd1aeSAssar Westerlund 		 */
2355e9cd1aeSAssar Westerlund 		return (UNVIS_VALIDPUSH);
2365e9cd1aeSAssar Westerlund 
2375e9cd1aeSAssar Westerlund 	default:
2385e9cd1aeSAssar Westerlund 		/*
2395e9cd1aeSAssar Westerlund 		 * decoder in unknown state - (probably uninitialized)
2405e9cd1aeSAssar Westerlund 		 */
2415e9cd1aeSAssar Westerlund 		*astate = S_GROUND;
2425e9cd1aeSAssar Westerlund 		return (UNVIS_SYNBAD);
2435e9cd1aeSAssar Westerlund 	}
2445e9cd1aeSAssar Westerlund }
2455e9cd1aeSAssar Westerlund 
2465e9cd1aeSAssar Westerlund /*
2475e9cd1aeSAssar Westerlund  * strunvis - decode src into dst
2485e9cd1aeSAssar Westerlund  *
2495e9cd1aeSAssar Westerlund  *	Number of chars decoded into dst is returned, -1 on error.
2505e9cd1aeSAssar Westerlund  *	Dst is null terminated.
2515e9cd1aeSAssar Westerlund  */
2525e9cd1aeSAssar Westerlund 
253*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rk_strunvis(char * dst,const char * src)254c19800e8SDoug Rabson rk_strunvis(char *dst, const char *src)
2555e9cd1aeSAssar Westerlund {
2565e9cd1aeSAssar Westerlund 	char c;
2575e9cd1aeSAssar Westerlund 	char *start = dst;
2585e9cd1aeSAssar Westerlund 	int state = 0;
2595e9cd1aeSAssar Westerlund 
2605e9cd1aeSAssar Westerlund 	_DIAGASSERT(src != NULL);
2615e9cd1aeSAssar Westerlund 	_DIAGASSERT(dst != NULL);
2625e9cd1aeSAssar Westerlund 
2635e9cd1aeSAssar Westerlund 	while ((c = *src++) != '\0') {
2645e9cd1aeSAssar Westerlund 	again:
265c19800e8SDoug Rabson 		switch (rk_unvis(dst, (unsigned char)c, &state, 0)) {
2665e9cd1aeSAssar Westerlund 		case UNVIS_VALID:
2675e9cd1aeSAssar Westerlund 			dst++;
2685e9cd1aeSAssar Westerlund 			break;
2695e9cd1aeSAssar Westerlund 		case UNVIS_VALIDPUSH:
2705e9cd1aeSAssar Westerlund 			dst++;
2715e9cd1aeSAssar Westerlund 			goto again;
2725e9cd1aeSAssar Westerlund 		case 0:
2735e9cd1aeSAssar Westerlund 		case UNVIS_NOCHAR:
2745e9cd1aeSAssar Westerlund 			break;
2755e9cd1aeSAssar Westerlund 		default:
2765e9cd1aeSAssar Westerlund 			return (-1);
2775e9cd1aeSAssar Westerlund 		}
2785e9cd1aeSAssar Westerlund 	}
279c19800e8SDoug Rabson 	if (unvis(dst, (unsigned char)c, &state, UNVIS_END) == UNVIS_VALID)
2805e9cd1aeSAssar Westerlund 		dst++;
2815e9cd1aeSAssar Westerlund 	*dst = '\0';
2825e9cd1aeSAssar Westerlund 	return (dst - start);
2835e9cd1aeSAssar Westerlund }
284