putparam.c revision 9781:ccf49524d5dc
1292932Sdim/*
2292932Sdim * CDDL HEADER START
3292932Sdim *
4292932Sdim * The contents of this file are subject to the terms of the
5292932Sdim * Common Development and Distribution License (the "License").
6292932Sdim * You may not use this file except in compliance with the License.
7292932Sdim *
8292932Sdim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9292932Sdim * or http://www.opensolaris.org/os/licensing.
10292932Sdim * See the License for the specific language governing permissions
11292932Sdim * and limitations under the License.
12292932Sdim *
13292932Sdim * When distributing Covered Code, include this CDDL HEADER in each
14292932Sdim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15292932Sdim * If applicable, add the following below this CDDL HEADER, with the
16292932Sdim * fields enclosed by brackets "[]" replaced with your own identifying
17292932Sdim * information: Portions Copyright [yyyy] [name of copyright owner]
18292932Sdim *
19292932Sdim * CDDL HEADER END
20292932Sdim */
21292932Sdim
22292932Sdim/*
23292932Sdim * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24292932Sdim * Use is subject to license terms.
25292932Sdim */
26292932Sdim
27292932Sdim/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28292932Sdim/* All Rights Reserved */
29292932Sdim
30292932Sdim
31292932Sdim#include <stdio.h>
32292932Sdim#include <limits.h>
33292932Sdim#include <stdlib.h>
34292932Sdim#include <unistd.h>
35292932Sdim#include <string.h>
36292932Sdim#include <fcntl.h>
37292932Sdim#include <sys/types.h>
38292932Sdim#include <sys/stat.h>
39292932Sdim#include <signal.h>
40292932Sdim#include <errno.h>
41292932Sdim#include <assert.h>
42292932Sdim#include <pkgdev.h>
43292932Sdim#include <pkginfo.h>
44292932Sdim#include <pkglocs.h>
45292932Sdim#include <locale.h>
46292932Sdim#include <libintl.h>
47292932Sdim#include <instzones_api.h>
48292932Sdim#include <pkglib.h>
49292932Sdim#include <install.h>
50292932Sdim#include <libinst.h>
51292932Sdim#include <libadm.h>
52292932Sdim#include <messages.h>
53292932Sdim
54292932Sdimstatic char *localeNames[] = {
55292932Sdim	"LC_CTYPE",
56292932Sdim	"LC_NUMERIC",
57292932Sdim	"LC_TIME",
58292932Sdim	"LC_COLLATE",
59292932Sdim	"LC_MESSAGES",
60292932Sdim	"LC_MONETARY",
61292932Sdim	"LC_ALL",
62292932Sdim	"LANG",
63292932Sdim	"TZ",
64292932Sdim	NULL
65292932Sdim};
66292932Sdim
67292932Sdim#define	NUM_LOCALE_TYPES	100
68292932Sdim
69292932Sdimstatic char	*envPtr[NUM_LOCALE_TYPES];
70292932Sdim
71292932Sdim/*
72292932Sdim * extern declarations
73292932Sdim */
74292932Sdim
75292932Sdimextern char	**environ;
76292932Sdim
77292932Sdim/*
78292932Sdim * this is the initial and incremental allocation used to
79292932Sdim * populate the environment "environ"
80292932Sdim */
81292932Sdim
82292932Sdim#define	MALSIZ	64
83292932Sdim
84292932Sdimvoid
85292932Sdimputparam(char *param, char *value)
86292932Sdim{
87292932Sdim	char	*pt;
88292932Sdim	int	ptlen;
89292932Sdim	int	i, n;
90292932Sdim
91292932Sdim	/*
92292932Sdim	 * If the environment is NULL, allocate space for the
93292932Sdim	 * character pointers.
94292932Sdim	 */
95292932Sdim	if (environ == NULL) {
96292932Sdim		environ = (char **)calloc(MALSIZ, sizeof (char *));
97292932Sdim		if (environ == NULL) {
98292932Sdim			progerr(gettext(ERR_MEMORY), errno);
99292932Sdim			quit(99);
100292932Sdim		}
101292932Sdim	}
102292932Sdim
103292932Sdim	/*
104292932Sdim	 * If this parameter is already in place and it has a different
105292932Sdim	 * value, clear the old value by freeing the memory previously
106292932Sdim	 * allocated. Otherwise, we leave well-enough alone.
107292932Sdim	 */
108292932Sdim	n = strlen(param);
109292932Sdim	for (i = 0; environ[i]; i++) {
110292932Sdim		if (strncmp(environ[i], param, n) == 0 &&
111292932Sdim		    (environ[i][n] == '=')) {
112292932Sdim			if (strcmp((environ[i]) + n + 1, value) == 0)
113292932Sdim				return;
114292932Sdim			else {
115292932Sdim				free(environ[i]);
116292932Sdim				break;
117292932Sdim			}
118292932Sdim		}
119292932Sdim	}
120292932Sdim
121292932Sdim	/* Allocate space for the new environment entry. */
122292932Sdim	ptlen = (strlen(param)+strlen(value)+2)*(sizeof (char));
123292932Sdim	pt = (char *)calloc(strlen(param)+strlen(value)+2, sizeof (char));
124292932Sdim	if (pt == NULL) {
125292932Sdim		progerr(gettext(ERR_MEMORY), errno);
126292932Sdim		quit(99);
127292932Sdim	}
128292932Sdim
129292932Sdim	/*
130292932Sdim	 * Put the statement into the allocated space and point the
131292932Sdim	 * environment entry at it.
132292932Sdim	 */
133292932Sdim	(void) snprintf(pt, ptlen, "%s=%s", param, value);
134292932Sdim	if (environ[i]) {
135292932Sdim		environ[i] = pt;
136292932Sdim		return;
137292932Sdim	}
138292932Sdim
139292932Sdim	/*
140292932Sdim	 * With this parameter in place, if we're at the end of the
141292932Sdim	 * allocated environment then allocate more space.
142292932Sdim	 */
143292932Sdim	environ[i++] = pt;
144292932Sdim	if ((i % MALSIZ) == 0) {
145292932Sdim		environ = (char **)realloc((void *)environ,
146292932Sdim			(i+MALSIZ)*sizeof (char *));
147292932Sdim		if (environ == NULL) {
148292932Sdim			progerr(gettext(ERR_MEMORY), errno);
149292932Sdim			quit(1);
150292932Sdim		}
151292932Sdim	}
152292932Sdim
153292932Sdim	/* Terminate the environment properly. */
154292932Sdim	environ[i] = (char *)NULL;
155292932Sdim}
156292932Sdim
157292932Sdim/* bugid 4279039 */
158292932Sdimvoid
159292932Sdimgetuserlocale(void)
160292932Sdim{
161292932Sdim	int i;
162292932Sdim
163292932Sdim	for (i = 0; (localeNames[i] != NULL) && (i < NUM_LOCALE_TYPES); i++) {
164292932Sdim		envPtr[i] = getenv(localeNames[i]);
165292932Sdim		if (envPtr[i]) {
166292932Sdim			putparam(localeNames[i], envPtr[i]);
167292932Sdim		}
168292932Sdim	}
169292932Sdim}
170292932Sdim
171292932Sdim/* bugid 4279039 */
172292932Sdimvoid
173292932Sdimputuserlocale(void)
174292932Sdim{
175292932Sdim	int i;
176292932Sdim
177292932Sdim	for (i = 0; (localeNames[i] != NULL) && (i < NUM_LOCALE_TYPES); i++) {
178292932Sdim		if (envPtr[i]) {
179292932Sdim			putparam(localeNames[i], envPtr[i]);
180292932Sdim		}
181292932Sdim	}
182292932Sdim}
183292932Sdim
184292932Sdim/*
185292932Sdim * Name:	putConditionInfo
186292932Sdim * Description:	put parent "condition" information to environment
187292932Sdim * Arguments:	a_parentZoneName - name of the parent zone
188292932Sdim *			== NULL - no name
189292932Sdim *		a_parentZoneType - parent zone "type"
190292932Sdim *			== NULL - no type
191292932Sdim * Returns:	void
192292932Sdim */
193292932Sdim
194292932Sdimvoid
195292932SdimputConditionInfo(char *a_parentZoneName, char *a_parentZoneType)
196292932Sdim{
197292932Sdim	char	**pp;
198292932Sdim	char	*p;
199292932Sdim	char	*pa;
200292932Sdim	SML_TAG	*tag = SML_TAG__NULL;
201292932Sdim	SML_TAG	*ntag;
202292932Sdim
203292932Sdim	/* entry debugging info */
204292932Sdim
205292932Sdim	echoDebug(DBG_PUTPARAM_PUTCONDINFO_ENTRY);
206292932Sdim
207292932Sdim	/*
208292932Sdim	 * create tag to hold condition information:
209292932Sdim	 * <environmentConditionInformation>
210292932Sdim	 * <parentZone zoneName=<?> zoneType=<?>/>
211292932Sdim	 * <currentZone zoneName=<?> zoneType=<?>/>
212292932Sdim	 * <inheritedFileSystem fileSystemName=<?>/>
213292932Sdim	 * </environmentConditionInformation>
214292932Sdim	 */
215292932Sdim
216292932Sdim	tag = smlNewTag(TAG_COND_TOPLEVEL);
217292932Sdim
218292932Sdim	/*
219292932Sdim	 * information about pkgadd or pkgrm environment
220292932Sdim	 * <parentZone zoneName=<?> zoneType=<?>/>
221292932Sdim	 */
222292932Sdim
223292932Sdim	/* allocate tag for parent info */
224292932Sdim
225292932Sdim	ntag = smlNewTag(TAG_COND_PARENT_ZONE);
226292932Sdim
227292932Sdim	/* parent zone name */
228292932Sdim
229292932Sdim	smlSetParam(ntag, TAG_COND_ZONE_NAME,
230292932Sdim		a_parentZoneName ? a_parentZoneName : "");
231292932Sdim
232292932Sdim	/* parent zone info */
233292932Sdim
234292932Sdim	smlSetParam(ntag, TAG_COND_ZONE_TYPE,
235292932Sdim		a_parentZoneType ? a_parentZoneType : "");
236292932Sdim
237292932Sdim	/* add to top level tag */
238292932Sdim
239292932Sdim	(void) smlAddTag(&tag, -1, ntag);
240292932Sdim	free(ntag);
241292932Sdim
242292932Sdim	/*
243292932Sdim	 * information about pkginstall or pkgremove environment
244292932Sdim	 * <currentZone zoneName=<?> zoneType=<?>/>
245292932Sdim	 */
246292932Sdim
247292932Sdim	/* allocate tag for parent info */
248292932Sdim
249292932Sdim	ntag = smlNewTag(TAG_COND_CURRENT_ZONE);
250292932Sdim
251292932Sdim	/* current zone name */
252292932Sdim
253292932Sdim	p = z_get_zonename();
254292932Sdim	if ((p != NULL) && (*p != '\0')) {
255292932Sdim		smlSetParam(ntag, TAG_COND_ZONE_NAME, p);
256292932Sdim		free(p);
257292932Sdim	}
258292932Sdim
259292932Sdim	/* current zone type */
260292932Sdim
261292932Sdim	smlSetParam(ntag, TAG_COND_ZONE_TYPE,
262292932Sdim		z_running_in_global_zone() == B_TRUE ?
263292932Sdim			TAG_VALUE_GLOBAL_ZONE : TAG_VALUE_NONGLOBAL_ZONE);
264292932Sdim
265292932Sdim	/* add to top level tag */
266292932Sdim
267292932Sdim	(void) smlAddTag(&tag, -1, ntag);
268292932Sdim	free(ntag);
269292932Sdim
270292932Sdim	/*
271292932Sdim	 * describe any inherited file systems:
272292932Sdim	 * <inheritedFileSystem fileSystemName=<?>/>
273292932Sdim	 */
274292932Sdim
275292932Sdim	pp = z_get_inherited_file_systems();
276292932Sdim	if (pp != (char **)NULL) {
277292932Sdim		int n;
278292932Sdim		for (n = 0; pp[n] != (char *)NULL; n++) {
279292932Sdim			/* allocate tag for inherited file system info */
280292932Sdim
281292932Sdim			ntag = smlNewTag(TAG_COND_INHERITED_FS);
282292932Sdim
283292932Sdim			/* inherited file system */
284292932Sdim
285292932Sdim			smlSetParam(ntag, TAG_COND_FS_NAME, pp[n]);
286292932Sdim
287292932Sdim			/* add to top level tag */
288292932Sdim
289292932Sdim			(void) smlAddTag(&tag, -1, ntag);
290292932Sdim			free(ntag);
291292932Sdim		}
292292932Sdim	}
293292932Sdim
294292932Sdim	/*
295292932Sdim	 * done filling in tag - convert to string and place in environment
296292932Sdim	 */
297292932Sdim
298292932Sdim	p = smlConvertTagToString(tag);
299292932Sdim
300292932Sdim	/* convert all new-line characters to space */
301292932Sdim
302292932Sdim	for (pa = p; *pa != '\0'; pa++) {
303292932Sdim		if (*pa == '\n') {
304292932Sdim			*pa = ' ';
305292932Sdim		}
306292932Sdim	}
307292932Sdim
308292932Sdim	echoDebug(DBG_PUTPARAM_PUTCONDINFO_EXIT, p);
309292932Sdim
310292932Sdim	putparam(PKGCOND_GLOBAL_VARIABLE, p);
311292932Sdim}
312292932Sdim