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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * NAME 32 * xsetenv, xgetenv, Xgetenv - manage an alternate environment space 33 * 34 * SYNOPSIS 35 * int ret = xsetenv(file) 36 * char *x = xgetenv("FOO"); 37 * char *x = Xgetenv("FOO"); 38 * 39 * DESCRIPTION 40 * xsetenv() reads the given file into an internal buffer 41 * and sets up an alternate environment. 42 * 43 * Return values: 1 - OKAY 44 * 0 - troubles reading the file 45 * -1 - troubles opening the file 46 * 47 * xgetenv() returns the environment value from the 48 * alternate environment. 49 * 50 * Return values: (char *)0 - no value for that variable 51 * pointer - the value 52 * 53 * Xgetenv() returns the environment value from the 54 * alternate environment. 55 * 56 * Return values: "" - no value for that variable 57 * pointer - the value 58 * 59 * LIMITATIONS 60 * Assumes the environment is < 5120 bytes, as in the UNIX 61 * System environment. Assumes < 512 lines in the file. 62 * These values may be adjusted below. 63 */ 64 65 #include <sys/types.h> 66 #include "libmail.h" 67 #include <stdio.h> 68 #include <string.h> 69 #include <fcntl.h> 70 #include <ctype.h> 71 72 #include <stdlib.h> 73 #include <unistd.h> 74 75 #define MAXVARS 512 76 #define MAXENV 5120 77 78 static char **xenv = 0; 79 static char *(xenvptrs[MAXVARS]); 80 static char xbuf[MAXENV]; 81 82 static void reduce(char *); 83 84 /* 85 * set up an environment buffer 86 * and the pointers into it 87 */ 88 int 89 xsetenv(char *xfile) 90 { 91 int envctr, infd; 92 ssize_t i, nread; 93 94 /* Open the file */ 95 infd = open(xfile, O_RDONLY); 96 if (infd == -1) { 97 return (-1); 98 } 99 100 /* Read in the entire file. */ 101 nread = read(infd, xbuf, sizeof (xbuf)); 102 if (nread < 0) { 103 (void) close(infd); 104 return (0); 105 } 106 107 /* 108 * Set up pointers into the buffer. 109 * Replace \n with \0. 110 * Collapse white space around the = sign and at the 111 * beginning and end of the line. 112 */ 113 xenv = xenvptrs; 114 xenv[0] = &xbuf[0]; 115 for (i = 0, envctr = 0; i < nread; i++) { 116 if (xbuf[i] == '\n') { 117 xbuf[i] = '\0'; 118 reduce(xenv[envctr]); 119 xenv[++envctr] = &xbuf[i+1]; 120 if (envctr == MAXVARS) { 121 break; 122 } 123 } 124 } 125 126 xenv[envctr] = 0; 127 (void) close(infd); 128 return (1); 129 } 130 131 /* 132 * Let getenv() do the dirty work 133 * of looking up the variable. We 134 * do this by temporarily resetting 135 * environ to point to the local area. 136 */ 137 char * 138 xgetenv(char *env) 139 { 140 extern char **environ; 141 char *ret, **svenviron = environ; 142 143 environ = xenv; 144 ret = getenv(env); 145 environ = svenviron; 146 return (ret); 147 } 148 149 /* 150 * Let xgetenv() do the dirty work 151 * of looking up the variable. 152 */ 153 char * 154 Xgetenv(char *env) 155 { 156 char *ret = xgetenv(env); 157 return (ret ? ret : ""); 158 } 159 160 /* 161 * Remove the spaces within the environment variable. 162 * The variable can look like this: 163 * 164 * <sp1> variable <sp2> = <sp3> value <sp4> \0 165 * 166 * All spaces can be removed, except within 167 * the variable name and the value. 168 */ 169 170 static void 171 reduce(char *from) 172 { 173 char *to = from; 174 char *svfrom = from; 175 176 /* <sp1> */ 177 while (*from &&isspace((int)*from)) 178 from++; 179 180 /* variable */ 181 while (*from && (*from != '=') && !isspace((int)*from)) 182 *to++ = *from++; 183 184 /* <sp2> */ 185 while (*from && isspace((int)*from)) 186 from++; 187 188 /* = */ 189 if (*from == '=') 190 *to++ = *from++; 191 192 /* <sp3> */ 193 while (*from && isspace((int)*from)) 194 from++; 195 196 /* value */ 197 while (*from) 198 *to++ = *from++; 199 200 /* <sp4> */ 201 while ((to > svfrom) && isspace((int)to[-1])) 202 to--; 203 *to = '\0'; 204 } 205