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