diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/bnu/stoa.c | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/bnu/stoa.c')
| -rw-r--r-- | usr/src/cmd/bnu/stoa.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/usr/src/cmd/bnu/stoa.c b/usr/src/cmd/bnu/stoa.c new file mode 100644 index 0000000000..d26f86f967 --- /dev/null +++ b/usr/src/cmd/bnu/stoa.c @@ -0,0 +1,222 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + +#ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:stoa.c 1.4 */ + +#include "uucp.h" + +#ifdef TLI + +#include <stdio.h> +#include <string.h> +#include <memory.h> +#include <malloc.h> +#include <sys/tiuser.h> +#include <ctype.h> +#define OCT 0 +#define HEX 1 +/* #include <nsaddr.h> +*/ +#define toupper(c) (islower(c) ? _toupper(c) : (c)) +#define todigit(c) ((int)((c) - '0')) /* char to digit */ +#define toxdigit(c) ((isdigit(c))?todigit(c):(toupper(c)-(int)'A'+10)) +#define isodigit(c) (isdigit(c) && ((c) != '9') && ((c) != '8')) +#define itoac(i) (((i) > 9) ? ((char)((i)-10) + 'A'):((char)(i) + '0')) +#define MASK(n) ((1 << (n)) - 1) + +#define SBUFSIZE 128 + +/* #define TRUE 1; + * #define FALSE 0; + */ + +GLOBAL char sbuf[SBUFSIZE]; + +/* local static functions */ +static int dobase(); +static void memcp(); +static char *xfer(); + +/* + stoa - convert string to address + + If a string begins in \o or \O, the following address is octal + " " " " " \x or \X, the following address is hex + + If ok, return pointer to netbuf structure. + A NULL is returned on any error(s). +*/ + +GLOBAL struct netbuf * +stoa(str, addr) /* Return netbuf ptr if success */ +char *str; /* Return NULL if error */ +struct netbuf *addr; +{ + int myadr; /* was netbuf struct allocated here ? */ + + myadr = FALSE; + + if (!str) + return NULL; + while (*str && isspace(*str)) /* leading whites are OK */ + ++str; + + if (!str || !*str) return NULL; /* Nothing to convert */ + + if (!addr) { + if ((addr = (struct netbuf *)malloc(sizeof(struct netbuf))) == NULL) + return NULL; + myadr = TRUE; + addr->buf = NULL; + addr->maxlen = 0; + addr->len = 0; + } + + /* Now process the address */ + if (*str == '\\') { + ++str; + switch (*str) { + + case 'X': /* hex */ + case 'x': + addr->len = dobase(++str, sbuf, HEX); + break; + + case 'o': /* octal */ + case 'O': + addr->len = dobase(++str, sbuf, OCT); + break; + + default: /* error */ + addr->len = 0; + break; + } + } + + if (addr->len == 0) { /* Error in conversion */ + if (myadr) + free(addr); + return NULL; + } + if ((addr->buf = xfer(addr->buf, sbuf, addr->len, addr->maxlen)) == NULL) + return NULL; + else + return addr; +} + +/* + dobase : converts a hex or octal ASCII string + to a binary address. Only HEX or OCT may be used + for type. + return length of binary string (in bytes), 0 if error. + The binary result is placed at buf. +*/ + +static int +dobase(s, buf, type) /* read in an address */ +char *s, *buf; /* source ASCII, result binary string */ +int type; +{ + int bp = SBUFSIZE - 1; + int shift = 0; + char *end; + + for (end = s; *end && ((type == OCT) ? isodigit(*end) : + isxdigit(*end)); ++end) ; + + /* any non-white, non-digits cause address to be rejected, + other fields are ignored */ + + if ((*s == 0) || (end == s) || (!isspace(*end) && *end)) { + fprintf(stderr, "dobase: Illegal trailer on address string\n"); + buf[0] = '\0'; + return 0; + } + --end; + + buf[bp] = '\0'; + + while (bp > 0 && end >= s) { + buf[bp] |= toxdigit(*end) << shift; + if (type == OCT) { + if (shift > 5) { + buf[--bp] = (todigit(*end) >> (8 - shift)) + & MASK(shift-5); + } + if ((shift = (shift + 3) % 8) == 0) + buf[--bp] = 0; + } + else /* hex */ + if ((shift = (shift) ? 0 : 4) == 0) + buf[--bp] = 0;; + --end; + } + if (bp == 0) { + fprintf(stderr, "stoa: dobase: number to long\n"); + return 0; + } + + /* need to catch end case to avoid extra 0's in front */ + if (!shift) + bp++; + memcp(buf, &buf[bp], (SBUFSIZE - bp)); + return (SBUFSIZE - bp); +} + +static void +memcp(d, s, n) /* safe memcpy for overlapping regions */ +char *d, *s; +int n; +{ + while (n--) + *d++ = *s++; + return; +} + +/* transfer block to a given destination or allocate one of the + right size + if max = 0 : ignore max +*/ + +static char * +xfer(dest, src, len, max) +char *dest, *src; +unsigned len, max; +{ + if (max && dest && max < len) { /* No room */ + fprintf(stderr, "xfer: destination not long enough\n"); + return NULL; + } + if (!dest) + if ((dest = malloc(len)) == NULL) { + fprintf(stderr, "xfer: malloc failed\n"); + return NULL; + } + + memcpy(dest, src, (int)len); + return dest; +} + +#endif /* TLI */ |
