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 * 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 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 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 * 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