File environment_variable.c¶
File List > base > environment_variable.c
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* environment_variable.c : Functions for manipulating the environment variable
*/
#ident "$Id$"
#include "config.h"
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include "porting.h"
#include "error_code.h"
#include "environment_variable.h"
// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"
/* available root directory symbols; NULL terminated array */
static const char envvar_Prefix_name[] = "CUBRID";
static const char *envvar_Prefix = NULL;
static const char *envvar_Root = NULL;
#define _ENVVAR_MAX_LENGTH 255
typedef enum
{
ENV_INVALID_DIR,
ENV_DONT_EXISTS_ROOT,
ENV_MUST_ABS_PATH,
ENV_TOO_LONG
} ENV_ERR_MSG;
static const char *env_msg[] = {
"The directory in $%s is invalid. (%s)\n",
"The root directory environment variable $%s is not set.\n",
"The $%s should be an absolute path. (%s)\n",
"The $%s is too long. (%s)\n"
};
static void
envvar_check_environment (void)
{
#if defined(WINDOWS)
return;
#else
const char *cubrid_tmp = envvar_get ("TMP");
if (cubrid_tmp)
{
char name[_ENVVAR_MAX_LENGTH];
size_t len = strlen (cubrid_tmp);
size_t limit = 108 - 12;
/* 108 = sizeof (((struct sockaddr_un *) 0)->sun_path) */
/* 12 = ("CUBRID65384" + 1) */
envvar_name (name, _ENVVAR_MAX_LENGTH, "TMP");
if (!IS_ABS_PATH (cubrid_tmp))
{
fprintf (stderr, env_msg[ENV_MUST_ABS_PATH], name, cubrid_tmp);
fflush (stderr);
exit (1);
}
if (len > limit)
{
fprintf (stderr, env_msg[ENV_TOO_LONG], name, cubrid_tmp);
fflush (stderr);
exit (1);
}
}
#endif
}
/*
* envvar_prefix - find a recognized prefix symbol
* return: prefix symbol
*/
const char *
envvar_prefix (void)
{
if (!envvar_Prefix)
{
envvar_Root = getenv (envvar_Prefix_name);
if (envvar_Root != NULL)
{
#if !defined (WINDOWS)
if (access (envvar_Root, F_OK) != 0)
{
fprintf (stderr, env_msg[ENV_INVALID_DIR], envvar_Prefix_name, envvar_Root);
fflush (stderr);
exit (1);
}
#endif
envvar_Prefix = envvar_Prefix_name;
}
else
{
fprintf (stderr, env_msg[ENV_DONT_EXISTS_ROOT], envvar_Prefix_name);
fflush (stderr);
exit (1);
}
envvar_check_environment ();
}
return envvar_Prefix;
}
/*
* envvar_root - get value of the root directory environment variable
* return: root directory
*/
const char *
envvar_root (void)
{
if (envvar_Root == NULL)
{
envvar_prefix ();
}
return envvar_Root;
}
/*
* envvar_name - add the prefix symbol to an environment variable name
* return: prefixed name
* buf(out): string buffer to store the prefixed name
* size(out): size of the buffer
* name(in): an environment variable name
*/
const char *
envvar_name (char *buf, size_t size, const char *name)
{
const char *prefix;
char *pname;
pname = buf;
prefix = envvar_prefix ();
while (size > 1 && *prefix)
{
*pname++ = *prefix++;
size--;
}
if (size > 1)
{
*pname++ = '_';
size--;
}
while (size > 1 && *name)
{
*pname++ = *name++;
size--;
}
*pname = '\0';
return buf;
}
/*
* envvar_get - get value of an prefixed environment variable
* return: a string containing the value for the specified environment
* variable
* name(in): environment variable name without prefix
*
* Note: the prefix symbol will be added to the name
*/
const char *
envvar_get (const char *name)
{
char buf[_ENVVAR_MAX_LENGTH];
return getenv (envvar_name (buf, _ENVVAR_MAX_LENGTH, name));
}
/*
* enclosing_method - change value of an prefixed environment variable
* return: error code
* name(in): environment variable name without prefix
* val(in): the value to be set to the environment variable
*
* Note: the prefix symbol will be added to the name
*/
int
envvar_set (const char *name, const char *val)
{
char buf[_ENVVAR_MAX_LENGTH];
int ret;
envvar_name (buf, _ENVVAR_MAX_LENGTH, name);
ret = setenv (buf, val, 1);
if (ret != 0)
{
return ER_FAILED;
}
return NO_ERROR;
}
/*
* envvar_expand - expand environment variables (${ENV}) with their values
* within the string
* return: error code
* string(in): string containing environment variables
* buffer(out): output buffer
* maxlen(in): maximum length of output buffer
*
* Note:
* The environment variables must be prefixed with a '$' and are
* enclosed by '{' and '}' or terminated by a non alpha numeric character
* except for '_'.
* If all of the referenced environment variables were expanded,
* NO_ERROR is returned. If a reference could not be expanded, the output
* buffer will contain the name of the unresolved variable.
* This function can handle up to 10 environment variables. It is an error
* if exceeds.
*/
int
envvar_expand (const char *string, char *buffer, size_t maxlen)
{
#define _ENVVAR_MAX_EXPANSION (10 * 2 + 1)
struct _fragment
{
const char *str;
size_t len;
} fragments[_ENVVAR_MAX_EXPANSION], *cur, *fen;
char env[_ENVVAR_MAX_LENGTH], *val;
const char *s, *e;
s = strchr (string, '$');
if (!s)
{
/* no environment variable in the string */
(void) strlcpy (buffer, string, maxlen);
return NO_ERROR;
}
cur = fragments;
fen = fragments + _ENVVAR_MAX_EXPANSION;
do
{
env[0] = '\0';
if (s[1] == '{')
{
for (e = s + 1; *e && *e != '}'; e++)
;
if (*e && (e - s - 2) < _ENVVAR_MAX_LENGTH)
{
/* ${ENV}; copy the name of the environment variable */
(void) strlcpy (env, s + 2, e - s - 1);
e++;
}
}
else
{
for (e = s + 1; *e && (isalnum (*e) || *e == '_'); e++)
;
if ((e - s - 1) < _ENVVAR_MAX_LENGTH)
{
/* $ENV; copy the name of the environment variable */
(void) strlcpy (env, s + 1, e - s);
}
}
if (env[0])
{
/* a environment variable is referred; get the value */
val = getenv (env);
if (!val)
{
/* error */
(void) strlcpy (buffer, env, maxlen);
return ER_FAILED;
}
if (s > string)
{
/* a fragment */
cur->str = string;
cur->len = s - string;
if (++cur > fen)
{
/* error */
*buffer = '\0';
return ER_FAILED;
}
}
/* a fragment of the value */
cur->str = val;
cur->len = strlen (val);
if (++cur > fen)
{
/* error */
*buffer = '\0';
return ER_FAILED;
}
}
else
{
cur->str = string;
cur->len = e - string;
if (++cur > fen)
{
/* error */
*buffer = '\0';
return ER_FAILED;
}
}
string = e;
s = strchr (string, '$');
}
while (s);
if (*string)
{
cur->str = string;
cur->len = strlen (string);
cur++;
}
cur->str = NULL;
cur->len = 0;
/* assemble fragments */
for (cur = fragments; cur->len && maxlen > 1; cur++)
{
if (cur->len >= maxlen)
{
cur->len = maxlen - 1;
}
(void) memcpy (buffer, cur->str, cur->len);
buffer += cur->len;
maxlen -= cur->len;
}
*buffer = '\0';
return NO_ERROR;
}
char *
envvar_bindir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/bin/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_libdir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/lib/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_vmdir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/vm/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_localedir_file (char *path, size_t size, const char *langpath, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/msg/%s/%s", envvar_Root, langpath, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_confdir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/conf/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_vardir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/var/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_tmpdir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/tmp/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_logdir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/log/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
void
envvar_trim_char (char *env_val, const int c)
{
char *buf;
size_t size;
if (env_val == NULL)
{
return;
}
size = strlen (env_val);
if (*env_val == c && size > 2)
{
buf = (char *) malloc (1 + size);
if (buf != NULL)
{
strcpy (buf, env_val);
strncpy (env_val, buf + 1, size - 2);
env_val[size - 2] = '\0';
free (buf);
}
}
}
char *
envvar_ldmldir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/locales/data/ldml/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_codepagedir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/locales/data/codepages/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_localedatadir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/locales/data/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_loclib_dir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/locales/loclib/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}
char *
envvar_cubrid_dir (char *path, size_t size)
{
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s", envvar_Root);
path[size - 1] = '\0';
return path;
}
char *
envvar_tzdata_dir_file (char *path, size_t size, const char *filename)
{
assert (filename != NULL);
if (envvar_Root == NULL)
{
envvar_root ();
}
snprintf (path, size, "%s/timezones/tzdata/%s", envvar_Root, filename);
path[size - 1] = '\0';
return path;
}