File util_support.c¶
File List > cubrid > src > executables > util_support.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_support.c: common utility functions
*/
#ident "$Id$"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#if !defined(WINDOWS)
#include <dlfcn.h>
#endif
#include "cubrid_getopt.h"
#include "error_code.h"
#include "util_support.h"
#include "utility.h"
#include "porting.h"
static int util_parse_string_table (UTIL_MAP * util_map, int index, int count, char **argv);
static int util_put_option_value (UTIL_MAP * util_map, int arg_ch, const char *option_arg);
static bool util_is_password_argument (int index, int value);
/*
* utility_make_getopt_optstring - makes optstring for getopt_long()
* return: optstring
* opt_array(in): array of option structure
* buf(out): buffer for optstring
*/
char *
utility_make_getopt_optstring (const GETOPT_LONG * opt_array, char *buf)
{
int i;
char *p = buf;
for (i = 0; opt_array[i].name; i++)
{
if (opt_array[i].val < 255)
{
*p++ = (char) opt_array[i].val;
if (opt_array[i].has_arg)
{
*p++ = ':';
}
}
}
*p = '\0';
return buf;
}
/*
* utility_load_library - load the shared object
*
* return: error code
* path(in): the path of shared object
*
* NOTE:
*/
int
utility_load_library (DSO_HANDLE * handle, const char *path)
{
UTILITY_INIT_FUNC init_fn;
#if defined(WINDOWS)
(*handle) = LoadLibrary (path);
#elif defined(_AIX)
(*handle) = dlopen (path, RTLD_NOW | RTLD_MEMBER);
#else
(*handle) = dlopen (path, RTLD_NOW | RTLD_GLOBAL);
#endif
if ((*handle) == 0)
{
// todo: generate verbose error
return ER_GENERIC_ERROR;
}
/* initialize library */
if (utility_load_symbol (*handle, (DSO_HANDLE *) (&init_fn), UTILITY_INIT_FUNC_NAME) == NO_ERROR
&& (*init_fn) () == NO_ERROR)
{
return NO_ERROR;
}
else
{
*handle = NULL;
return ER_GENERIC_ERROR;
}
}
/*
* utility_load_symbol - load the symbol of an utility-function in runtime
*
* return:
*
* NOTE:
*/
int
utility_load_symbol (DSO_HANDLE library_handle, DSO_HANDLE * symbol_handle, const char *symbol_name)
{
#if defined(WINDOWS)
(*symbol_handle) = GetProcAddress ((HMODULE) library_handle, symbol_name);
return (*symbol_handle) == NULL ? ER_GENERIC_ERROR : NO_ERROR;
#else
(*symbol_handle) = dlsym (library_handle, symbol_name);
return (*symbol_handle) == 0 ? ER_GENERIC_ERROR : NO_ERROR;
#endif
}
/*
* utility_load_print_error - print error message that occurred during dynamic linking
*
* return:
*
* NOTE:
*/
void
utility_load_print_error (FILE * fp)
{
#if defined(WINDOWS)
char *error;
#endif /* WINDOWS */
if (fp == NULL)
{
return;
}
#if defined(WINDOWS)
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) (&error), 0, NULL);
fprintf (fp, "%s\n", error);
LocalFree (error);
#else /* !WINDOWS */
fprintf (fp, "%s\n", dlerror ());
#endif /* !WINDOWS */
}
/*
* util_parse_argument - parse arguments of an utility
*
* return:
*/
static const char *
util_get_option_name (GETOPT_LONG * option, int option_value)
{
int i = 0;
for (i = 0; option[i].name != NULL; i++)
{
if (option[i].val == option_value)
{
return option[i].name;
}
}
/* unreachable code */
return "";
}
/*
* util_parse_argument - parse arguments of an utility
*
* return:
*
* NOTE:
*/
int
util_parse_argument (UTIL_MAP * util_map, int argc, char **argv)
{
int status;
int option_value;
int option_index;
char option_string[64];
GETOPT_LONG *option = util_map->getopt_long;
utility_make_getopt_optstring (option, option_string);
status = NO_ERROR;
while (status == NO_ERROR)
{
option_index = 0;
option_value = getopt_long (argc, argv, option_string, option, &option_index);
if (option_value == -1)
{
break;
}
else if (option_value == '?' || option_value == ':')
{
status = ER_FAILED;
return status;
}
status = util_put_option_value (util_map, option_value, optarg);
if (status != NO_ERROR)
{
fprintf (stderr, "invalid '--%s' option value: %s\n", util_get_option_name (option, option_value), optarg);
return ER_FAILED;
}
if (util_is_password_argument (util_map->utility_index, option_value))
{
util_hide_password (optarg);
}
}
status = util_parse_string_table (util_map, optind, argc, argv);
return status;
}
/*
* util_is_password_argument -
*
* return:
*
* NOTE:
*/
static bool
util_is_password_argument (int index, int value)
{
if ((index == KILLTRAN && value == KILLTRAN_DBA_PASSWORD_S)
#if defined(TRANLIST_PASSWORD_S)
|| (index == TRANLIST && value == TRANLIST_PASSWORD_S)
#endif
|| (index == TDE && value == TDE_DBA_PASSWORD_S)
|| (index == LOADDB && value == LOAD_PASSWORD_S) || (index == UNLOADDB && value == UNLOAD_PASSWORD_S)
|| (index == FLASHBACK && value == FLASHBACK_DBA_PASSWORD_S))
{
return true;
}
return false;
}
/*
* util_put_option_value - put parsed an argument's value to the utility map
*
* return:
*
* NOTE: An allocated memory may be leaked by the strdup.
*/
static int
util_put_option_value (UTIL_MAP * util_map, int arg_ch, const char *option_arg)
{
int i;
UTIL_ARG_MAP *arg_map = util_map->arg_map;
for (i = 0; arg_map[i].arg_ch; i++)
{
if (arg_map[i].arg_ch == arg_ch)
{
switch (arg_map[i].value_info.value_type)
{
case ARG_BOOLEAN:
arg_map[i].arg_value.i = 1;
return NO_ERROR;
case ARG_INTEGER:
{
int value = 0, result;
result = parse_int (&value, option_arg, 10);
if (result != 0)
{
return ER_FAILED;
}
arg_map[i].arg_value.i = value;
return NO_ERROR;
}
case ARG_BIGINT:
{
int result = 0;
INT64 value;
result = parse_bigint (&value, option_arg, 10);
if (result != 0)
{
return ER_FAILED;
}
arg_map[i].arg_value.l = value;
return NO_ERROR;
}
case ARG_STRING:
if (option_arg[0] == '-')
{
return ER_FAILED;
}
arg_map[i].arg_value.p = strdup (option_arg);
return NO_ERROR;
default:
return ER_FAILED;
}
return NO_ERROR;
}
}
return ER_FAILED;
}
/*
* util_parse_string_table - parse non-option arguments
*
* return:
*
* NOTE: An allocated memory may be leaked by the malloc and the strdup.
*/
static int
util_parse_string_table (UTIL_MAP * util_map, int index, int count, char **argv)
{
int i;
int need_args_num;
char **string_table;
UTIL_ARG_MAP *string_table_arg = NULL;
int num_string_args;
for (i = 0; i < util_map->arg_map[i].arg_ch; i++)
{
if (util_map->arg_map[i].arg_ch == OPTION_STRING_TABLE)
{
string_table_arg = &util_map->arg_map[i];
need_args_num = util_map->need_args_num;
break;
}
}
if (string_table_arg == NULL)
{
return ER_FAILED;
}
num_string_args = count - index;
string_table = (char **) malloc (sizeof (char *) * num_string_args);
if (string_table == NULL)
{
return ER_FAILED;
}
memset (string_table, 0, sizeof (char *) * num_string_args);
for (i = 0; index < count; index++, i++)
{
string_table[i] = argv[index];
/* fprintf (stdout, "%s\n", (*string_table)[i]); */
}
string_table_arg->arg_value.p = string_table;
string_table_arg->value_info.num_strings = num_string_args;
if (need_args_num < num_string_args
&& (util_map->utility_index != COMPACTDB && util_map->utility_index != CHECKDB
&& util_map->utility_index != FLASHBACK))
{
fprintf (stderr, "'%s' argument is not needed.\n",
string_table[need_args_num] == NULL ? "" : string_table[need_args_num]);
return ER_FAILED;
}
return NO_ERROR;
}
/*
* util_hide_password -
*
* return:
*
*/
void
util_hide_password (char *arg)
{
#if defined (LINUX)
if (arg == NULL)
{
return;
}
memset (arg, '*', strlen (arg));
#else
(void) arg;
#endif /* LINUX */
}