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