2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A
2N/A/*
2N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * nlsenv.c:
2N/A *
2N/A * Utilities for servers to access environment set by listener.
2N/A *
2N/A * nlsgetcall: Returns pointer to t_call structure listener recieved during
2N/A * the t_listen. Gets data from environment and converts
2N/A * the data to internal address form.
2N/A *
2N/A * nlsprovider: Returns name of provider from environment.
2N/A *
2N/A */
2N/A
2N/A#include <ctype.h>
2N/A#include <strings.h>
2N/A#include <sys/tiuser.h>
2N/A#include "listen.h"
2N/A
2N/A/*
2N/A * define DEBUGMODE for diagnostic printf's to stderr
2N/A */
2N/A
2N/A/* #define DEBUGMODE */
2N/A
2N/A#ifdef DEBUGMODE
2N/A#include <stdio.h>
2N/A#endif
2N/A
2N/A/*
2N/A * nlsenv: (static)
2N/A *
2N/A * Given an environment variable name, a receiving buffer and the length
2N/A * of the receiving buffer, getenv gets the environment variable, decodes
2N/A * it and places the decoded data in addr. The return value is the length
2N/A * of "addr" if succesful, or a negative value if unsuccessful.
2N/A */
2N/A
2N/Aextern char *getenv();
2N/A
2N/Aint
2N/Anlsenv(struct netbuf *buf, char *envname)
2N/A{
2N/A char *charaddr;
2N/A extern char *calloc();
2N/A extern int nlsc2addr();
2N/A int length;
2N/A
2N/A if (!(charaddr = getenv(envname)))
2N/A return(-11);
2N/A
2N/A#ifdef DEBUGMODE
2N/A fprintf(stderr, "nlsenv: environ %s = %s len = %d\n",
2N/A envname, charaddr, strlen(charaddr));
2N/A#endif
2N/A
2N/A if ((int)strlen(charaddr) & 1)
2N/A return(-12);
2N/A
2N/A length = (strlen(charaddr) + 1) / 2;
2N/A if (!(buf->buf = calloc(1, length)))
2N/A return(-13);
2N/A else
2N/A buf->maxlen = length;
2N/A return(nlsc2addr(buf->buf, buf->maxlen, charaddr));
2N/A}
2N/A
2N/A
2N/A/*
2N/A * nlsgetcall: Get calling data provided by the client via the listener.
2N/A *
2N/A * nlsgetcall allows network server processes started by the
2N/A * network listener process to access the callers 't_call'
2N/A * structure provided in the client's t_connect primitive.
2N/A *
2N/A * This routine gets this data from the environment
2N/A * via putenv(3C), interprets the data and places the data
2N/A * in a t_call structure allocated via t_alloc.
2N/A *
2N/A * synopsis:
2N/A *
2N/A * struct t_call *nlsgetcall(fd);
2N/A * int fd; arg now ignored
2N/A *
2N/A *
2N/A * returns: Address of an allocated t_call structure
2N/A * or
2N/A * NULL for failure. (calloc failed)
2N/A * If calloc succeeds, non-existant
2N/A * env. variables or data is indicated
2N/A * by a negative 'len' field in the approp.
2N/A * netbuf structure. A length of zero in the
2N/A * netbuf structure is valid.
2N/A *
2N/A */
2N/A
2N/Astruct t_call *
2N/Anlsgetcall(int fd)
2N/A{
2N/A struct t_call *call;
2N/A extern char *calloc();
2N/A
2N/A if (!(call = (struct t_call *) calloc(1, sizeof(struct t_call))))
2N/A return((struct t_call *)0);
2N/A
2N/A/*
2N/A * Note: space for buffers gets allocated by nlsenv on the fly
2N/A */
2N/A
2N/A call->addr.len = nlsenv(&call->addr, NLSADDR);
2N/A call->opt.len = nlsenv(&call->opt, NLSOPT);
2N/A call->udata.len = nlsenv(&call->udata, NLSUDATA);
2N/A
2N/A return (call);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * nlsprovider: Return the name of the transport provider
2N/A * as placed in the environment by the Network listener
2N/A * process. If the variable is not defined in the
2N/A * environment, a NULL pointer is returned.
2N/A *
2N/A * If the provider is "/dev/starlan", nlsprovider
2N/A * returns a pointer to the null terminated character string:
2N/A * "/dev/starlan" if this calling process is a child of the
2N/A * network listener process.
2N/A */
2N/A
2N/Achar *
2N/Anlsprovider()
2N/A{
2N/A return(getenv(NLSPROVIDER));
2N/A}
2N/A
2N/A
2N/A/*
2N/A * nlsc2addr: Convert external address to internal form.
2N/A * (from nlsaddr.c)
2N/A */
2N/A
2N/A/*
2N/A * asctohex(X): convert char X to integer value
2N/A * assumes isxdigit(X). returns integer value.
2N/A * Note that 'a' > 'A'. See usage in code below.
2N/A */
2N/A
2N/A#define asctohex(X) \
2N/A ((int)(isdigit(X) ? (int)(X-'0') : (X>='a') ? (X-'a')+10 : (X-'A')+10))
2N/A
2N/A/*
2N/A * nlsc2addr: Given a buffer containing the hex/ascii representation
2N/A * of a logical address, the buffer's size and an address
2N/A * of a receiving buffer, char2addr converts the logical
2N/A * addr to internal format and returns the size of the logical
2N/A * address. A negative value is returned and the receiving
2N/A * buffers contents are undefined if:
2N/A *
2N/A * A. The receiving buffer is not large enough. (rc = -1)
2N/A * B. If 'charaddr' does not contain a series of octets
2N/A * (strlen(charaddr) must be even). (rc = -2)
2N/A * C. Any character in 'charaddr' is not an ASCII hex digit.
2N/A * (rc = -3)
2N/A *
2N/A * NOTE: that even if the internal representation of an address is
2N/A * an ASCII string, there is no guarantee that the output will be
2N/A * null terminated, thus the returned length must be used when
2N/A * accessing the internal address.
2N/A */
2N/A
2N/A
2N/Aint
2N/Anlsc2addr(char *addr, int maxlen, char *charaddr)
2N/A{
2N/A int len;
2N/A int i;
2N/A char c;
2N/A unsigned char val;
2N/A
2N/A if (strlen(charaddr) & 1)
2N/A return(-1);
2N/A
2N/A for (len = 0; ((maxlen--) && (*charaddr)); ++len) {
2N/A for (i = 2, val = 0; i--; ) {
2N/A c = *charaddr++;
2N/A if (!(isxdigit(c)))
2N/A return(-3);
2N/A val = (val << 4) | (unsigned char)asctohex(c);
2N/A }
2N/A
2N/A *addr++ = (char)val;
2N/A }
2N/A
2N/A#ifdef DEBUGMODE
2N/A fprintf(stderr, "nlsc2addr: returned length = %d\n", len);
2N/A#endif
2N/A
2N/A return(*charaddr ? -2 : len);
2N/A}