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