xref: /illumos-gate/usr/src/lib/libnsl/dial/stoa.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
2261961e0fSrobinson 
2361961e0fSrobinson /*
24*e8031f0aSraf  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
2561961e0fSrobinson  * Use is subject to license terms.
2661961e0fSrobinson  */
2761961e0fSrobinson 
287c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
297c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
307c478bd9Sstevel@tonic-gate 
31*e8031f0aSraf #include "mt.h"
327c478bd9Sstevel@tonic-gate #include "uucp.h"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #ifdef TLI
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <stdio.h>
377c478bd9Sstevel@tonic-gate #include <string.h>
387c478bd9Sstevel@tonic-gate #include <memory.h>
397c478bd9Sstevel@tonic-gate #include <malloc.h>
407c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
417c478bd9Sstevel@tonic-gate #include <ctype.h>
427c478bd9Sstevel@tonic-gate #define	OCT	0
437c478bd9Sstevel@tonic-gate #define	HEX	1
4461961e0fSrobinson /*
4561961e0fSrobinson  * #include <nsaddr.h>
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate #define	toupper(c)	(islower(c) ? _toupper(c) : (c))
487c478bd9Sstevel@tonic-gate #define	todigit(c)	((int)((c) - '0'))	/* char to digit */
497c478bd9Sstevel@tonic-gate #define	toxdigit(c)	((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10))
507c478bd9Sstevel@tonic-gate #define	isodigit(c)	(isdigit(c) && ((c) != '9') && ((c) != '8'))
517c478bd9Sstevel@tonic-gate #define	itoac(i)	(((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0'))
527c478bd9Sstevel@tonic-gate #define	MASK(n)		((1 << (n)) - 1)
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #define	SBUFSIZE	128
557c478bd9Sstevel@tonic-gate 
5661961e0fSrobinson /*
5761961e0fSrobinson  * #define	TRUE	1
5861961e0fSrobinson  * #define	FALSE	0
597c478bd9Sstevel@tonic-gate  */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate /*	local static functions	*/
6261961e0fSrobinson static int dobase(char *, char *, int);
6361961e0fSrobinson static void memcp(char *, char *, int);
6461961e0fSrobinson static char *xfer(char *, char *, unsigned, unsigned);
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
6761961e0fSrobinson  *	stoa - convert string to address
6861961e0fSrobinson  *
6961961e0fSrobinson  *	If a string begins in \o or \O, the following address is octal
7061961e0fSrobinson  *	"  "   "       "    " \x or \X, the following address is hex
7161961e0fSrobinson  *
7261961e0fSrobinson  *	If ok, return pointer to netbuf structure.
7361961e0fSrobinson  *	A  NULL is returned on any error(s).
747c478bd9Sstevel@tonic-gate  */
757c478bd9Sstevel@tonic-gate 
7661961e0fSrobinson /* Return netbuf ptr if success */
7761961e0fSrobinson static struct netbuf *
stoa(char * str,struct netbuf * addr)7861961e0fSrobinson stoa(char *str, struct netbuf *addr)
797c478bd9Sstevel@tonic-gate {
807c478bd9Sstevel@tonic-gate 	int	myadr;		/* was netbuf struct allocated here ? */
817c478bd9Sstevel@tonic-gate 	static	char *sbuf;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	myadr = FALSE;
847c478bd9Sstevel@tonic-gate 
8561961e0fSrobinson 	if (!str)
867c478bd9Sstevel@tonic-gate 		return (NULL);
877c478bd9Sstevel@tonic-gate 	while (*str && isspace(*str))	/* leading whites are OK */
887c478bd9Sstevel@tonic-gate 		++str;
897c478bd9Sstevel@tonic-gate 
9061961e0fSrobinson 	if (!str || !*str)	/* Nothing to convert */
917c478bd9Sstevel@tonic-gate 		return (NULL);
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	if (!addr) {
9461961e0fSrobinson 		if ((addr = malloc(sizeof (struct netbuf))) == NULL)
957c478bd9Sstevel@tonic-gate 			return (NULL);
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 		myadr = TRUE;
987c478bd9Sstevel@tonic-gate 		addr->buf = NULL;
997c478bd9Sstevel@tonic-gate 		addr->maxlen = 0;
1007c478bd9Sstevel@tonic-gate 		addr->len = 0;
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	if (sbuf == NULL) {
10461961e0fSrobinson 		sbuf = malloc(SBUFSIZE);
1057c478bd9Sstevel@tonic-gate 		if (sbuf == NULL)
1067c478bd9Sstevel@tonic-gate 			return (NULL);
1077c478bd9Sstevel@tonic-gate 	}
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	/* Now process the address */
1107c478bd9Sstevel@tonic-gate 	if (*str == '\\') {
1117c478bd9Sstevel@tonic-gate 		++str;
1127c478bd9Sstevel@tonic-gate 		switch (*str) {
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 		case 'X':	/* hex */
1157c478bd9Sstevel@tonic-gate 		case 'x':
1167c478bd9Sstevel@tonic-gate 			addr->len = dobase(++str, sbuf, HEX);
1177c478bd9Sstevel@tonic-gate 			break;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 		case 'o':	/* octal */
1207c478bd9Sstevel@tonic-gate 		case 'O':
1217c478bd9Sstevel@tonic-gate 			addr->len = dobase(++str, sbuf, OCT);
1227c478bd9Sstevel@tonic-gate 			break;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 		default:	/* error */
1257c478bd9Sstevel@tonic-gate 			addr->len = 0;
1267c478bd9Sstevel@tonic-gate 			break;
1277c478bd9Sstevel@tonic-gate 		}
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	if (addr->len == 0) {	/* Error in conversion */
1317c478bd9Sstevel@tonic-gate 		if (myadr)
1327c478bd9Sstevel@tonic-gate 			free(addr);
1337c478bd9Sstevel@tonic-gate 		return (NULL);
1347c478bd9Sstevel@tonic-gate 	}
13561961e0fSrobinson 	if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) ==
13661961e0fSrobinson 									NULL)
1377c478bd9Sstevel@tonic-gate 		return (NULL);
13861961e0fSrobinson 	return (addr);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /*
14261961e0fSrobinson  *	dobase :	converts a hex or octal ASCII string
14361961e0fSrobinson  *		to a binary address. Only HEX or OCT may be used
14461961e0fSrobinson  *		for type.
14561961e0fSrobinson  *	return length of binary string (in bytes), 0 if error.
14661961e0fSrobinson  *	The binary result is placed at buf.
1477c478bd9Sstevel@tonic-gate  */
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate static int
dobase(char * s,char * buf,int type)15061961e0fSrobinson dobase(char *s, char *buf, int type)
1517c478bd9Sstevel@tonic-gate {
1527c478bd9Sstevel@tonic-gate 	int	bp = SBUFSIZE - 1;
1537c478bd9Sstevel@tonic-gate 	int	shift = 0;
1547c478bd9Sstevel@tonic-gate 	char	*end;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	for (end = s; *end && ((type == OCT) ? isodigit(*end) :
15761961e0fSrobinson 							isxdigit(*end)); ++end)
15861961e0fSrobinson 		;
1597c478bd9Sstevel@tonic-gate 
16061961e0fSrobinson 	/*
16161961e0fSrobinson 	 * any non-white, non-digits cause address to be rejected,
16261961e0fSrobinson 	 * other fields are ignored
16361961e0fSrobinson 	 */
1647c478bd9Sstevel@tonic-gate 	if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) {
16561961e0fSrobinson 		(void) fprintf(stderr,
16661961e0fSrobinson 				"dobase: Illegal trailer on address string\n");
1677c478bd9Sstevel@tonic-gate 		buf[0] = '\0';
1687c478bd9Sstevel@tonic-gate 		return (0);
1697c478bd9Sstevel@tonic-gate 	}
1707c478bd9Sstevel@tonic-gate 	--end;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	buf[bp] = '\0';
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	while (bp > 0 && end >= s) {
1757c478bd9Sstevel@tonic-gate 		buf[bp] |= toxdigit(*end) << shift;
1767c478bd9Sstevel@tonic-gate 		if (type == OCT) {
1777c478bd9Sstevel@tonic-gate 			if (shift > 5) {
1787c478bd9Sstevel@tonic-gate 				buf[--bp] = (todigit(*end) >> (8 - shift))
1797c478bd9Sstevel@tonic-gate 					& MASK(shift-5);
1807c478bd9Sstevel@tonic-gate 			}
1817c478bd9Sstevel@tonic-gate 			if ((shift = (shift + 3) % 8) == 0)
1827c478bd9Sstevel@tonic-gate 				buf[--bp] = 0;
18361961e0fSrobinson 		} else	/* hex */
1847c478bd9Sstevel@tonic-gate 			if ((shift = (shift) ? 0 : 4) == 0)
18561961e0fSrobinson 				buf[--bp] = 0;
1867c478bd9Sstevel@tonic-gate 		--end;
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 	if (bp == 0) {
18961961e0fSrobinson 		(void) fprintf(stderr, "stoa: dobase: number to long\n");
1907c478bd9Sstevel@tonic-gate 		return (0);
1917c478bd9Sstevel@tonic-gate 	}
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 	/* need to catch end case to avoid extra 0's in front	*/
1947c478bd9Sstevel@tonic-gate 	if (!shift)
1957c478bd9Sstevel@tonic-gate 		bp++;
1967c478bd9Sstevel@tonic-gate 	memcp(buf, &buf[bp], (SBUFSIZE - bp));
1977c478bd9Sstevel@tonic-gate 	return (SBUFSIZE - bp);
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate static void
memcp(char * d,char * s,int n)20161961e0fSrobinson memcp(char *d, char *s, int n)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	while (n--)
2047c478bd9Sstevel@tonic-gate 		*d++ = *s++;
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
20761961e0fSrobinson /*
20861961e0fSrobinson  * transfer block to a given destination or allocate one of the
20961961e0fSrobinson  *	right size
21061961e0fSrobinson  *	if max = 0 : ignore max
2117c478bd9Sstevel@tonic-gate  */
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate static char *
xfer(char * dest,char * src,unsigned len,unsigned max)21461961e0fSrobinson xfer(char *dest, char *src, unsigned len, unsigned max)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate 	if (max && dest && max < len) {		/* No room */
21761961e0fSrobinson 		(void) fprintf(stderr, "xfer: destination not long enough\n");
2187c478bd9Sstevel@tonic-gate 		return (NULL);
2197c478bd9Sstevel@tonic-gate 	}
2207c478bd9Sstevel@tonic-gate 	if (!dest)
2217c478bd9Sstevel@tonic-gate 		if ((dest = malloc(len)) == NULL) {
22261961e0fSrobinson 			(void) fprintf(stderr, "xfer: malloc failed\n");
2237c478bd9Sstevel@tonic-gate 			return (NULL);
2247c478bd9Sstevel@tonic-gate 		}
2257c478bd9Sstevel@tonic-gate 
22661961e0fSrobinson 	(void) memcpy(dest, src, (size_t)len);
2277c478bd9Sstevel@tonic-gate 	return (dest);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate #endif /* TLI */
230