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