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 /* 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * nlsenv.c: 33 * 34 * Utilities for servers to access environment set by listener. 35 * 36 * nlsgetcall: Returns pointer to t_call structure listener recieved during 37 * the t_listen. Gets data from environment and converts 38 * the data to internal address form. 39 * 40 * nlsprovider: Returns name of provider from environment. 41 * 42 */ 43 44 #include <ctype.h> 45 #include <strings.h> 46 #include <sys/tiuser.h> 47 #include "listen.h" 48 49 /* 50 * define DEBUGMODE for diagnostic printf's to stderr 51 */ 52 53 /* #define DEBUGMODE */ 54 55 #ifdef DEBUGMODE 56 #include <stdio.h> 57 #endif 58 59 /* 60 * nlsenv: (static) 61 * 62 * Given an environment variable name, a receiving buffer and the length 63 * of the receiving buffer, getenv gets the environment variable, decodes 64 * it and places the decoded data in addr. The return value is the length 65 * of "addr" if succesful, or a negative value if unsuccessful. 66 */ 67 68 extern char *getenv(); 69 70 int 71 nlsenv(struct netbuf *buf, char *envname) 72 { 73 char *charaddr; 74 extern char *calloc(); 75 extern int nlsc2addr(); 76 int length; 77 78 if (!(charaddr = getenv(envname))) 79 return(-11); 80 81 #ifdef DEBUGMODE 82 fprintf(stderr, "nlsenv: environ %s = %s len = %d\n", 83 envname, charaddr, strlen(charaddr)); 84 #endif 85 86 if ((int)strlen(charaddr) & 1) 87 return(-12); 88 89 length = (strlen(charaddr) + 1) / 2; 90 if (!(buf->buf = calloc(1, length))) 91 return(-13); 92 else 93 buf->maxlen = length; 94 return(nlsc2addr(buf->buf, buf->maxlen, charaddr)); 95 } 96 97 98 /* 99 * nlsgetcall: Get calling data provided by the client via the listener. 100 * 101 * nlsgetcall allows network server processes started by the 102 * network listener process to access the callers 't_call' 103 * structure provided in the client's t_connect primitive. 104 * 105 * This routine gets this data from the environment 106 * via putenv(3C), interprets the data and places the data 107 * in a t_call structure allocated via t_alloc. 108 * 109 * synopsis: 110 * 111 * struct t_call *nlsgetcall(fd); 112 * int fd; arg now ignored 113 * 114 * 115 * returns: Address of an allocated t_call structure 116 * or 117 * NULL for failure. (calloc failed) 118 * If calloc succeeds, non-existant 119 * env. variables or data is indicated 120 * by a negative 'len' field in the approp. 121 * netbuf structure. A length of zero in the 122 * netbuf structure is valid. 123 * 124 */ 125 126 struct t_call * 127 nlsgetcall(int fd) 128 { 129 struct t_call *call; 130 extern char *calloc(); 131 132 if (!(call = (struct t_call *) calloc(1, sizeof(struct t_call)))) 133 return((struct t_call *)0); 134 135 /* 136 * Note: space for buffers gets allocated by nlsenv on the fly 137 */ 138 139 call->addr.len = nlsenv(&call->addr, NLSADDR); 140 call->opt.len = nlsenv(&call->opt, NLSOPT); 141 call->udata.len = nlsenv(&call->udata, NLSUDATA); 142 143 return (call); 144 } 145 146 147 /* 148 * nlsprovider: Return the name of the transport provider 149 * as placed in the environment by the Network listener 150 * process. If the variable is not defined in the 151 * environment, a NULL pointer is returned. 152 * 153 * If the provider is "/dev/starlan", nlsprovider 154 * returns a pointer to the null terminated character string: 155 * "/dev/starlan" if this calling process is a child of the 156 * network listener process. 157 */ 158 159 char * 160 nlsprovider() 161 { 162 return(getenv(NLSPROVIDER)); 163 } 164 165 166 /* 167 * nlsc2addr: Convert external address to internal form. 168 * (from nlsaddr.c) 169 */ 170 171 /* 172 * asctohex(X): convert char X to integer value 173 * assumes isxdigit(X). returns integer value. 174 * Note that 'a' > 'A'. See usage in code below. 175 */ 176 177 #define asctohex(X) \ 178 ((int)(isdigit(X) ? (int)(X-'0') : (X>='a') ? (X-'a')+10 : (X-'A')+10)) 179 180 /* 181 * nlsc2addr: Given a buffer containing the hex/ascii representation 182 * of a logical address, the buffer's size and an address 183 * of a receiving buffer, char2addr converts the logical 184 * addr to internal format and returns the size of the logical 185 * address. A negative value is returned and the receiving 186 * buffers contents are undefined if: 187 * 188 * A. The receiving buffer is not large enough. (rc = -1) 189 * B. If 'charaddr' does not contain a series of octets 190 * (strlen(charaddr) must be even). (rc = -2) 191 * C. Any character in 'charaddr' is not an ASCII hex digit. 192 * (rc = -3) 193 * 194 * NOTE: that even if the internal representation of an address is 195 * an ASCII string, there is no guarantee that the output will be 196 * null terminated, thus the returned length must be used when 197 * accessing the internal address. 198 */ 199 200 201 int 202 nlsc2addr(char *addr, int maxlen, char *charaddr) 203 { 204 int len; 205 int i; 206 char c; 207 unsigned char val; 208 209 if (strlen(charaddr) & 1) 210 return(-1); 211 212 for (len = 0; ((maxlen--) && (*charaddr)); ++len) { 213 for (i = 2, val = 0; i--; ) { 214 c = *charaddr++; 215 if (!(isxdigit(c))) 216 return(-3); 217 val = (val << 4) | (unsigned char)asctohex(c); 218 } 219 220 *addr++ = (char)val; 221 } 222 223 #ifdef DEBUGMODE 224 fprintf(stderr, "nlsc2addr: returned length = %d\n", len); 225 #endif 226 227 return(*charaddr ? -2 : len); 228 } 229