CUBRID Engine  latest
util_support.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * util_support.c: common utility functions
21  */
22 
23 #ident "$Id$"
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <errno.h>
28 #if !defined(WINDOWS)
29 #include <dlfcn.h>
30 #endif
31 
32 #include "cubrid_getopt.h"
33 #include "error_code.h"
34 #include "util_support.h"
35 #include "utility.h"
36 #include "porting.h"
37 
38 static int util_parse_string_table (UTIL_MAP * util_map, int index, int count, char **argv);
39 static int util_put_option_value (UTIL_MAP * util_map, int arg_ch, const char *option_arg);
40 static bool util_is_password_argument (int index, int value);
41 
42 /*
43  * utility_make_getopt_optstring - makes optstring for getopt_long()
44  * return: optstring
45  * opt_array(in): array of option structure
46  * buf(out): buffer for optstring
47  */
48 char *
49 utility_make_getopt_optstring (const GETOPT_LONG * opt_array, char *buf)
50 {
51  int i;
52  char *p = buf;
53  for (i = 0; opt_array[i].name; i++)
54  {
55  if (opt_array[i].val < 255)
56  {
57  *p++ = (char) opt_array[i].val;
58  if (opt_array[i].has_arg)
59  {
60  *p++ = ':';
61  }
62  }
63  }
64  *p = '\0';
65  return buf;
66 }
67 
68 /*
69  * utility_load_library - load the shared object
70  *
71  * return: error code
72  * path(in): the path of shared object
73  *
74  * NOTE:
75  */
76 int
77 utility_load_library (DSO_HANDLE * handle, const char *path)
78 {
79  UTILITY_INIT_FUNC init_fn;
80 
81 #if defined(WINDOWS)
82  (*handle) = LoadLibrary (path);
83 #elif defined(_AIX)
84  (*handle) = dlopen (path, RTLD_NOW | RTLD_MEMBER);
85 #else
86  (*handle) = dlopen (path, RTLD_NOW | RTLD_GLOBAL);
87 #endif
88  if ((*handle) == 0)
89  {
90  // todo: generate verbose error
91  return ER_GENERIC_ERROR;
92  }
93 
94  /* initialize library */
95  if (utility_load_symbol (*handle, (DSO_HANDLE *) (&init_fn), UTILITY_INIT_FUNC_NAME) == NO_ERROR
96  && (*init_fn) () == NO_ERROR)
97  {
98  return NO_ERROR;
99  }
100  else
101  {
102  *handle = NULL;
103  return ER_GENERIC_ERROR;
104  }
105 }
106 
107 /*
108  * utility_load_symbol - load the symbol of an utility-function in runtime
109  *
110  * return:
111  *
112  * NOTE:
113  */
114 int
115 utility_load_symbol (DSO_HANDLE library_handle, DSO_HANDLE * symbol_handle, const char *symbol_name)
116 {
117 #if defined(WINDOWS)
118  (*symbol_handle) = GetProcAddress ((HMODULE) library_handle, symbol_name);
119  return (*symbol_handle) == NULL ? ER_GENERIC_ERROR : NO_ERROR;
120 #else
121  (*symbol_handle) = dlsym (library_handle, symbol_name);
122  return (*symbol_handle) == 0 ? ER_GENERIC_ERROR : NO_ERROR;
123 #endif
124 }
125 
126 /*
127  * utility_load_print_error - print error message that occurred during dynamic linking
128  *
129  * return:
130  *
131  * NOTE:
132  */
133 void
135 {
136 
137 #if defined(WINDOWS)
138  char *error;
139 #endif /* WINDOWS */
140 
141  if (fp == NULL)
142  {
143  return;
144  }
145 
146 #if defined(WINDOWS)
147  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
148  GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) (&error), 0, NULL);
149  fprintf (fp, "%s\n", error);
150  LocalFree (error);
151 #else /* !WINDOWS */
152  fprintf (fp, "%s\n", dlerror ());
153 #endif /* !WINDOWS */
154 }
155 
156 /*
157  * util_parse_argument - parse arguments of an utility
158  *
159  * return:
160  */
161 static const char *
163 {
164  int i = 0;
165 
166  for (i = 0; option[i].name != NULL; i++)
167  {
168  if (option[i].val == option_value)
169  {
170  return option[i].name;
171  }
172  }
173 
174  /* unreachable code */
175  return "";
176 }
177 
178 /*
179  * util_parse_argument - parse arguments of an utility
180  *
181  * return:
182  *
183  * NOTE:
184  */
185 int
186 util_parse_argument (UTIL_MAP * util_map, int argc, char **argv)
187 {
188  int status;
189  int option_value;
190  int option_index;
191  char option_string[64];
192  GETOPT_LONG *option = util_map->getopt_long;
193  utility_make_getopt_optstring (option, option_string);
194  status = NO_ERROR;
195  while (status == NO_ERROR)
196  {
197  option_index = 0;
198  option_value = getopt_long (argc, argv, option_string, option, &option_index);
199  if (option_value == -1)
200  {
201  break;
202  }
203  else if (option_value == '?' || option_value == ':')
204  {
205  status = ER_FAILED;
206  return status;
207  }
208  status = util_put_option_value (util_map, option_value, optarg);
209  if (status != NO_ERROR)
210  {
211  fprintf (stderr, "invalid '--%s' option value: %s\n", util_get_option_name (option, option_value), optarg);
212  return ER_FAILED;
213  }
214 
215  if (util_is_password_argument (util_map->utility_index, option_value))
216  {
218  }
219  }
220 
221  status = util_parse_string_table (util_map, optind, argc, argv);
222  return status;
223 }
224 
225 /*
226  * util_is_password_argument -
227  *
228  * return:
229  *
230  * NOTE:
231  */
232 static bool
234 {
235  if ((index == KILLTRAN && value == KILLTRAN_DBA_PASSWORD_S)
236 #if defined(TRANLIST_PASSWORD_S)
237  || (index == TRANLIST && value == TRANLIST_PASSWORD_S)
238 #endif
239  || (index == TDE && value == TDE_DBA_PASSWORD_S)
240  || (index == LOADDB && value == LOAD_PASSWORD_S) || (index == UNLOADDB && value == UNLOAD_PASSWORD_S))
241  {
242  return true;
243  }
244 
245  return false;
246 }
247 
248 /*
249  * util_put_option_value - put parsed an argument's value to the utility map
250  *
251  * return:
252  *
253  * NOTE: An allocated memory may be leaked by the strdup.
254  */
255 static int
256 util_put_option_value (UTIL_MAP * util_map, int arg_ch, const char *option_arg)
257 {
258  int i;
259  UTIL_ARG_MAP *arg_map = util_map->arg_map;
260 
261  for (i = 0; arg_map[i].arg_ch; i++)
262  {
263  if (arg_map[i].arg_ch == arg_ch)
264  {
265  switch (arg_map[i].value_info.value_type)
266  {
267  case ARG_BOOLEAN:
268  arg_map[i].arg_value.i = 1;
269  return NO_ERROR;
270  case ARG_INTEGER:
271  {
272  int value = 0, result;
273 
274  result = parse_int (&value, option_arg, 10);
275 
276  if (result != 0)
277  {
278  return ER_FAILED;
279  }
280 
281  arg_map[i].arg_value.i = value;
282  return NO_ERROR;
283  }
284  case ARG_BIGINT:
285  {
286  int result = 0;
287  INT64 value;
288 
289  result = parse_bigint (&value, option_arg, 10);
290 
291  if (result != 0)
292  {
293  return ER_FAILED;
294  }
295 
296  arg_map[i].arg_value.l = value;
297  return NO_ERROR;
298  }
299  case ARG_STRING:
300  if (option_arg[0] == '-')
301  {
302  return ER_FAILED;
303  }
304 
305  arg_map[i].arg_value.p = strdup (option_arg);
306  return NO_ERROR;
307  default:
308  return ER_FAILED;
309  }
310  return NO_ERROR;
311  }
312  }
313  return ER_FAILED;
314 }
315 
316 /*
317  * util_parse_string_table - parse non-option arguments
318  *
319  * return:
320  *
321  * NOTE: An allocated memory may be leaked by the malloc and the strdup.
322  */
323 static int
324 util_parse_string_table (UTIL_MAP * util_map, int index, int count, char **argv)
325 {
326  int i;
327  int need_args_num;
328  char **string_table;
329  UTIL_ARG_MAP *string_table_arg = NULL;
330  int num_string_args;
331  for (i = 0; i < util_map->arg_map[i].arg_ch; i++)
332  {
333  if (util_map->arg_map[i].arg_ch == OPTION_STRING_TABLE)
334  {
335  string_table_arg = &util_map->arg_map[i];
336  need_args_num = util_map->need_args_num;
337  break;
338  }
339  }
340  if (string_table_arg == NULL)
341  {
342  return ER_FAILED;
343  }
344  num_string_args = count - index;
345  string_table = (char **) malloc (sizeof (char *) * num_string_args);
346  if (string_table == NULL)
347  {
348  return ER_FAILED;
349  }
350  memset (string_table, 0, sizeof (char *) * num_string_args);
351  for (i = 0; index < count; index++, i++)
352  {
353  string_table[i] = argv[index];
354  /* fprintf (stdout, "%s\n", (*string_table)[i]); */
355  }
356  string_table_arg->arg_value.p = string_table;
357  string_table_arg->value_info.num_strings = num_string_args;
358  if (need_args_num < num_string_args && (util_map->utility_index != COMPACTDB && util_map->utility_index != CHECKDB))
359  {
360  fprintf (stderr, "'%s' argument is not needed.\n",
361  string_table[need_args_num] == NULL ? "" : string_table[need_args_num]);
362  return ER_FAILED;
363  }
364  return NO_ERROR;
365 }
366 
367 /*
368  * util_hide_password -
369  *
370  * return:
371  *
372  */
373 void
375 {
376 #if defined (LINUX)
377  if (arg == NULL)
378  {
379  return;
380  }
381 
382  memset (arg, '*', strlen (arg));
383 #else
384  (void) arg;
385 #endif /* LINUX */
386 }
DllImport int optind
void * handle
#define NO_ERROR
Definition: error_code.h:46
DllImport char * optarg
void * DSO_HANDLE
Definition: utility.h:706
int utility_index
Definition: utility.h:788
#define TDE_DBA_PASSWORD_S
Definition: utility.h:1621
int utility_load_symbol(DSO_HANDLE library_handle, DSO_HANDLE *symbol_handle, const char *symbol_name)
Definition: util_support.c:115
union UTIL_ARG_MAP::@81 value_info
int argc
Definition: dynamic_load.c:951
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
GETOPT_LONG * getopt_long
Definition: utility.h:793
#define ER_FAILED
Definition: error_code.h:47
int need_args_num
Definition: utility.h:790
union UTIL_ARG_MAP::@82 arg_value
void util_hide_password(char *arg)
Definition: util_support.c:374
int getopt_long(int, char *const *, const char *, const struct option *, int *)
INT64 l
Definition: utility.h:782
void utility_load_print_error(FILE *fp)
Definition: util_support.c:134
#define UTILITY_INIT_FUNC_NAME
Definition: utility.h:1641
int utility_load_library(DSO_HANDLE *handle, const char *path)
Definition: util_support.c:77
int value_type
Definition: utility.h:775
#define ER_GENERIC_ERROR
Definition: error_code.h:49
const char * name
Definition: cubrid_getopt.h:56
#define NULL
Definition: freelistheap.h:34
int(* UTILITY_INIT_FUNC)(void)
Definition: utility.h:1644
char * utility_make_getopt_optstring(const GETOPT_LONG *opt_array, char *buf)
Definition: util_support.c:49
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
int util_parse_argument(UTIL_MAP *util_map, int argc, char **argv)
Definition: util_support.c:186
static void error(const char *msg)
Definition: gencat.c:331
static int util_parse_string_table(UTIL_MAP *util_map, int index, int count, char **argv)
Definition: util_support.c:324
const char ** argv
Definition: dynamic_load.c:952
#define strlen(s1)
Definition: intl_support.c:43
#define KILLTRAN_DBA_PASSWORD_S
Definition: utility.h:1224
#define LOAD_PASSWORD_S
Definition: utility.h:1236
static const char * util_get_option_name(GETOPT_LONG *option, int option_value)
Definition: util_support.c:162
int i
Definition: dynamic_load.c:954
void * p
Definition: utility.h:780
char * strdup(const char *str)
Definition: porting.c:901
int parse_bigint(INT64 *ret_p, const char *str_p, int base)
Definition: porting.c:2318
#define OPTION_STRING_TABLE
Definition: utility.h:813
int has_arg
Definition: cubrid_getopt.h:61
Definition: utility.h:751
#define UNLOAD_PASSWORD_S
Definition: utility.h:1312
UTIL_ARG_MAP * arg_map
Definition: utility.h:794
static int util_put_option_value(UTIL_MAP *util_map, int arg_ch, const char *option_arg)
Definition: util_support.c:256
static bool util_is_password_argument(int index, int value)
Definition: util_support.c:233
int arg_ch
Definition: utility.h:772
int num_strings
Definition: utility.h:776
const char ** p
Definition: dynamic_load.c:945