#include <libintl.h>
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
#include <errno.h>
#include <alloca.h>
#include "sgs.h"
#include "rtc.h"
#include "_crle.h"
#include "msg.h"
int
addenv(Crle_desc *crle, const char *arg, unsigned int flags)
{
Env_desc *env;
char *str;
size_t varsz, totsz = strlen(arg) + 1;
if ((str = strchr(arg, '=')) != NULL) {
Aliste idx;
varsz = (size_t)(str - arg);
for (APLIST_TRAVERSE(crle->c_env, idx, env)) {
if ((env->e_varsz == varsz) &&
(strncmp(env->e_str, arg, varsz) == 0)) {
if ((env->e_flags & RTC_ENV_CONFIG) == 0) {
(void) fprintf(stderr,
MSG_INTL(MSG_WARN_ENV),
crle->c_name, (int)varsz,
env->e_str);
return (2);
}
free((void *)env->e_str);
crle->c_strsize -= env->e_totsz;
crle->c_strsize += totsz;
if ((env->e_str = strdup(arg)) == 0) {
int err = errno;
(void) fprintf(stderr,
MSG_INTL(MSG_SYS_MALLOC),
crle->c_name, strerror(err));
return (0);
}
env->e_varsz = varsz;
env->e_totsz = totsz;
env->e_flags &= ~RTC_ENV_CONFIG;
env->e_flags |= flags;
return (1);
}
}
} else {
Aliste idx;
for (APLIST_TRAVERSE(crle->c_env, idx, env)) {
if (env->e_varsz)
continue;
if (strcmp(env->e_str, arg) == 0) {
if ((env->e_flags & RTC_ENV_CONFIG) == 0) {
(void) fprintf(stderr,
MSG_INTL(MSG_WARN_ENV),
crle->c_name, (int)totsz,
env->e_str);
return (2);
}
env->e_flags &= ~RTC_ENV_CONFIG;
env->e_flags |= flags;
return (1);
}
}
varsz = 0;
}
if (((env = malloc(sizeof (Env_desc))) == NULL) ||
((env->e_str = strdup(arg)) == NULL)) {
int err = errno;
(void) fprintf(stderr, MSG_INTL(MSG_SYS_MALLOC),
crle->c_name, strerror(err));
free(env);
return (0);
}
env->e_varsz = varsz;
env->e_totsz = totsz;
env->e_flags = flags;
if (aplist_append(&(crle->c_env), env, AL_CNT_CRLE) == NULL)
return (0);
crle->c_envnum++;
crle->c_strsize += totsz;
return (1);
}
int
addlib(Crle_desc *crle, char **lib, const char *args)
{
char *str, *arg;
char *lasts;
size_t tlen = strlen(args) + 1;
const char *colon = MSG_ORIG(MSG_STR_COLON);
str = alloca(tlen);
(void) strcpy(str, args);
arg = str;
if ((arg = strtok_r(arg, colon, &lasts)) != NULL) {
do {
size_t llen, alen = strlen(arg);
if (*lib) {
if (((str = strstr(*lib, arg)) != NULL) &&
(((str == *lib) ||
(*(str - 1) == *colon)) &&
(str += alen) &&
((*str == '\0') || (*str == *colon))))
continue;
llen = strlen(*lib);
tlen = llen + 1;
} else {
llen = 0;
tlen = 0;
}
alen += 1;
tlen += alen;
if ((str = realloc((void *)*lib, tlen)) == 0) {
int err = errno;
(void) fprintf(stderr, MSG_INTL(MSG_SYS_MALLOC),
crle->c_name, strerror(err));
return (1);
}
if (llen == 0)
(void) strcpy(str, arg);
else {
(void) sprintf(&str[llen],
MSG_ORIG(MSG_FMT_COLON), arg);
}
*lib = str;
crle->c_strsize += alen;
} while ((arg = strtok_r(NULL, colon, &lasts)) != NULL);
}
return (0);
}
int
dlflags(Crle_desc *crle, const char *arg)
{
int _flags;
char *tok, *_arg;
char *lasts;
const char *separate = MSG_ORIG(MSG_MOD_SEPARATE);
if ((_flags = (int)strtol(arg, (char **)NULL, 0)) != 0)
return (_flags);
if ((_arg = malloc(strlen(arg) + 1)) == 0)
return (0);
(void) strcpy(_arg, arg);
if ((tok = strtok_r(_arg, separate, &lasts)) != NULL) {
do {
if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_RELATIVE)) == 0)
_flags |= RTLD_REL_RELATIVE;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_EXEC)) == 0)
_flags |= RTLD_REL_EXEC;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_DEPENDS)) == 0)
_flags |= RTLD_REL_DEPENDS;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_PRELOAD)) == 0)
_flags |= RTLD_REL_PRELOAD;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_SELF)) == 0)
_flags |= RTLD_REL_SELF;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_WEAK)) == 0)
_flags |= RTLD_REL_WEAK;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_ALL)) == 0)
_flags |= RTLD_REL_ALL;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_MEMORY)) == 0)
_flags |= RTLD_MEMORY;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_STRIP)) == 0)
_flags |= RTLD_STRIP;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_NOHEAP)) == 0)
_flags |= RTLD_NOHEAP;
else if (strcmp(tok, MSG_ORIG(MSG_MOD_REL_CONFGEN)) == 0)
_flags |= RTLD_CONFGEN;
else {
(void) fprintf(stderr, MSG_INTL(MSG_ARG_FLAGS),
crle->c_name, tok);
free(_arg);
return (0);
}
} while ((tok = strtok_r(NULL, separate, &lasts)) != NULL);
}
if (_flags == 0)
(void) fprintf(stderr, MSG_INTL(MSG_ARG_FLAGS),
crle->c_name, arg);
free(_arg);
return (_flags);
}
const char *
_crle_msg(Msg mid)
{
return (gettext(MSG_ORIG(mid)));
}