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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
41 * Add an environment string. A list of environment variable descriptors is
42 * maintained so that duplicate definitions can be caught, the first one wins.
45 addenv(Crle_desc
*crle
, const char *arg
, unsigned int flags
)
49 size_t varsz
, totsz
= strlen(arg
) + 1;
52 * Determine "=" location so as to separated the variable name from
55 if ((str
= strchr(arg
, '=')) != NULL
) {
58 varsz
= (size_t)(str
- arg
);
61 * Traverse any existing environment variables to see if we've
64 for (APLIST_TRAVERSE(crle
->c_env
, idx
, env
)) {
65 if ((env
->e_varsz
== varsz
) &&
66 (strncmp(env
->e_str
, arg
, varsz
) == 0)) {
68 * If the user has already specified this string
69 * given them a warning, and ignore the new one.
71 if ((env
->e_flags
& RTC_ENV_CONFIG
) == 0) {
72 (void) fprintf(stderr
,
73 MSG_INTL(MSG_WARN_ENV
),
74 crle
->c_name
, (int)varsz
,
80 * Otherwise the original string must have been
81 * retrieved from a config file. In this case
82 * allow the user to override it.
84 free((void *)env
->e_str
);
85 crle
->c_strsize
-= env
->e_totsz
;
86 crle
->c_strsize
+= totsz
;
88 if ((env
->e_str
= strdup(arg
)) == 0) {
90 (void) fprintf(stderr
,
91 MSG_INTL(MSG_SYS_MALLOC
),
92 crle
->c_name
, strerror(err
));
97 env
->e_flags
&= ~RTC_ENV_CONFIG
;
98 env
->e_flags
|= flags
;
107 * Although this is just a plain environment definition (no "=")
108 * and probably has no effect on ld.so.1 anyway, we might as
109 * well make sure we're not duplicating the same string.
111 for (APLIST_TRAVERSE(crle
->c_env
, idx
, env
)) {
114 if (strcmp(env
->e_str
, arg
) == 0) {
115 if ((env
->e_flags
& RTC_ENV_CONFIG
) == 0) {
116 (void) fprintf(stderr
,
117 MSG_INTL(MSG_WARN_ENV
),
118 crle
->c_name
, (int)totsz
,
122 env
->e_flags
&= ~RTC_ENV_CONFIG
;
123 env
->e_flags
|= flags
;
132 * Allocate a new environment descriptor.
134 if (((env
= malloc(sizeof (Env_desc
))) == 0) ||
135 ((env
->e_str
= strdup(arg
)) == 0)) {
137 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_MALLOC
),
138 crle
->c_name
, strerror(err
));
141 env
->e_varsz
= varsz
;
142 env
->e_totsz
= totsz
;
143 env
->e_flags
= flags
;
145 if (aplist_append(&(crle
->c_env
), env
, AL_CNT_CRLE
) == NULL
)
149 * Update the number of environment variables found, and the string
153 crle
->c_strsize
+= totsz
;
159 * Add a library path. Multiple library paths are concatenated together into a
160 * colon separated string suitable for runtime processing. These colon
161 * separated strings can also be passed in as arguments to addlib(), e.g.,
162 * -l /usr/lib:/usr/local/lib. This is enabled to make update easier.
165 addlib(Crle_desc
*crle
, char **lib
, const char *args
)
169 size_t tlen
= strlen(args
) + 1;
170 const char *colon
= MSG_ORIG(MSG_STR_COLON
);
173 * Parse the argument for any ":" separated elements.
176 (void) strcpy(str
, args
);
179 if ((arg
= strtok_r(arg
, colon
, &lasts
)) != NULL
) {
181 size_t llen
, alen
= strlen(arg
);
185 * Determine whether this argument exists in the
186 * existing string buffer.
188 if (((str
= strstr(*lib
, arg
)) != NULL
) &&
190 (*(str
- 1) == *colon
)) &&
192 ((*str
== '\0') || (*str
== *colon
))))
199 * This is the first argument to be added.
206 * This is a new string, so add it to the buffer. If
207 * this is the first occurrence of a string the size is
208 * simply the size of the string + a trailing null.
209 * Otherwise the size is the old string + ":" + the
210 * size of the new string + a trailing null.
214 if ((str
= realloc((void *)*lib
, tlen
)) == 0) {
216 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_MALLOC
),
217 crle
->c_name
, strerror(err
));
221 (void) strcpy(str
, arg
);
224 (void) sprintf(&str
[llen
],
225 MSG_ORIG(MSG_FMT_COLON
), arg
);
228 crle
->c_strsize
+= alen
;
230 } while ((arg
= strtok_r(NULL
, colon
, &lasts
)) != NULL
);
238 * -f option expansion. Interpret its argument as a numeric or symbolic
239 * representation of the dldump(3dl) flags.
242 dlflags(Crle_desc
*crle
, const char *arg
)
247 const char *separate
= MSG_ORIG(MSG_MOD_SEPARATE
);
250 * Scan the argument looking for allowable tokens. First determine if
251 * the string is numeric, otherwise try and parse any known flags.
253 if ((_flags
= (int)strtol(arg
, (char **)NULL
, 0)) != 0)
256 if ((_arg
= malloc(strlen(arg
) + 1)) == 0)
258 (void) strcpy(_arg
, arg
);
260 if ((tok
= strtok_r(_arg
, separate
, &lasts
)) != NULL
) {
263 if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_RELATIVE
)) == 0)
264 _flags
|= RTLD_REL_RELATIVE
;
265 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_EXEC
)) == 0)
266 _flags
|= RTLD_REL_EXEC
;
267 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_DEPENDS
)) == 0)
268 _flags
|= RTLD_REL_DEPENDS
;
269 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_PRELOAD
)) == 0)
270 _flags
|= RTLD_REL_PRELOAD
;
271 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_SELF
)) == 0)
272 _flags
|= RTLD_REL_SELF
;
273 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_WEAK
)) == 0)
274 _flags
|= RTLD_REL_WEAK
;
275 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_ALL
)) == 0)
276 _flags
|= RTLD_REL_ALL
;
277 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_MEMORY
)) == 0)
278 _flags
|= RTLD_MEMORY
;
279 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_STRIP
)) == 0)
280 _flags
|= RTLD_STRIP
;
281 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_NOHEAP
)) == 0)
282 _flags
|= RTLD_NOHEAP
;
283 else if (strcmp(tok
, MSG_ORIG(MSG_MOD_REL_CONFGEN
)) == 0)
284 _flags
|= RTLD_CONFGEN
;
286 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_FLAGS
),
291 } while ((tok
= strtok_r(NULL
, separate
, &lasts
)) != NULL
);
295 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_FLAGS
),
303 * Internationalization interface for sgsmsg(1l) use.
308 return (gettext(MSG_ORIG(mid
)));