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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28 
29 
30 #include <stdio.h>
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <fcntl.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <signal.h>
39 #include <errno.h>
40 #include <assert.h>
41 #include <pkgdev.h>
42 #include <pkginfo.h>
43 #include <pkglocs.h>
44 #include <locale.h>
45 #include <libintl.h>
46 #include <instzones_api.h>
47 #include <pkglib.h>
48 #include <install.h>
49 #include <libinst.h>
50 #include <libadm.h>
51 #include <messages.h>
52 
53 static char *localeNames[] = {
54 	"LC_CTYPE",
55 	"LC_NUMERIC",
56 	"LC_TIME",
57 	"LC_COLLATE",
58 	"LC_MESSAGES",
59 	"LC_MONETARY",
60 	"LC_ALL",
61 	"LANG",
62 	"TZ",
63 	NULL
64 };
65 
66 #define	NUM_LOCALE_TYPES	100
67 
68 static char	*envPtr[NUM_LOCALE_TYPES];
69 
70 /*
71  * extern declarations
72  */
73 
74 extern char	**environ;
75 
76 /*
77  * this is the initial and incremental allocation used to
78  * populate the environment "environ"
79  */
80 
81 #define	MALSIZ	64
82 
83 void
putparam(char * param,char * value)84 putparam(char *param, char *value)
85 {
86 	char	*pt;
87 	int	ptlen;
88 	int	i, n;
89 
90 	/*
91 	 * If the environment is NULL, allocate space for the
92 	 * character pointers.
93 	 */
94 	if (environ == NULL) {
95 		environ = (char **)calloc(MALSIZ, sizeof (char *));
96 		if (environ == NULL) {
97 			progerr(gettext(ERR_MEMORY), errno);
98 			quit(99);
99 		}
100 	}
101 
102 	/*
103 	 * If this parameter is already in place and it has a different
104 	 * value, clear the old value by freeing the memory previously
105 	 * allocated. Otherwise, we leave well-enough alone.
106 	 */
107 	n = strlen(param);
108 	for (i = 0; environ[i]; i++) {
109 		if (strncmp(environ[i], param, n) == 0 &&
110 		    (environ[i][n] == '=')) {
111 			if (strcmp((environ[i]) + n + 1, value) == 0)
112 				return;
113 			else {
114 				free(environ[i]);
115 				break;
116 			}
117 		}
118 	}
119 
120 	/* Allocate space for the new environment entry. */
121 	ptlen = (strlen(param)+strlen(value)+2)*(sizeof (char));
122 	pt = (char *)calloc(strlen(param)+strlen(value)+2, sizeof (char));
123 	if (pt == NULL) {
124 		progerr(gettext(ERR_MEMORY), errno);
125 		quit(99);
126 	}
127 
128 	/*
129 	 * Put the statement into the allocated space and point the
130 	 * environment entry at it.
131 	 */
132 	(void) snprintf(pt, ptlen, "%s=%s", param, value);
133 	if (environ[i]) {
134 		environ[i] = pt;
135 		return;
136 	}
137 
138 	/*
139 	 * With this parameter in place, if we're at the end of the
140 	 * allocated environment then allocate more space.
141 	 */
142 	environ[i++] = pt;
143 	if ((i % MALSIZ) == 0) {
144 		environ = (char **)realloc((void *)environ,
145 			(i+MALSIZ)*sizeof (char *));
146 		if (environ == NULL) {
147 			progerr(gettext(ERR_MEMORY), errno);
148 			quit(1);
149 		}
150 	}
151 
152 	/* Terminate the environment properly. */
153 	environ[i] = (char *)NULL;
154 }
155 
156 /* bugid 4279039 */
157 void
getuserlocale(void)158 getuserlocale(void)
159 {
160 	int i;
161 
162 	for (i = 0; (localeNames[i] != NULL) && (i < NUM_LOCALE_TYPES); i++) {
163 		envPtr[i] = getenv(localeNames[i]);
164 		if (envPtr[i]) {
165 			putparam(localeNames[i], envPtr[i]);
166 		}
167 	}
168 }
169 
170 /* bugid 4279039 */
171 void
putuserlocale(void)172 putuserlocale(void)
173 {
174 	int i;
175 
176 	for (i = 0; (localeNames[i] != NULL) && (i < NUM_LOCALE_TYPES); i++) {
177 		if (envPtr[i]) {
178 			putparam(localeNames[i], envPtr[i]);
179 		}
180 	}
181 }
182 
183 /*
184  * Name:	putConditionInfo
185  * Description:	put parent "condition" information to environment
186  * Arguments:	a_parentZoneName - name of the parent zone
187  *			== NULL - no name
188  *		a_parentZoneType - parent zone "type"
189  *			== NULL - no type
190  * Returns:	void
191  */
192 
193 void
putConditionInfo(char * a_parentZoneName,char * a_parentZoneType)194 putConditionInfo(char *a_parentZoneName, char *a_parentZoneType)
195 {
196 	char	*p;
197 	char	*pa;
198 	SML_TAG	*tag = SML_TAG__NULL;
199 	SML_TAG	*ntag;
200 
201 	/* entry debugging info */
202 
203 	echoDebug(DBG_PUTPARAM_PUTCONDINFO_ENTRY);
204 
205 	/*
206 	 * create tag to hold condition information:
207 	 * <environmentConditionInformation>
208 	 * <parentZone zoneName=<?> zoneType=<?>/>
209 	 * <currentZone zoneName=<?> zoneType=<?>/>
210 	 * </environmentConditionInformation>
211 	 */
212 
213 	tag = smlNewTag(TAG_COND_TOPLEVEL);
214 
215 	/*
216 	 * information about pkgadd or pkgrm environment
217 	 * <parentZone zoneName=<?> zoneType=<?>/>
218 	 */
219 
220 	/* allocate tag for parent info */
221 
222 	ntag = smlNewTag(TAG_COND_PARENT_ZONE);
223 
224 	/* parent zone name */
225 
226 	smlSetParam(ntag, TAG_COND_ZONE_NAME,
227 		a_parentZoneName ? a_parentZoneName : "");
228 
229 	/* parent zone info */
230 
231 	smlSetParam(ntag, TAG_COND_ZONE_TYPE,
232 		a_parentZoneType ? a_parentZoneType : "");
233 
234 	/* add to top level tag */
235 
236 	(void) smlAddTag(&tag, -1, ntag);
237 	free(ntag);
238 
239 	/*
240 	 * information about pkginstall or pkgremove environment
241 	 * <currentZone zoneName=<?> zoneType=<?>/>
242 	 */
243 
244 	/* allocate tag for parent info */
245 
246 	ntag = smlNewTag(TAG_COND_CURRENT_ZONE);
247 
248 	/* current zone name */
249 
250 	p = z_get_zonename();
251 	if ((p != NULL) && (*p != '\0')) {
252 		smlSetParam(ntag, TAG_COND_ZONE_NAME, p);
253 		free(p);
254 	}
255 
256 	/* current zone type */
257 
258 	smlSetParam(ntag, TAG_COND_ZONE_TYPE,
259 		z_running_in_global_zone() == B_TRUE ?
260 			TAG_VALUE_GLOBAL_ZONE : TAG_VALUE_NONGLOBAL_ZONE);
261 
262 	/* add to top level tag */
263 
264 	(void) smlAddTag(&tag, -1, ntag);
265 	free(ntag);
266 
267 	/*
268 	 * done filling in tag - convert to string and place in environment
269 	 */
270 
271 	p = smlConvertTagToString(tag);
272 
273 	/* convert all new-line characters to space */
274 
275 	for (pa = p; *pa != '\0'; pa++) {
276 		if (*pa == '\n') {
277 			*pa = ' ';
278 		}
279 	}
280 
281 	echoDebug(DBG_PUTPARAM_PUTCONDINFO_EXIT, p);
282 
283 	putparam(PKGCOND_GLOBAL_VARIABLE, p);
284 }
285