File util_common.c¶
File List > cubrid > src > executables > util_common.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.
*
*/
/*
* util_common.c - utility common functions
*/
#ident "$Id$"
#include <ctype.h>
#include <assert.h>
#if !defined(WINDOWS)
#include <fcntl.h>
#endif /* !defined(WINDOWS) */
#include "config.h"
#include "utility.h"
#include "util_func.h"
#include "porting.h"
#include "message_catalog.h"
#include "log_common_impl.h"
#include "log_writer.h"
#include "mprec.h"
#include "system_parameter.h"
#include "environment_variable.h"
#include "heartbeat.h"
#if defined (WINDOWS)
#include "wintcp.h"
#else
#include "tcp.h"
#endif
// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"
typedef enum
{
EXISTING_DATABASE,
NEW_DATABASE
} DATABASE_NAME;
static int utility_get_option_index (UTIL_ARG_MAP * arg_map, int arg_ch);
static int check_database_name_local (const char *name, int existing_or_new_db);
static char **util_split_ha_node (const char *str);
static char **util_split_ha_db (const char *str);
static char **util_split_ha_sync (const char *str);
static int util_get_ha_parameters (char **ha_node_list_p, char **ha_db_list_p, char **ha_sync_mode_p,
const char **ha_copy_log_base_p, int *ha_max_mem_size_p);
static bool util_is_replica_node (void);
static int utility_system_class_def_compare (const void *a, const void *b);
/*
* utility_initialize() - initialize cubrid library
* return: 0 if success, otherwise -1
*/
int
utility_initialize ()
{
er_init (NULL, ER_NEVER_EXIT);
if (msgcat_init () != NO_ERROR)
{
PRINT_AND_LOG_ERR_MSG ("Unable to access system message catalog.\n");
return ER_BO_CANNOT_ACCESS_MESSAGE_CATALOG;
}
return NO_ERROR;
}
/*
* utility_get_generic_message() - get a string of the generic-utility from the catalog
* return: message string
* message_index(in): an index of the message string
*/
const char *
utility_get_generic_message (int message_index)
{
return (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC, message_index));
}
/*
* check_database_name() - check validation of the name of a database for existing db
* return: error code
* name(in): the name of a database
*/
int
check_database_name (const char *name)
{
return check_database_name_local (name, EXISTING_DATABASE);
}
/*
* check_database_name() - check validation of the name of a database for new db
* return: error code
* name(in): the name of a database
*/
int
check_new_database_name (const char *name)
{
return check_database_name_local (name, NEW_DATABASE);
}
/*
* check_database_name_local() - check validation of the name of a database
* return: error code
* name(in): the name of a database
* existing_or_new_db(in): whether db is existing or new one
*/
static int
check_database_name_local (const char *name, int existing_or_new_db)
{
int status = NO_ERROR;
int i = 0;
if (name[0] == '#')
{
status = ER_GENERIC_ERROR;
}
else
{
for (i = 0; name[i] != 0; i++)
{
if (isspace (name[i]) || name[i] == '/' || name[i] == '\\' || !isprint (name[i])
|| (existing_or_new_db == NEW_DATABASE && name[i] == '@'))
{
status = ER_GENERIC_ERROR;
break;
}
}
}
if (status == ER_GENERIC_ERROR)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_BAD_DATABASE_NAME);
if (message != NULL)
{
PRINT_AND_LOG_ERR_MSG (message, name[i], name);
}
}
return status;
}
/*
* check_volume_name() - check validation of the name of a volume
* return: error code
* name(in): the name of a volume
*/
int
check_volume_name (const char *name)
{
int status = NO_ERROR;
int i = 0;
if (name == NULL)
{
return NO_ERROR;
}
if (name[0] == '#')
{
status = ER_GENERIC_ERROR;
}
else
{
for (i = 0; name[i] != 0; i++)
{
if (isspace (name[i]) || name[i] == '/' || name[i] == '\\' || !isprint (name[i]))
{
status = ER_GENERIC_ERROR;
break;
}
}
}
if (status == ER_GENERIC_ERROR)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_BAD_VOLUME_NAME);
if (message != NULL)
{
PRINT_AND_LOG_ERR_MSG (message, name[i], name);
}
}
return status;
}
/*
* utility_get_option_index() - search an option in the map of arguments
* return: an index of a founded option
* arg_map(in): the map of arguments
* arg_ch(in): the value of an argument
*/
static int
utility_get_option_index (UTIL_ARG_MAP * arg_map, int arg_ch)
{
int i;
for (i = 0; arg_map[i].arg_ch; i++)
{
if (arg_map[i].arg_ch == arg_ch)
{
return i;
}
}
return -1;
}
/*
* utility_get_option_int_value() - search an option in the map of arguments
* and return that value
* return: the value of a searched argument
* arg_map(in): the map of arguments
* arg_ch(in): the value of an argument
*/
int
utility_get_option_int_value (UTIL_ARG_MAP * arg_map, int arg_ch)
{
int index = utility_get_option_index (arg_map, arg_ch);
if (index != -1)
{
return arg_map[index].arg_value.i;
}
return 0;
}
/*
* get_option_bool_value() - search an option in the map of arguments
* and return that value
* return: the value of a searched argument
* arg_map(in): the map of arguments
* arg_ch(in): the value of an argument
*/
bool
utility_get_option_bool_value (UTIL_ARG_MAP * arg_map, int arg_ch)
{
int index = utility_get_option_index (arg_map, arg_ch);
if (index != -1)
{
if (arg_map[index].arg_value.i == 1)
{
return true;
}
}
return false;
}
/*
* get_option_string_value() - search an option in the map of arguments
* and return that value
* return: the value of a searched argument
* arg_map(in): the map of arguments
* arg_ch(in): the value of an argument
*/
char *
utility_get_option_string_value (UTIL_ARG_MAP * arg_map, int arg_ch, int index)
{
int arg_index = utility_get_option_index (arg_map, arg_ch);
if (arg_index != -1)
{
if (arg_ch == OPTION_STRING_TABLE)
{
if (index < arg_map[arg_index].value_info.num_strings)
{
return (((char **) arg_map[arg_index].arg_value.p)[index]);
}
}
else
{
return ((char *) arg_map[arg_index].arg_value.p);
}
}
return NULL;
}
/*
* utility_get_option_bigint_value() - search an option in the map of arguments
* and return that value
* return: the value of a searched argument
* arg_map(in): the map of arguments
* arg_ch(in): the value of an argument
*/
INT64
utility_get_option_bigint_value (UTIL_ARG_MAP * arg_map, int arg_ch)
{
int index = utility_get_option_index (arg_map, arg_ch);
if (index != -1)
{
return arg_map[index].arg_value.l;
}
return 0;
}
int
utility_get_option_string_table_size (UTIL_ARG_MAP * arg_map)
{
int arg_index = utility_get_option_index (arg_map, OPTION_STRING_TABLE);
if (arg_index != -1)
{
return arg_map[arg_index].value_info.num_strings;
}
return 0;
}
/*
* utility_check_class_name() - Check if class name is valid.
* return: error code
* class_name(in): the name of the class
*/
int
utility_check_class_name (const char *class_name)
{
int class_name_len = 0;
int sub_len = 0;
const char *dot = NULL;
if (class_name == NULL || class_name[0] == '\0')
{
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC, MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT));
util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
return ER_FAILED;
}
class_name_len = STATIC_CAST (int, strlen (class_name));
if (class_name_len >= SM_MAX_IDENTIFIER_LENGTH)
{
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC,
MSGCAT_UTIL_GENERIC_CLASSNAME_EXCEED_MAX_LENGTH), SM_MAX_USER_LENGTH,
SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH);
util_log_write_errid (MSGCAT_UTIL_GENERIC_CLASSNAME_EXCEED_MAX_LENGTH, SM_MAX_USER_LENGTH,
SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH);
return ER_FAILED;
}
dot = strchr (class_name, '.');
if (dot == NULL)
{
/* owner name or class name is not specified */
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC,
MSGCAT_UTIL_GENERIC_CLASSNAME_INVALID_FORMAT), class_name);
util_log_write_errid (MSGCAT_UTIL_GENERIC_CLASSNAME_INVALID_FORMAT, class_name);
return ER_FAILED;
}
/* check length of owner name */
sub_len = STATIC_CAST (int, dot - class_name);
if (sub_len < 1)
{
/* owner name is not specified (e.g. '.class_name') */
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC,
MSGCAT_UTIL_GENERIC_CLASSNAME_INVALID_FORMAT), class_name);
util_log_write_errid (MSGCAT_UTIL_GENERIC_CLASSNAME_INVALID_FORMAT, class_name);
return ER_FAILED;
}
if (sub_len >= SM_MAX_USER_LENGTH)
{
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC,
MSGCAT_UTIL_GENERIC_CLASSNAME_EXCEED_MAX_LENGTH), SM_MAX_USER_LENGTH,
SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH);
util_log_write_errid (MSGCAT_UTIL_GENERIC_CLASSNAME_EXCEED_MAX_LENGTH, SM_MAX_USER_LENGTH,
SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH);
return ER_FAILED;
}
/* check length of class name */
sub_len = STATIC_CAST (int, strlen (dot + 1));
if (sub_len < 1)
{
/* class name is not specified (e.g. 'owner_name.') */
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC,
MSGCAT_UTIL_GENERIC_CLASSNAME_INVALID_FORMAT), class_name);
util_log_write_errid (MSGCAT_UTIL_GENERIC_CLASSNAME_INVALID_FORMAT, class_name);
return ER_FAILED;
}
if (sub_len >= SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH)
{
PRINT_AND_LOG_ERR_MSG (msgcat_message
(MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC,
MSGCAT_UTIL_GENERIC_CLASSNAME_EXCEED_MAX_LENGTH), SM_MAX_USER_LENGTH,
SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH);
util_log_write_errid (MSGCAT_UTIL_GENERIC_CLASSNAME_EXCEED_MAX_LENGTH, SM_MAX_USER_LENGTH,
SM_MAX_IDENTIFIER_LENGTH - SM_MAX_USER_LENGTH);
return ER_FAILED;
}
return NO_ERROR;
}
/*
* fopen_ex - open a file for variable architecture
* return: FILE *
* filename(in): path to the file to open
* type(in): open type
*/
FILE *
fopen_ex (const char *filename, const char *type)
{
#if defined(SOLARIS)
size_t r = 0;
char buf[1024];
extern size_t confstr (int, char *, size_t);
r = confstr (_CS_LFS_CFLAGS, buf, 1024);
if (r > 0)
return fopen64 (filename, type);
else
return fopen (filename, type);
#elif defined(HPUX)
#if _LFS64_LARGEFILE == 1
return fopen64 (filename, type);
#else
return fopen (filename, type);
#endif
#elif defined(AIX) || (defined(I386) && defined(LINUX))
return fopen64 (filename, type);
#else /* NT, ALPHA_OSF, and the others */
return fopen (filename, type);
#endif
}
/*
* utility_keyword_search
*/
int
utility_keyword_search (const UTIL_KEYWORD * keywords, int *keyval_p, char **keystr_p)
{
const UTIL_KEYWORD *keyp;
if (*keyval_p >= 0 && *keystr_p == NULL)
{
/* get keyword string from keyword value */
for (keyp = keywords; keyp->keyval >= 0; keyp++)
{
if (*keyval_p == keyp->keyval)
{
*keystr_p = const_cast < char *>(keyp->keystr);
return NO_ERROR;
}
}
}
else if (*keyval_p < 0 && *keystr_p != NULL)
{
/* get keyword value from keyword string */
for (keyp = keywords; keyp->keystr != NULL; keyp++)
{
if (!strcasecmp (*keystr_p, keyp->keystr))
{
*keyval_p = keyp->keyval;
return NO_ERROR;
}
}
}
return ER_FAILED;
}
/*
* utility_localtime - transform date and time to broken-down time
* return: 0 if success, otherwise -1
* ts(in): pointer of time_t data value
* result(out): pointer of struct tm which will store the broken-down time
*/
int
utility_localtime (const time_t * ts, struct tm *result)
{
struct tm *tm_p, tm_val;
if (result == NULL)
{
return -1;
}
tm_p = localtime_r (ts, &tm_val);
if (tm_p == NULL)
{
memset (result, 0, sizeof (struct tm));
return -1;
}
memcpy (result, tm_p, sizeof (struct tm));
return 0;
}
/*
* util_is_localhost -
*
* return:
*
* NOTE:
*/
bool
util_is_localhost (char *host)
{
char localhost[CUB_MAXHOSTNAMELEN];
GETHOSTNAME (localhost, CUB_MAXHOSTNAMELEN);
return are_hostnames_equal (host, localhost);
}
bool
are_hostnames_equal (const char *hostname_a, const char *hostname_b)
{
const char *a;
const char *b;
for (a = hostname_a, b = hostname_b; *a && *b && (toupper (*a) == toupper (*b)); ++a, ++b)
;
if (*a == '\0' && *b != '\0')
{
return *b == '.';
}
else if (*a != '\0' && *b == '\0')
{
return *a == '.';
}
else
{
return toupper (*a) == toupper (*b);
}
}
/*
* util_get_num_of_ha_nodes - counter the number of nodes
* in either ha_node_list or ha_replica_list
* return: the number of nodes in a node list
* node_list(in): ha_node_list or ha_replica_list
*/
int
util_get_num_of_ha_nodes (const char *node_list)
{
char **ha_node_list_pp = NULL;
int num_of_nodes = 0;
if (node_list == NULL)
{
return 0;
}
if ((ha_node_list_pp = util_split_ha_node (node_list)) != NULL)
{
for (num_of_nodes = 0; ha_node_list_pp[num_of_nodes] != NULL;)
{
num_of_nodes++;
}
}
if (ha_node_list_pp)
{
util_free_string_array (ha_node_list_pp);
}
return num_of_nodes;
}
static char **
util_split_ha_node (const char *str)
{
char *start_node;
start_node = (char *) strchr (str, '@');
if (start_node == NULL || str == start_node)
{
return NULL;
}
return util_split_string (start_node + 1, " ,:");
}
static char **
util_split_ha_db (const char *str)
{
return util_split_string (str, " ,:");
}
static char **
util_split_ha_sync (const char *str)
{
return util_split_string (str, " ,:");
}
/*
* copylogdb_keyword() - get keyword value or string of the copylogdb mode
* return: NO_ERROR or ER_FAILED
* keyval_p(in/out): keyword value
* keystr_p(in/out): keyword string
*/
int
copylogdb_keyword (int *keyval_p, char **keystr_p)
{
static const UTIL_KEYWORD keywords[] = {
{LOGWR_MODE_ASYNC, "async"},
{LOGWR_MODE_SEMISYNC, "semisync"},
{LOGWR_MODE_SYNC, "sync"},
{-1, NULL}
};
return utility_keyword_search (keywords, keyval_p, keystr_p);
}
/*
* changemode_keyword() - get keyword value or string of the server mode
* return: NO_ERROR or ER_FAILED
* keyval_p(in/out): keyword value
* keystr_p(in/out): keyword string
*/
int
changemode_keyword (int *keyval_p, char **keystr_p)
{
static const UTIL_KEYWORD keywords[] = {
{HA_SERVER_STATE_IDLE, HA_SERVER_STATE_IDLE_STR},
{HA_SERVER_STATE_ACTIVE, HA_SERVER_STATE_ACTIVE_STR},
{HA_SERVER_STATE_TO_BE_ACTIVE, HA_SERVER_STATE_TO_BE_ACTIVE_STR},
{HA_SERVER_STATE_STANDBY, HA_SERVER_STATE_STANDBY_STR},
{HA_SERVER_STATE_TO_BE_STANDBY, HA_SERVER_STATE_TO_BE_STANDBY_STR},
{HA_SERVER_STATE_MAINTENANCE, HA_SERVER_STATE_MAINTENANCE_STR},
{HA_SERVER_STATE_DEAD, HA_SERVER_STATE_DEAD_STR},
{-1, NULL}
};
return utility_keyword_search (keywords, keyval_p, keystr_p);
}
static int
util_get_ha_parameters (char **ha_node_list_p, char **ha_db_list_p, char **ha_sync_mode_p,
const char **ha_copy_log_base_p, int *ha_max_mem_size_p)
{
int error = NO_ERROR;
*(ha_db_list_p) = prm_get_string_value (PRM_ID_HA_DB_LIST);
if (*(ha_db_list_p) == NULL || **(ha_db_list_p) == '\0')
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_INVALID_PARAMETER);
fprintf (stderr, message, prm_get_name (PRM_ID_HA_DB_LIST), "");
return ER_GENERIC_ERROR;
}
*(ha_node_list_p) = prm_get_string_value (PRM_ID_HA_NODE_LIST);
if (*(ha_node_list_p) == NULL || **(ha_node_list_p) == '\0')
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_INVALID_PARAMETER);
fprintf (stderr, message, prm_get_name (PRM_ID_HA_NODE_LIST), "");
return ER_GENERIC_ERROR;
}
*(ha_sync_mode_p) = prm_get_string_value (PRM_ID_HA_COPY_SYNC_MODE);
*(ha_max_mem_size_p) = prm_get_integer_value (PRM_ID_HA_APPLY_MAX_MEM_SIZE);
*(ha_copy_log_base_p) = prm_get_string_value (PRM_ID_HA_COPY_LOG_BASE);
if (*(ha_copy_log_base_p) == NULL || **(ha_copy_log_base_p) == '\0')
{
*(ha_copy_log_base_p) = (char *) envvar_get ("DATABASES");
if (*(ha_copy_log_base_p) == NULL)
{
*(ha_copy_log_base_p) = ".";
}
}
return error;
}
static bool
util_is_replica_node (void)
{
bool is_replica_node = false;
int i;
char local_host_name[CUB_MAXHOSTNAMELEN];
char *ha_replica_list_p, **ha_replica_list_pp = NULL;
ha_replica_list_p = prm_get_string_value (PRM_ID_HA_REPLICA_LIST);
if (ha_replica_list_p != NULL && *(ha_replica_list_p) != '\0')
{
ha_replica_list_pp = util_split_ha_node (ha_replica_list_p);
if (ha_replica_list_pp != NULL && (GETHOSTNAME (local_host_name, sizeof (local_host_name)) == 0))
{
for (i = 0; ha_replica_list_pp[i] != NULL; i++)
{
if (strcmp (ha_replica_list_pp[i], local_host_name) == 0)
{
is_replica_node = true;
break;
}
}
}
}
if (ha_replica_list_pp)
{
util_free_string_array (ha_replica_list_pp);
}
return is_replica_node;
}
/*
* util_free_ha_conf -
*
* return:
*
* NOTE:
*/
void
util_free_ha_conf (HA_CONF * ha_conf)
{
int i;
HA_NODE_CONF *nc;
for (i = 0, nc = ha_conf->node_conf; i < ha_conf->num_node_conf; i++)
{
if (nc[i].node_name)
{
free_and_init (nc[i].node_name);
}
if (nc[i].copy_log_base)
{
free_and_init (nc[i].copy_log_base);
}
if (nc[i].copy_sync_mode)
{
free_and_init (nc[i].copy_sync_mode);
}
}
free_and_init (ha_conf->node_conf);
ha_conf->num_node_conf = 0;
ha_conf->node_conf = NULL;
if (ha_conf->db_names)
{
util_free_string_array (ha_conf->db_names);
ha_conf->db_names = NULL;
}
return;
}
/*
* util_make_ha_conf -
*
* return:
*
* NOTE:
*/
int
util_make_ha_conf (HA_CONF * ha_conf)
{
int error = NO_ERROR;
int i, num_ha_nodes;
char *ha_db_list_p = NULL;
char *ha_node_list_p = NULL, **ha_node_list_pp = NULL;
char *ha_sync_mode_p = NULL, **ha_sync_mode_pp = NULL;
const char *ha_copy_log_base_p;
int ha_max_mem_size;
bool is_replica_node;
error =
util_get_ha_parameters (&ha_node_list_p, &ha_db_list_p, &ha_sync_mode_p, &ha_copy_log_base_p, &ha_max_mem_size);
if (error != NO_ERROR)
{
return error;
}
ha_conf->db_names = util_split_ha_db (ha_db_list_p);
if (ha_conf->db_names == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
ha_node_list_pp = util_split_ha_node (ha_node_list_p);
if (ha_node_list_pp == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
for (i = 0; ha_node_list_pp[i] != NULL;)
{
i++;
}
num_ha_nodes = i;
ha_conf->node_conf = (HA_NODE_CONF *) malloc (sizeof (HA_NODE_CONF) * num_ha_nodes);
if (ha_conf->node_conf == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
memset ((void *) ha_conf->node_conf, 0, sizeof (HA_NODE_CONF) * num_ha_nodes);
ha_conf->num_node_conf = num_ha_nodes;
/* set ha_sync_mode */
is_replica_node = util_is_replica_node ();
if (is_replica_node == true)
{
for (i = 0; i < num_ha_nodes; i++)
{
ha_conf->node_conf[i].copy_sync_mode = strdup ("async");
if (ha_conf->node_conf[i].copy_sync_mode == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
}
}
else
{
if (ha_sync_mode_p == NULL || *(ha_sync_mode_p) == '\0')
{
for (i = 0; i < num_ha_nodes; i++)
{
ha_conf->node_conf[i].copy_sync_mode = strdup ("sync");
if (ha_conf->node_conf[i].copy_sync_mode == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
}
}
else
{
int mode;
ha_sync_mode_pp = util_split_ha_sync (ha_sync_mode_p);
if (ha_sync_mode_pp == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
for (i = 0; i < num_ha_nodes; i++)
{
mode = -1;
if (ha_sync_mode_pp[i] == NULL || copylogdb_keyword (&mode, &ha_sync_mode_pp[i]) == -1)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_INVALID_PARAMETER);
fprintf (stderr, message, prm_get_name (PRM_ID_HA_COPY_SYNC_MODE),
(ha_sync_mode_pp[i]) ? ha_sync_mode_pp[i] : "");
error = ER_GENERIC_ERROR;
goto ret;
}
ha_conf->node_conf[i].copy_sync_mode = strdup (ha_sync_mode_pp[i]);
if (ha_conf->node_conf[i].copy_sync_mode == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
}
}
}
for (i = 0; i < num_ha_nodes; i++)
{
assert_release (ha_node_list_pp[i] != NULL);
ha_conf->node_conf[i].node_name = strdup (ha_node_list_pp[i]);
ha_conf->node_conf[i].copy_log_base = strdup (ha_copy_log_base_p);
ha_conf->node_conf[i].apply_max_mem_size = ha_max_mem_size;
if (ha_conf->node_conf[i].node_name == NULL || ha_conf->node_conf[i].copy_log_base == NULL)
{
const char *message = utility_get_generic_message (MSGCAT_UTIL_GENERIC_NO_MEM);
fprintf (stderr, message);
error = ER_GENERIC_ERROR;
goto ret;
}
}
ret:
if (ha_node_list_pp)
{
util_free_string_array (ha_node_list_pp);
ha_node_list_pp = NULL;
}
if (ha_sync_mode_pp)
{
util_free_string_array (ha_sync_mode_pp);
ha_sync_mode_pp = NULL;
}
if (error != NO_ERROR)
{
util_free_ha_conf (ha_conf);
}
return error;
}
/*
* util_get_ha_mode_for_sa_utils -
*
* return:
*
* NOTE:
*/
int
util_get_ha_mode_for_sa_utils (void)
{
return prm_get_integer_value (PRM_ID_HA_MODE_FOR_SA_UTILS_ONLY);
}
#if !defined(WINDOWS)
/*
* util_redirect_stdout_to_null - redirect stdout/stderr to /dev/null
*
* return:
*
*/
void
util_redirect_stdout_to_null (void)
{
const char *null_dev = "/dev/null";
int fd;
fd = open (null_dev, O_WRONLY);
if (fd != -1)
{
close (1);
close (2);
dup2 (fd, 1);
dup2 (fd, 2);
close (fd);
}
}
#endif /* !defined(WINDOWS) */
/*
* util_size_to_byte -
*
* return:
*
*/
static int
util_size_to_byte (double *pre, const char *post)
{
if (strcasecmp (post, "b") == 0)
{
/* bytes */
}
else if ((strcasecmp (post, "k") == 0) || (strcasecmp (post, "kb") == 0))
{
/* kilo */
*pre = *pre * ONE_K;
}
else if ((strcasecmp (post, "m") == 0) || (strcasecmp (post, "mb") == 0))
{
/* mega */
*pre = *pre * ONE_M;
}
else if ((strcasecmp (post, "g") == 0) || (strcasecmp (post, "gb") == 0))
{
/* giga */
*pre = *pre * ONE_G;
}
else if ((strcasecmp (post, "t") == 0) || (strcasecmp (post, "tb") == 0))
{
/* tera */
*pre = *pre * ONE_T;
}
else if ((strcasecmp (post, "p") == 0) || (strcasecmp (post, "pb") == 0))
{
/* peta */
*pre = *pre * ONE_P;
}
else
{
return ER_FAILED;
}
return NO_ERROR;
}
/*
* util_byte_to_size_string -
*
* return:
*
*/
int
util_byte_to_size_string (char *buf, size_t len, UINT64 size_num)
{
char num_str[100];
const char *ss = "BKMGTP";
double v = (double) size_num;
int pow = 0;
int i, decpt, sign, num_len;
char *rve;
if (buf == NULL)
{
return ER_FAILED;
}
buf[0] = '\0';
while (pow < 6 && v >= ONE_K)
{
pow++;
v /= ONE_K;
}
_dtoa (v, 3, 1, &decpt, &sign, &rve, num_str, 0);
num_str[99] = '\0';
num_len = (int) strlen (num_str);
if (len < (size_t) (decpt + 4))
{
return ER_FAILED;
}
for (i = 0; i <= decpt + 1; i++)
{
if (i == decpt)
{
buf[i] = '.';
}
else if (i == decpt + 1)
{
if (num_len > decpt)
{
buf[i] = num_str[num_len - 1];
}
else
{
buf[i] = '0';
}
buf[i + 1] = ss[pow];
buf[i + 2] = '\0';
}
else
{
if (num_len < decpt && i >= num_len)
{
buf[i] = '0';
}
else
{
buf[i] = num_str[i];
}
}
}
return NO_ERROR;
}
/*
* util_size_string_to_byte -
*
* return:
*
*/
int
util_size_string_to_byte (UINT64 * size_num, const char *size_str)
{
double val;
const char *default_unit = "B";
char *end;
const char *size_unit;
if (size_str == NULL || size_num == NULL)
{
return ER_FAILED;
}
*size_num = 0;
val = strtod (size_str, &end);
if (end == size_str)
{
return ER_FAILED;
}
if (val < 0)
{
return ER_FAILED;
}
if (*end != '\0')
{
size_unit = end;
}
else
{
size_unit = default_unit;
}
if (util_size_to_byte (&val, size_unit) != NO_ERROR)
{
return ER_FAILED;
}
*size_num = (UINT64) val;
return NO_ERROR;
}
/*
* util_time_to_byte -
*
* return:
*
*/
static int
util_time_to_msec (double *pre, const char *post)
{
if ((strcasecmp (post, "ms") == 0) || (strcasecmp (post, "msec") == 0))
{
/* millisecond */
}
else if ((strcasecmp (post, "s") == 0) || (strcasecmp (post, "sec") == 0))
{
/* second */
*pre = *pre * ONE_SEC;
}
else if (strcasecmp (post, "min") == 0)
{
/* minute */
*pre = *pre * ONE_MIN;
}
else if (strcasecmp (post, "h") == 0)
{
/* hours */
*pre = *pre * ONE_HOUR;
}
else
{
return ER_FAILED;
}
return NO_ERROR;
}
/*
* util_msec_to_time_string -
*
* return:
*
*/
int
util_msec_to_time_string (char *buf, size_t len, INT64 msec_num)
{
INT64 v = msec_num;
INT64 sec, msec;
int error = 0;
if (buf == NULL)
{
return ER_FAILED;
}
buf[0] = '\0';
sec = v / ONE_SEC;
if (sec > 0)
{
msec = v % ONE_SEC;
error = snprintf (buf, len, "%lld.%03lld sec", (long long) sec, (long long) msec);
}
else if (v < 0)
{
error = snprintf (buf, len, "%lld", (long long) v);
}
else
{
error = snprintf (buf, len, "%lld msec", (long long) v);
}
if (error < 0)
{
return ER_FAILED;
}
return NO_ERROR;
}
/*
* util_time_string_to_msec -
*
* return:
*
*/
int
util_time_string_to_msec (INT64 * msec_num, char *time_str)
{
double val;
const char *default_unit = "ms";
char *end;
const char *time_unit;
if (time_str == NULL || msec_num == NULL)
{
return ER_FAILED;
}
*msec_num = 0;
val = strtod (time_str, &end);
if (end == time_str)
{
return ER_FAILED;
}
if (val < 0)
{
*msec_num = (INT64) val;
return NO_ERROR;
}
if (*end != '\0')
{
time_unit = end;
}
else
{
time_unit = default_unit;
}
if (util_time_to_msec (&val, time_unit) != NO_ERROR)
{
return ER_FAILED;
}
*msec_num = (INT64) val;
return NO_ERROR;
}
/*
* util_print_deprecated -
*
* return:
*
*/
void
util_print_deprecated (const char *option)
{
int cat = MSGCAT_CATALOG_UTILS;
int set = MSGCAT_UTIL_SET_GENERIC;
int msg = MSGCAT_UTIL_GENERIC_DEPRECATED;
const char *fmt = msgcat_message (cat, set, msg);
if (fmt == NULL)
{
fprintf (stderr, "error: msgcat_message");
}
else
{
fprintf (stderr, fmt, option);
}
}
/*
* util_get_table_list_from_file() -
* return: NO_ERROR/ER_GENERIC_ERROR
*/
int
util_get_table_list_from_file (char *fname, dynamic_array * darray)
{
int c, i, p;
char name[SM_MAX_IDENTIFIER_LENGTH];
FILE *fp = fopen (fname, "r");
if (fp == NULL)
{
util_log_write_errid (MSGCAT_UTIL_GENERIC_FILEOPEN_ERROR, fname);
return ER_GENERIC_ERROR;
}
i = p = 0;
while (1)
{
c = fgetc (fp);
if (char_isspace2 (c) || c == ',' || c == EOF)
{
if (p != 0)
{
name[p] = '\0';
if (utility_check_class_name (name) != NO_ERROR)
{
fclose (fp);
/* The util_log_write_errid function is called inside the utility_check_class_name function. */
return ER_GENERIC_ERROR;
}
if (da_add (darray, name) != NO_ERROR)
{
fclose (fp);
util_log_write_errid (MSGCAT_UTIL_GENERIC_NO_MEM);
return ER_GENERIC_ERROR;
}
i++;
p = 0;
}
if (c == EOF)
{
break;
}
continue;
}
name[p++] = c;
if (p == SM_MAX_IDENTIFIER_LENGTH)
{
/* too long table name */
if (utility_check_class_name (name) != NO_ERROR)
{
fclose (fp);
/* The util_log_write_errid function is called inside the utility_check_class_name function. */
return ER_GENERIC_ERROR;
}
}
}
fclose (fp);
return NO_ERROR;
}