diff options
Diffstat (limited to 'usr/src/lib/libnls/common/nlsenv.c')
| -rw-r--r-- | usr/src/lib/libnls/common/nlsenv.c | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/usr/src/lib/libnls/common/nlsenv.c b/usr/src/lib/libnls/common/nlsenv.c new file mode 100644 index 0000000000..45c5f9f760 --- /dev/null +++ b/usr/src/lib/libnls/common/nlsenv.c @@ -0,0 +1,230 @@ +/* + * 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 */ + + +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * nlsenv.c: + * + * Utilities for servers to access environment set by listener. + * + * nlsgetcall: Returns pointer to t_call structure listener recieved during + * the t_listen. Gets data from environment and converts + * the data to internal address form. + * + * nlsprovider: Returns name of provider from environment. + * + */ + +#include <ctype.h> +#include <strings.h> +#include <sys/tiuser.h> +#include "listen.h" + +/* + * define DEBUGMODE for diagnostic printf's to stderr + */ + +/* #define DEBUGMODE */ + +#ifdef DEBUGMODE +#include <stdio.h> +#endif + +/* + * nlsenv: (static) + * + * Given an environment variable name, a receiving buffer and the length + * of the receiving buffer, getenv gets the environment variable, decodes + * it and places the decoded data in addr. The return value is the length + * of "addr" if succesful, or a negative value if unsuccessful. + */ + +extern char *getenv(); + +int +nlsenv(struct netbuf *buf, char *envname) +{ + char *charaddr; + extern char *calloc(); + extern int nlsc2addr(); + int length; + + if (!(charaddr = getenv(envname))) + return(-11); + +#ifdef DEBUGMODE + fprintf(stderr, "nlsenv: environ %s = %s len = %d\n", + envname, charaddr, strlen(charaddr)); +#endif + + if ((int)strlen(charaddr) & 1) + return(-12); + + length = (strlen(charaddr) + 1) / 2; + if (!(buf->buf = calloc(1, length))) + return(-13); + else + buf->maxlen = length; + return(nlsc2addr(buf->buf, buf->maxlen, charaddr)); +} + + +/* + * nlsgetcall: Get calling data provided by the client via the listener. + * + * nlsgetcall allows network server processes started by the + * network listener process to access the callers 't_call' + * structure provided in the client's t_connect primitive. + * + * This routine gets this data from the environment + * via putenv(3C), interprets the data and places the data + * in a t_call structure allocated via t_alloc. + * + * synopsis: + * + * struct t_call *nlsgetcall(fd); + * int fd; arg now ignored + * + * + * returns: Address of an allocated t_call structure + * or + * NULL for failure. (calloc failed) + * If calloc succeeds, non-existant + * env. variables or data is indicated + * by a negative 'len' field in the approp. + * netbuf structure. A length of zero in the + * netbuf structure is valid. + * + */ + +struct t_call * +nlsgetcall(int fd) +{ + struct t_call *call; + extern char *calloc(); + + if (!(call = (struct t_call *) calloc(1, sizeof(struct t_call)))) + return((struct t_call *)0); + +/* + * Note: space for buffers gets allocated by nlsenv on the fly + */ + + call->addr.len = nlsenv(&call->addr, NLSADDR); + call->opt.len = nlsenv(&call->opt, NLSOPT); + call->udata.len = nlsenv(&call->udata, NLSUDATA); + + return (call); +} + + +/* + * nlsprovider: Return the name of the transport provider + * as placed in the environment by the Network listener + * process. If the variable is not defined in the + * environment, a NULL pointer is returned. + * + * If the provider is "/dev/starlan", nlsprovider + * returns a pointer to the null terminated character string: + * "/dev/starlan" if this calling process is a child of the + * network listener process. + */ + +char * +nlsprovider() +{ + return(getenv(NLSPROVIDER)); +} + + +/* + * nlsc2addr: Convert external address to internal form. + * (from nlsaddr.c) + */ + +/* + * asctohex(X): convert char X to integer value + * assumes isxdigit(X). returns integer value. + * Note that 'a' > 'A'. See usage in code below. + */ + +#define asctohex(X) \ + ((int)(isdigit(X) ? (int)(X-'0') : (X>='a') ? (X-'a')+10 : (X-'A')+10)) + +/* + * nlsc2addr: Given a buffer containing the hex/ascii representation + * of a logical address, the buffer's size and an address + * of a receiving buffer, char2addr converts the logical + * addr to internal format and returns the size of the logical + * address. A negative value is returned and the receiving + * buffers contents are undefined if: + * + * A. The receiving buffer is not large enough. (rc = -1) + * B. If 'charaddr' does not contain a series of octets + * (strlen(charaddr) must be even). (rc = -2) + * C. Any character in 'charaddr' is not an ASCII hex digit. + * (rc = -3) + * + * NOTE: that even if the internal representation of an address is + * an ASCII string, there is no guarantee that the output will be + * null terminated, thus the returned length must be used when + * accessing the internal address. + */ + + +int +nlsc2addr(char *addr, int maxlen, char *charaddr) +{ + int len; + int i; + char c; + unsigned char val; + + if (strlen(charaddr) & 1) + return(-1); + + for (len = 0; ((maxlen--) && (*charaddr)); ++len) { + for (i = 2, val = 0; i--; ) { + c = *charaddr++; + if (!(isxdigit(c))) + return(-3); + val = (val << 4) | (unsigned char)asctohex(c); + } + + *addr++ = (char)val; + } + +#ifdef DEBUGMODE + fprintf(stderr, "nlsc2addr: returned length = %d\n", len); +#endif + + return(*charaddr ? -2 : len); +} |
