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