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