1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */
24*7c478bd9Sstevel@tonic-gate
25*7c478bd9Sstevel@tonic-gate
26*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:stoa.c 1.4 */
27*7c478bd9Sstevel@tonic-gate
28*7c478bd9Sstevel@tonic-gate #include "uucp.h"
29*7c478bd9Sstevel@tonic-gate
30*7c478bd9Sstevel@tonic-gate #ifdef TLI
31*7c478bd9Sstevel@tonic-gate
32*7c478bd9Sstevel@tonic-gate #include <stdio.h>
33*7c478bd9Sstevel@tonic-gate #include <string.h>
34*7c478bd9Sstevel@tonic-gate #include <memory.h>
35*7c478bd9Sstevel@tonic-gate #include <malloc.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
37*7c478bd9Sstevel@tonic-gate #include <ctype.h>
38*7c478bd9Sstevel@tonic-gate #define OCT 0
39*7c478bd9Sstevel@tonic-gate #define HEX 1
40*7c478bd9Sstevel@tonic-gate /* #include <nsaddr.h>
41*7c478bd9Sstevel@tonic-gate */
42*7c478bd9Sstevel@tonic-gate #define toupper(c) (islower(c) ? _toupper(c) : (c))
43*7c478bd9Sstevel@tonic-gate #define todigit(c) ((int)((c) - '0')) /* char to digit */
44*7c478bd9Sstevel@tonic-gate #define toxdigit(c) ((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10))
45*7c478bd9Sstevel@tonic-gate #define isodigit(c) (isdigit(c) && ((c) != '9') && ((c) != '8'))
46*7c478bd9Sstevel@tonic-gate #define itoac(i) (((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0'))
47*7c478bd9Sstevel@tonic-gate #define MASK(n) ((1 << (n)) - 1)
48*7c478bd9Sstevel@tonic-gate
49*7c478bd9Sstevel@tonic-gate #define SBUFSIZE 128
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate /* #define TRUE 1;
52*7c478bd9Sstevel@tonic-gate * #define FALSE 0;
53*7c478bd9Sstevel@tonic-gate */
54*7c478bd9Sstevel@tonic-gate
55*7c478bd9Sstevel@tonic-gate GLOBAL char sbuf[SBUFSIZE];
56*7c478bd9Sstevel@tonic-gate
57*7c478bd9Sstevel@tonic-gate /* local static functions */
58*7c478bd9Sstevel@tonic-gate static int dobase();
59*7c478bd9Sstevel@tonic-gate static void memcp();
60*7c478bd9Sstevel@tonic-gate static char *xfer();
61*7c478bd9Sstevel@tonic-gate
62*7c478bd9Sstevel@tonic-gate /*
63*7c478bd9Sstevel@tonic-gate stoa - convert string to address
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate If a string begins in \o or \O, the following address is octal
66*7c478bd9Sstevel@tonic-gate " " " " " \x or \X, the following address is hex
67*7c478bd9Sstevel@tonic-gate
68*7c478bd9Sstevel@tonic-gate If ok, return pointer to netbuf structure.
69*7c478bd9Sstevel@tonic-gate A NULL is returned on any error(s).
70*7c478bd9Sstevel@tonic-gate */
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate GLOBAL struct netbuf *
stoa(str,addr)73*7c478bd9Sstevel@tonic-gate stoa(str, addr) /* Return netbuf ptr if success */
74*7c478bd9Sstevel@tonic-gate char *str; /* Return NULL if error */
75*7c478bd9Sstevel@tonic-gate struct netbuf *addr;
76*7c478bd9Sstevel@tonic-gate {
77*7c478bd9Sstevel@tonic-gate int myadr; /* was netbuf struct allocated here ? */
78*7c478bd9Sstevel@tonic-gate
79*7c478bd9Sstevel@tonic-gate myadr = FALSE;
80*7c478bd9Sstevel@tonic-gate
81*7c478bd9Sstevel@tonic-gate if (!str)
82*7c478bd9Sstevel@tonic-gate return NULL;
83*7c478bd9Sstevel@tonic-gate while (*str && isspace(*str)) /* leading whites are OK */
84*7c478bd9Sstevel@tonic-gate ++str;
85*7c478bd9Sstevel@tonic-gate
86*7c478bd9Sstevel@tonic-gate if (!str || !*str) return NULL; /* Nothing to convert */
87*7c478bd9Sstevel@tonic-gate
88*7c478bd9Sstevel@tonic-gate if (!addr) {
89*7c478bd9Sstevel@tonic-gate if ((addr = (struct netbuf *)malloc(sizeof(struct netbuf))) == NULL)
90*7c478bd9Sstevel@tonic-gate return NULL;
91*7c478bd9Sstevel@tonic-gate myadr = TRUE;
92*7c478bd9Sstevel@tonic-gate addr->buf = NULL;
93*7c478bd9Sstevel@tonic-gate addr->maxlen = 0;
94*7c478bd9Sstevel@tonic-gate addr->len = 0;
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate /* Now process the address */
98*7c478bd9Sstevel@tonic-gate if (*str == '\\') {
99*7c478bd9Sstevel@tonic-gate ++str;
100*7c478bd9Sstevel@tonic-gate switch (*str) {
101*7c478bd9Sstevel@tonic-gate
102*7c478bd9Sstevel@tonic-gate case 'X': /* hex */
103*7c478bd9Sstevel@tonic-gate case 'x':
104*7c478bd9Sstevel@tonic-gate addr->len = dobase(++str, sbuf, HEX);
105*7c478bd9Sstevel@tonic-gate break;
106*7c478bd9Sstevel@tonic-gate
107*7c478bd9Sstevel@tonic-gate case 'o': /* octal */
108*7c478bd9Sstevel@tonic-gate case 'O':
109*7c478bd9Sstevel@tonic-gate addr->len = dobase(++str, sbuf, OCT);
110*7c478bd9Sstevel@tonic-gate break;
111*7c478bd9Sstevel@tonic-gate
112*7c478bd9Sstevel@tonic-gate default: /* error */
113*7c478bd9Sstevel@tonic-gate addr->len = 0;
114*7c478bd9Sstevel@tonic-gate break;
115*7c478bd9Sstevel@tonic-gate }
116*7c478bd9Sstevel@tonic-gate }
117*7c478bd9Sstevel@tonic-gate
118*7c478bd9Sstevel@tonic-gate if (addr->len == 0) { /* Error in conversion */
119*7c478bd9Sstevel@tonic-gate if (myadr)
120*7c478bd9Sstevel@tonic-gate free(addr);
121*7c478bd9Sstevel@tonic-gate return NULL;
122*7c478bd9Sstevel@tonic-gate }
123*7c478bd9Sstevel@tonic-gate if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) == NULL)
124*7c478bd9Sstevel@tonic-gate return NULL;
125*7c478bd9Sstevel@tonic-gate else
126*7c478bd9Sstevel@tonic-gate return addr;
127*7c478bd9Sstevel@tonic-gate }
128*7c478bd9Sstevel@tonic-gate
129*7c478bd9Sstevel@tonic-gate /*
130*7c478bd9Sstevel@tonic-gate dobase : converts a hex or octal ASCII string
131*7c478bd9Sstevel@tonic-gate to a binary address. Only HEX or OCT may be used
132*7c478bd9Sstevel@tonic-gate for type.
133*7c478bd9Sstevel@tonic-gate return length of binary string (in bytes), 0 if error.
134*7c478bd9Sstevel@tonic-gate The binary result is placed at buf.
135*7c478bd9Sstevel@tonic-gate */
136*7c478bd9Sstevel@tonic-gate
137*7c478bd9Sstevel@tonic-gate static int
dobase(s,buf,type)138*7c478bd9Sstevel@tonic-gate dobase(s, buf, type) /* read in an address */
139*7c478bd9Sstevel@tonic-gate char *s, *buf; /* source ASCII, result binary string */
140*7c478bd9Sstevel@tonic-gate int type;
141*7c478bd9Sstevel@tonic-gate {
142*7c478bd9Sstevel@tonic-gate int bp = SBUFSIZE - 1;
143*7c478bd9Sstevel@tonic-gate int shift = 0;
144*7c478bd9Sstevel@tonic-gate char *end;
145*7c478bd9Sstevel@tonic-gate
146*7c478bd9Sstevel@tonic-gate for (end = s; *end && ((type == OCT) ? isodigit(*end) :
147*7c478bd9Sstevel@tonic-gate isxdigit(*end)); ++end) ;
148*7c478bd9Sstevel@tonic-gate
149*7c478bd9Sstevel@tonic-gate /* any non-white, non-digits cause address to be rejected,
150*7c478bd9Sstevel@tonic-gate other fields are ignored */
151*7c478bd9Sstevel@tonic-gate
152*7c478bd9Sstevel@tonic-gate if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) {
153*7c478bd9Sstevel@tonic-gate fprintf(stderr, "dobase: Illegal trailer on address string\n");
154*7c478bd9Sstevel@tonic-gate buf[0] = '\0';
155*7c478bd9Sstevel@tonic-gate return 0;
156*7c478bd9Sstevel@tonic-gate }
157*7c478bd9Sstevel@tonic-gate --end;
158*7c478bd9Sstevel@tonic-gate
159*7c478bd9Sstevel@tonic-gate buf[bp] = '\0';
160*7c478bd9Sstevel@tonic-gate
161*7c478bd9Sstevel@tonic-gate while (bp > 0 && end >= s) {
162*7c478bd9Sstevel@tonic-gate buf[bp] |= toxdigit(*end) << shift;
163*7c478bd9Sstevel@tonic-gate if (type == OCT) {
164*7c478bd9Sstevel@tonic-gate if (shift > 5) {
165*7c478bd9Sstevel@tonic-gate buf[--bp] = (todigit(*end) >> (8 - shift))
166*7c478bd9Sstevel@tonic-gate & MASK(shift-5);
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate if ((shift = (shift + 3) % 8) == 0)
169*7c478bd9Sstevel@tonic-gate buf[--bp] = 0;
170*7c478bd9Sstevel@tonic-gate }
171*7c478bd9Sstevel@tonic-gate else /* hex */
172*7c478bd9Sstevel@tonic-gate if ((shift = (shift) ? 0 : 4) == 0)
173*7c478bd9Sstevel@tonic-gate buf[--bp] = 0;;
174*7c478bd9Sstevel@tonic-gate --end;
175*7c478bd9Sstevel@tonic-gate }
176*7c478bd9Sstevel@tonic-gate if (bp == 0) {
177*7c478bd9Sstevel@tonic-gate fprintf(stderr, "stoa: dobase: number to long\n");
178*7c478bd9Sstevel@tonic-gate return 0;
179*7c478bd9Sstevel@tonic-gate }
180*7c478bd9Sstevel@tonic-gate
181*7c478bd9Sstevel@tonic-gate /* need to catch end case to avoid extra 0's in front */
182*7c478bd9Sstevel@tonic-gate if (!shift)
183*7c478bd9Sstevel@tonic-gate bp++;
184*7c478bd9Sstevel@tonic-gate memcp(buf, &buf[bp], (SBUFSIZE - bp));
185*7c478bd9Sstevel@tonic-gate return (SBUFSIZE - bp);
186*7c478bd9Sstevel@tonic-gate }
187*7c478bd9Sstevel@tonic-gate
188*7c478bd9Sstevel@tonic-gate static void
memcp(d,s,n)189*7c478bd9Sstevel@tonic-gate memcp(d, s, n) /* safe memcpy for overlapping regions */
190*7c478bd9Sstevel@tonic-gate char *d, *s;
191*7c478bd9Sstevel@tonic-gate int n;
192*7c478bd9Sstevel@tonic-gate {
193*7c478bd9Sstevel@tonic-gate while (n--)
194*7c478bd9Sstevel@tonic-gate *d++ = *s++;
195*7c478bd9Sstevel@tonic-gate return;
196*7c478bd9Sstevel@tonic-gate }
197*7c478bd9Sstevel@tonic-gate
198*7c478bd9Sstevel@tonic-gate /* transfer block to a given destination or allocate one of the
199*7c478bd9Sstevel@tonic-gate right size
200*7c478bd9Sstevel@tonic-gate if max = 0 : ignore max
201*7c478bd9Sstevel@tonic-gate */
202*7c478bd9Sstevel@tonic-gate
203*7c478bd9Sstevel@tonic-gate static char *
xfer(dest,src,len,max)204*7c478bd9Sstevel@tonic-gate xfer(dest, src, len, max)
205*7c478bd9Sstevel@tonic-gate char *dest, *src;
206*7c478bd9Sstevel@tonic-gate unsigned len, max;
207*7c478bd9Sstevel@tonic-gate {
208*7c478bd9Sstevel@tonic-gate if (max && dest && max < len) { /* No room */
209*7c478bd9Sstevel@tonic-gate fprintf(stderr, "xfer: destination not long enough\n");
210*7c478bd9Sstevel@tonic-gate return NULL;
211*7c478bd9Sstevel@tonic-gate }
212*7c478bd9Sstevel@tonic-gate if (!dest)
213*7c478bd9Sstevel@tonic-gate if ((dest = malloc(len)) == NULL) {
214*7c478bd9Sstevel@tonic-gate fprintf(stderr, "xfer: malloc failed\n");
215*7c478bd9Sstevel@tonic-gate return NULL;
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate
218*7c478bd9Sstevel@tonic-gate memcpy(dest, src, (int)len);
219*7c478bd9Sstevel@tonic-gate return dest;
220*7c478bd9Sstevel@tonic-gate }
221*7c478bd9Sstevel@tonic-gate
222*7c478bd9Sstevel@tonic-gate #endif /* TLI */
223