config.c revision 1618:8c9a4f31d225
1254721Semaste/*
2254721Semaste * CDDL HEADER START
3254721Semaste *
4254721Semaste * The contents of this file are subject to the terms of the
5254721Semaste * Common Development and Distribution License (the "License").
6254721Semaste * You may not use this file except in compliance with the License.
7254721Semaste *
8254721Semaste * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9254721Semaste * or http://www.opensolaris.org/os/licensing.
10254721Semaste * See the License for the specific language governing permissions
11254721Semaste * and limitations under the License.
12254721Semaste *
13254721Semaste * When distributing Covered Code, include this CDDL HEADER in each
14254721Semaste * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15263363Semaste * If applicable, add the following below this CDDL HEADER, with the
16254721Semaste * fields enclosed by brackets "[]" replaced with your own identifying
17254721Semaste * information: Portions Copyright [yyyy] [name of copyright owner]
18254721Semaste *
19254721Semaste * CDDL HEADER END
20254721Semaste */
21254721Semaste
22254721Semaste/*
23263363Semaste * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24254721Semaste * Use is subject to license terms.
25254721Semaste */
26254721Semaste#pragma ident	"%Z%%M%	%I%	%E% SMI"
27254721Semaste
28254721Semaste#include	<stdlib.h>
29254721Semaste#include	<sys/types.h>
30254721Semaste#include	<string.h>
31254721Semaste#include	"rtc.h"
32254721Semaste#include	"_conv.h"
33254721Semaste#include	"config_msg.h"
34254721Semaste
35254721Semaste#define	FEATSZ	MSG_GBL_OSQBRKT_SIZE + \
36254721Semaste		MSG_CONF_EDLIBPATH_SIZE + \
37254721Semaste		MSG_CONF_ESLIBPATH_SIZE + \
38254721Semaste		MSG_CONF_ADLIBPATH_SIZE + \
39254721Semaste		MSG_CONF_ASLIBPATH_SIZE + \
40254721Semaste		MSG_CONF_DIRCFG_SIZE + \
41254721Semaste		MSG_CONF_OBJALT_SIZE + \
42254721Semaste		MSG_CONF_MEMRESV_SIZE + \
43254721Semaste		MSG_CONF_ENVS_SIZE + \
44254721Semaste		MSG_CONF_FLTR_SIZE + \
45263363Semaste		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
46254721Semaste
47254721Semaste/*
48254721Semaste * String conversion routine for configuration file information.
49254721Semaste */
50254721Semasteconst char *
51254721Semasteconv_config_feat(int features)
52254721Semaste{
53254721Semaste	static	char	string[FEATSZ];
54254721Semaste	static Val_desc	vda[] = {
55254721Semaste		{ CONF_EDLIBPATH,	MSG_ORIG(MSG_CONF_EDLIBPATH) },
56254721Semaste		{ CONF_ESLIBPATH,	MSG_ORIG(MSG_CONF_ESLIBPATH) },
57254721Semaste		{ CONF_ADLIBPATH,	MSG_ORIG(MSG_CONF_ADLIBPATH) },
58254721Semaste		{ CONF_ASLIBPATH,	MSG_ORIG(MSG_CONF_ASLIBPATH) },
59254721Semaste		{ CONF_DIRCFG,		MSG_ORIG(MSG_CONF_DIRCFG) },
60254721Semaste		{ CONF_OBJALT,		MSG_ORIG(MSG_CONF_OBJALT) },
61254721Semaste		{ CONF_MEMRESV,		MSG_ORIG(MSG_CONF_MEMRESV) },
62254721Semaste		{ CONF_ENVS,		MSG_ORIG(MSG_CONF_ENVS) },
63254721Semaste		{ CONF_FLTR,		MSG_ORIG(MSG_CONF_FLTR) },
64254721Semaste		{ 0,			0 }
65254721Semaste	};
66254721Semaste
67254721Semaste	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FEATSZ);
68254721Semaste	if (conv_expn_field(string, FEATSZ, vda, features,
69254721Semaste	    features, 0, 0))
70254721Semaste		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FEATSZ);
71254721Semaste
72254721Semaste	return ((const char *)string);
73254721Semaste}
74254721Semaste
75254721Semaste#define	FLAGSZ	MSG_GBL_OSQBRKT_SIZE + \
76254721Semaste		MSG_CONF_DIRENT_SIZE + \
77254721Semaste		MSG_CONF_ALLENTS_SIZE + \
78254721Semaste		MSG_CONF_NOEXIST_SIZE + \
79254721Semaste		MSG_CONF_EXEC_SIZE + \
80254721Semaste		MSG_CONF_ALTER_SIZE + \
81254721Semaste		MSG_CONF_OPTIONAL_SIZE + \
82254721Semaste		MSG_CONF_DUMP_SIZE + \
83254721Semaste		MSG_CONF_REALPATH_SIZE + \
84254721Semaste		MSG_CONF_NOALTER_SIZE + \
85254721Semaste		MSG_CONF_GROUP_SIZE + \
86254721Semaste		MSG_CONF_APP_SIZE + \
87263363Semaste		MSG_CONF_CMDLINE_SIZE + \
88263363Semaste		MSG_CONF_FILTER_SIZE + \
89263363Semaste		MSG_CONF_FILTEE_SIZE + \
90263363Semaste		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
91263363Semaste
92263363Semaste/*
93263363Semaste * String conversion routine for object flags.
94263363Semaste */
95263363Semasteconst char *
96263363Semasteconv_config_obj(ushort_t flags)
97263363Semaste{
98263363Semaste	static char	string[FLAGSZ];
99263363Semaste	static Val_desc vda[] = {
100263363Semaste		{ RTC_OBJ_DIRENT,	MSG_ORIG(MSG_CONF_DIRENT) },
101263363Semaste		{ RTC_OBJ_ALLENTS,	MSG_ORIG(MSG_CONF_ALLENTS) },
102263363Semaste		{ RTC_OBJ_NOEXIST,	MSG_ORIG(MSG_CONF_NOEXIST) },
103263363Semaste		{ RTC_OBJ_EXEC,		MSG_ORIG(MSG_CONF_EXEC) },
104254721Semaste		{ RTC_OBJ_ALTER,	MSG_ORIG(MSG_CONF_ALTER) },
105254721Semaste		{ RTC_OBJ_DUMP,		MSG_ORIG(MSG_CONF_DUMP) },
106254721Semaste		{ RTC_OBJ_NOALTER,	MSG_ORIG(MSG_CONF_NOALTER) },
107254721Semaste		{ RTC_OBJ_REALPTH,	MSG_ORIG(MSG_CONF_REALPATH) },
108254721Semaste		{ RTC_OBJ_GROUP,	MSG_ORIG(MSG_CONF_GROUP) },
109254721Semaste		{ RTC_OBJ_APP,		MSG_ORIG(MSG_CONF_APP) },
110254721Semaste		{ RTC_OBJ_CMDLINE,	MSG_ORIG(MSG_CONF_CMDLINE) },
111254721Semaste		{ RTC_OBJ_FILTER,	MSG_ORIG(MSG_CONF_FILTER) },
112254721Semaste		{ RTC_OBJ_FILTEE,	MSG_ORIG(MSG_CONF_FILTEE) },
113254721Semaste		{ 0,			0 }
114254721Semaste	};
115254721Semaste	ushort_t	_flags = flags;
116254721Semaste
117254721Semaste	if ((flags == 0) || (flags == RTC_OBJ_OPTINAL))
118254721Semaste		return (MSG_ORIG(MSG_GBL_NULL));
119254721Semaste
120254721Semaste	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FLAGSZ);
121254721Semaste
122254721Semaste	/*
123254721Semaste	 * Print an alternative-optional object simply as optional.
124	 */
125	if ((flags & (RTC_OBJ_ALTER | RTC_OBJ_OPTINAL)) ==
126	    (RTC_OBJ_ALTER | RTC_OBJ_OPTINAL)) {
127		if (strlcat(string, MSG_ORIG(MSG_CONF_OPTIONAL),
128		    FLAGSZ) >= FLAGSZ)
129			return (conv_invalid_val(string, FLAGSZ, flags, 0));
130		flags = _flags &= ~(RTC_OBJ_ALTER | RTC_OBJ_OPTINAL);
131	}
132	flags = _flags &= ~RTC_OBJ_OPTINAL;
133
134	if (conv_expn_field(string, FLAGSZ, vda, flags, _flags, 0, 0))
135		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FLAGSZ);
136
137	return ((const char *)string);
138}
139
140/*
141 * Determine whether and old pathname exists within a search path string,
142 * without a new pathname, i.e., does the search path string contain "/usr/lib"
143 * but not "/lib".  If so, add the new pathname before the old pathname.  For
144 * example, convert:
145 *
146 *	/local/lib:/opt/sfw/lib:/usr/lib
147 * to:
148 *	/local/lib:/opt/sfw/lib:/lib:/usr/lib
149 */
150const char *
151conv_config_upm(const char *str, const char *old, const char *new,
152    size_t newlen)
153{
154	const char	*curstr, *ptr;
155	const char	*curold = 0, *curnew = 0;
156	const char	*ptrold = old, * ptrnew = new;
157	int		chkold = 1, chknew = 1;
158
159	for (curstr = ptr = str; *ptr; ptr++) {
160		if (*ptr == ':') {
161			/*
162			 * We've come to the end of a token within the string.
163			 */
164			if ((uintptr_t)ptr - (uintptr_t)curstr) {
165				/*
166				 * If the old or new string checking is still
167				 * enabled, we've found a match.
168				 */
169				if (chkold)
170					curold = curstr;
171				if (chknew)
172					curnew = curstr;
173			}
174			curstr = (char *)(ptr + 1);
175
176			/*
177			 * If an old or new string hasn't yet been matched,
178			 * re-enable the checking for either.
179			 */
180			if (curold == 0) {
181				ptrold = old;
182				chkold = 1;
183			}
184			if (curnew == 0) {
185				ptrnew = new;
186				chknew = 1;
187			}
188			continue;
189		}
190
191		/*
192		 * Determine if the current token matches the old or new string.
193		 * If not, disable the checking for each string.
194		 */
195		if (chkold && (*ptr != *ptrold++))
196			chkold = 0;
197		if (chknew && (*ptr != *ptrnew++))
198			chknew = 0;
199	}
200
201	/*
202	 * We've come to the end of the string, if the old or new string
203	 * checking is still enabled, we've found a match.
204	 */
205	if ((uintptr_t)ptr - (uintptr_t)curstr) {
206		if (chkold)
207			curold = curstr;
208		if (chknew)
209			curnew = curstr;
210	}
211
212	/*
213	 * If an old string hasn't been found, or it has and a new string has
214	 * been found, return the original string.
215	 */
216	if ((curold == 0) || curnew)
217		return (str);
218	else {
219		char	*newstr;
220		size_t	len;
221
222		/*
223		 * Allocate a new string, enlarged to accommodate the new string
224		 * that will be inserted, and an associated separator.
225		 */
226		if ((curstr = malloc(newlen + 2 +
227		    (uintptr_t)ptr - (uintptr_t)str)) == 0)
228			return (str);
229
230		newstr = (char *)curstr;
231		for (len = (uintptr_t)curold - (uintptr_t)str; len; len--)
232			*(newstr++) = *(str++);		/* copy up to */
233							/*    insertion point */
234		for (len = newlen; len; len--)
235			*(newstr++) = *(new++);		/* add new string and */
236		*(newstr++) = ':';			/*    separator */
237		for (len = (uintptr_t)ptr - (uintptr_t)str; len; len--)
238			*(newstr++) = *(str++);		/* add remaining */
239		*(newstr++) = '\0';			/*	string */
240
241		return (curstr);
242	}
243}
244