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