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