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" /* SVr4.0 1.1 */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include "uucp.h" 29*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h> 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #ifdef TLI 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdio.h> 34*7c478bd9Sstevel@tonic-gate #include <string.h> 35*7c478bd9Sstevel@tonic-gate #include <memory.h> 36*7c478bd9Sstevel@tonic-gate #include <malloc.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/tiuser.h> 38*7c478bd9Sstevel@tonic-gate #include <ctype.h> 39*7c478bd9Sstevel@tonic-gate #define OCT 0 40*7c478bd9Sstevel@tonic-gate #define HEX 1 41*7c478bd9Sstevel@tonic-gate /* #include <nsaddr.h> 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate #define toupper(c) (islower(c) ? _toupper(c) : (c)) 44*7c478bd9Sstevel@tonic-gate #define todigit(c) ((int)((c) - '0')) /* char to digit */ 45*7c478bd9Sstevel@tonic-gate #define toxdigit(c) ((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10)) 46*7c478bd9Sstevel@tonic-gate #define isodigit(c) (isdigit(c) && ((c) != '9') && ((c) != '8')) 47*7c478bd9Sstevel@tonic-gate #define itoac(i) (((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0')) 48*7c478bd9Sstevel@tonic-gate #define MASK(n) ((1 << (n)) - 1) 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #define SBUFSIZE 128 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /* #define TRUE 1; 53*7c478bd9Sstevel@tonic-gate * #define FALSE 0; 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* local static functions */ 57*7c478bd9Sstevel@tonic-gate static int dobase(); 58*7c478bd9Sstevel@tonic-gate static void memcp(); 59*7c478bd9Sstevel@tonic-gate static char *xfer(); 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate stoa - convert string to address 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate If a string begins in \o or \O, the following address is octal 65*7c478bd9Sstevel@tonic-gate " " " " " \x or \X, the following address is hex 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate If ok, return pointer to netbuf structure. 68*7c478bd9Sstevel@tonic-gate A NULL is returned on any error(s). 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate GLOBAL struct netbuf * 72*7c478bd9Sstevel@tonic-gate stoa(str, addr) /* Return netbuf ptr if success */ 73*7c478bd9Sstevel@tonic-gate char *str; /* Return NULL if error */ 74*7c478bd9Sstevel@tonic-gate struct netbuf *addr; 75*7c478bd9Sstevel@tonic-gate { 76*7c478bd9Sstevel@tonic-gate int myadr; /* was netbuf struct allocated here ? */ 77*7c478bd9Sstevel@tonic-gate static char *sbuf; 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 0); 80*7c478bd9Sstevel@tonic-gate myadr = FALSE; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate if (!str) { 83*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 1); 84*7c478bd9Sstevel@tonic-gate return (NULL); 85*7c478bd9Sstevel@tonic-gate } 86*7c478bd9Sstevel@tonic-gate while (*str && isspace(*str)) /* leading whites are OK */ 87*7c478bd9Sstevel@tonic-gate ++str; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate if (!str || !*str) { /* Nothing to convert */ 90*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 1); 91*7c478bd9Sstevel@tonic-gate return (NULL); 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate if (!addr) { 95*7c478bd9Sstevel@tonic-gate if ((addr = (struct netbuf *)malloc(sizeof(struct netbuf))) == NULL) { 96*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 1); 97*7c478bd9Sstevel@tonic-gate return (NULL); 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate myadr = TRUE; 101*7c478bd9Sstevel@tonic-gate addr->buf = NULL; 102*7c478bd9Sstevel@tonic-gate addr->maxlen = 0; 103*7c478bd9Sstevel@tonic-gate addr->len = 0; 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate if (sbuf == NULL) { 107*7c478bd9Sstevel@tonic-gate sbuf = (char *)malloc(SBUFSIZE); 108*7c478bd9Sstevel@tonic-gate if (sbuf == NULL) 109*7c478bd9Sstevel@tonic-gate return (NULL); 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* Now process the address */ 113*7c478bd9Sstevel@tonic-gate if (*str == '\\') { 114*7c478bd9Sstevel@tonic-gate ++str; 115*7c478bd9Sstevel@tonic-gate switch (*str) { 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate case 'X': /* hex */ 118*7c478bd9Sstevel@tonic-gate case 'x': 119*7c478bd9Sstevel@tonic-gate addr->len = dobase(++str, sbuf, HEX); 120*7c478bd9Sstevel@tonic-gate break; 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate case 'o': /* octal */ 123*7c478bd9Sstevel@tonic-gate case 'O': 124*7c478bd9Sstevel@tonic-gate addr->len = dobase(++str, sbuf, OCT); 125*7c478bd9Sstevel@tonic-gate break; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate default: /* error */ 128*7c478bd9Sstevel@tonic-gate addr->len = 0; 129*7c478bd9Sstevel@tonic-gate break; 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate if (addr->len == 0) { /* Error in conversion */ 134*7c478bd9Sstevel@tonic-gate if (myadr) 135*7c478bd9Sstevel@tonic-gate free(addr); 136*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 1); 137*7c478bd9Sstevel@tonic-gate return (NULL); 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) == NULL) { 140*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 1); 141*7c478bd9Sstevel@tonic-gate return (NULL); 142*7c478bd9Sstevel@tonic-gate } else { 143*7c478bd9Sstevel@tonic-gate trace1(TR_stoa, 1); 144*7c478bd9Sstevel@tonic-gate return addr; 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate /* 149*7c478bd9Sstevel@tonic-gate dobase : converts a hex or octal ASCII string 150*7c478bd9Sstevel@tonic-gate to a binary address. Only HEX or OCT may be used 151*7c478bd9Sstevel@tonic-gate for type. 152*7c478bd9Sstevel@tonic-gate return length of binary string (in bytes), 0 if error. 153*7c478bd9Sstevel@tonic-gate The binary result is placed at buf. 154*7c478bd9Sstevel@tonic-gate */ 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate static int 157*7c478bd9Sstevel@tonic-gate dobase(s, buf, type) /* read in an address */ 158*7c478bd9Sstevel@tonic-gate char *s, *buf; /* source ASCII, result binary string */ 159*7c478bd9Sstevel@tonic-gate int type; 160*7c478bd9Sstevel@tonic-gate { 161*7c478bd9Sstevel@tonic-gate int bp = SBUFSIZE - 1; 162*7c478bd9Sstevel@tonic-gate int shift = 0; 163*7c478bd9Sstevel@tonic-gate char *end; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate trace2(TR_dobase, 0, type); 166*7c478bd9Sstevel@tonic-gate for (end = s; *end && ((type == OCT) ? isodigit(*end) : 167*7c478bd9Sstevel@tonic-gate isxdigit(*end)); ++end) ; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* any non-white, non-digits cause address to be rejected, 170*7c478bd9Sstevel@tonic-gate other fields are ignored */ 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) { 173*7c478bd9Sstevel@tonic-gate fprintf(stderr, "dobase: Illegal trailer on address string\n"); 174*7c478bd9Sstevel@tonic-gate buf[0] = '\0'; 175*7c478bd9Sstevel@tonic-gate trace1(TR_dobase, 1); 176*7c478bd9Sstevel@tonic-gate return (0); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate --end; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate buf[bp] = '\0'; 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate while (bp > 0 && end >= s) { 183*7c478bd9Sstevel@tonic-gate buf[bp] |= toxdigit(*end) << shift; 184*7c478bd9Sstevel@tonic-gate if (type == OCT) { 185*7c478bd9Sstevel@tonic-gate if (shift > 5) { 186*7c478bd9Sstevel@tonic-gate buf[--bp] = (todigit(*end) >> (8 - shift)) 187*7c478bd9Sstevel@tonic-gate & MASK(shift-5); 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate if ((shift = (shift + 3) % 8) == 0) 190*7c478bd9Sstevel@tonic-gate buf[--bp] = 0; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate else /* hex */ 193*7c478bd9Sstevel@tonic-gate if ((shift = (shift) ? 0 : 4) == 0) 194*7c478bd9Sstevel@tonic-gate buf[--bp] = 0;; 195*7c478bd9Sstevel@tonic-gate --end; 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate if (bp == 0) { 198*7c478bd9Sstevel@tonic-gate fprintf(stderr, "stoa: dobase: number to long\n"); 199*7c478bd9Sstevel@tonic-gate trace1(TR_dobase, 1); 200*7c478bd9Sstevel@tonic-gate return (0); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate /* need to catch end case to avoid extra 0's in front */ 204*7c478bd9Sstevel@tonic-gate if (!shift) 205*7c478bd9Sstevel@tonic-gate bp++; 206*7c478bd9Sstevel@tonic-gate memcp(buf, &buf[bp], (SBUFSIZE - bp)); 207*7c478bd9Sstevel@tonic-gate trace1(TR_dobase, 1); 208*7c478bd9Sstevel@tonic-gate return (SBUFSIZE - bp); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate static void 212*7c478bd9Sstevel@tonic-gate memcp(d, s, n) /* safe memcpy for overlapping regions */ 213*7c478bd9Sstevel@tonic-gate char *d, *s; 214*7c478bd9Sstevel@tonic-gate int n; 215*7c478bd9Sstevel@tonic-gate { 216*7c478bd9Sstevel@tonic-gate trace2(TR_memcp, 0, n); 217*7c478bd9Sstevel@tonic-gate while (n--) 218*7c478bd9Sstevel@tonic-gate *d++ = *s++; 219*7c478bd9Sstevel@tonic-gate trace1(TR_memcp, 1); 220*7c478bd9Sstevel@tonic-gate return; 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* transfer block to a given destination or allocate one of the 224*7c478bd9Sstevel@tonic-gate right size 225*7c478bd9Sstevel@tonic-gate if max = 0 : ignore max 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate static char * 229*7c478bd9Sstevel@tonic-gate xfer(dest, src, len, max) 230*7c478bd9Sstevel@tonic-gate char *dest, *src; 231*7c478bd9Sstevel@tonic-gate unsigned len, max; 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate trace3(TR_xfer, 0, len, max); 234*7c478bd9Sstevel@tonic-gate if (max && dest && max < len) { /* No room */ 235*7c478bd9Sstevel@tonic-gate fprintf(stderr, "xfer: destination not long enough\n"); 236*7c478bd9Sstevel@tonic-gate trace1(TR_xfer, 1); 237*7c478bd9Sstevel@tonic-gate return (NULL); 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate if (!dest) 240*7c478bd9Sstevel@tonic-gate if ((dest = malloc(len)) == NULL) { 241*7c478bd9Sstevel@tonic-gate fprintf(stderr, "xfer: malloc failed\n"); 242*7c478bd9Sstevel@tonic-gate trace1(TR_xfer, 1); 243*7c478bd9Sstevel@tonic-gate return (NULL); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate memcpy(dest, src, (int)len); 247*7c478bd9Sstevel@tonic-gate trace1(TR_xfer, 1); 248*7c478bd9Sstevel@tonic-gate return (dest); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate #endif /* TLI */ 252