CUBRID Engine  latest
csql_launcher.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  * csql_launcher.c : csql invocation program
21  */
22 
23 #ident "$Id$"
24 
25 #include <stdio.h>
26 #include <stdarg.h>
27 
28 #include "csql.h"
29 #include "message_catalog.h"
30 #include "environment_variable.h"
31 #include "intl_support.h"
32 #include "utility.h"
33 #include "util_support.h"
34 #include "cubrid_getopt.h"
35 
36 typedef const char *(*CSQL_GET_MESSAGE) (int message_index);
37 typedef int (*CSQL) (const char *argv0, CSQL_ARGUMENT * csql_arg);
38 
39 static void utility_csql_usage (void);
40 static void utility_csql_print (void);
41 
42 /*
43  * utility_csql_usage() - display csql usage
44  */
45 static void
47 {
48  DSO_HANDLE util_sa_library;
50  const char *message;
51 
52  utility_load_library (&util_sa_library, LIB_UTIL_SA_NAME);
53  if (util_sa_library == NULL)
54  {
55  utility_load_print_error (stderr);
56  return;
57  }
58  utility_load_symbol (util_sa_library, (DSO_HANDLE *) (&csql_get_message), "csql_get_message");
59  if (csql_get_message == NULL)
60  {
61  utility_load_print_error (stderr);
62  return;
63  }
64  message = (*csql_get_message) (CSQL_MSG_USAGE);
65  fprintf (stderr, message, PRODUCT_STRING, UTIL_CSQL_NAME);
66 }
67 
68 /*
69  * utility_csql_print - display a version of this utility
70  *
71  * return:
72  *
73  * NOTE:
74  */
75 static void
76 utility_csql_print (int message_num, ...)
77 {
78  typedef const char *(*GET_MESSAGE) (int message_index);
79 
80  DSO_HANDLE util_sa_library;
82  GET_MESSAGE get_message_fn;
83 
84  utility_load_library (&util_sa_library, LIB_UTIL_SA_NAME);
85  if (util_sa_library == NULL)
86  {
87  utility_load_print_error (stderr);
88  return;
89  }
90  utility_load_symbol (util_sa_library, &symbol, UTILITY_GENERIC_MSG_FUNC_NAME);
91  if (symbol == NULL)
92  {
93  utility_load_print_error (stderr);
94  return;
95  }
96 
97  get_message_fn = (GET_MESSAGE) symbol;
98 
99  {
100  va_list ap;
101 
102  va_start (ap, message_num);
103  vfprintf (stderr, get_message_fn (message_num), ap);
104  va_end (ap);
105  }
106 }
107 
108 /*
109  * main() - csql main module.
110  * return: no return if no error,
111  * EXIT_FAILURE otherwise.
112  */
113 int
114 main (int argc, char *argv[])
115 {
116  char option_string[64];
117  int error = 0;
118  CSQL_ARGUMENT csql_arg;
119  DSO_HANDLE util_library;
120  CSQL csql;
121  int check_output_style = 0;
122  bool explicit_single_line = false;
123 
124  GETOPT_LONG csql_option[] = {
127  {CSQL_USER_L, 1, 0, CSQL_USER_S},
139  {CSQL_SYSADM_L, 0, 0, CSQL_SYSADM_S},
150  {VERSION_L, 0, 0, VERSION_S},
151  {0, 0, 0, 0}
152  };
153 
154  memset (&csql_arg, 0, sizeof (CSQL_ARGUMENT));
155  csql_arg.auto_commit = true;
156  csql_arg.single_line_execution = true;
157  csql_arg.string_width = 0;
158  csql_arg.trigger_action_flag = true;
159  csql_arg.plain_output = false;
160  csql_arg.query_output = false;
161  csql_arg.loaddb_output = false;
162  csql_arg.column_delimiter = -1;
163  csql_arg.column_enclosure = -1;
164  utility_make_getopt_optstring (csql_option, option_string);
165 
166  while (1)
167  {
168  int option_index = 0;
169  int option_key;
170 
171  option_key = getopt_long (argc, argv, option_string, csql_option, &option_index);
172  if (option_key == -1)
173  {
174  break;
175  }
176 
177  switch (option_key)
178  {
179  case CSQL_SA_MODE_S:
180  csql_arg.sa_mode = true;
181  break;
182 
183  case CSQL_CS_MODE_S:
184  csql_arg.cs_mode = true;
185  break;
186 
187  case CSQL_USER_S:
188  if (csql_arg.user_name != NULL)
189  {
190  free ((void *) csql_arg.user_name);
191  }
192  csql_arg.user_name = strdup (optarg);
193  break;
194 
195  case CSQL_PASSWORD_S:
196  if (csql_arg.passwd != NULL)
197  {
198  free ((void *) csql_arg.passwd);
199  }
200  csql_arg.passwd = strdup (optarg);
202  break;
203 
205  csql_arg.continue_on_error = true;
206  break;
207 
208  case CSQL_INPUT_FILE_S:
209  if (csql_arg.in_file_name != NULL)
210  {
211  free ((void *) csql_arg.in_file_name);
212  }
213  csql_arg.in_file_name = strdup (optarg);
214  break;
215 
216  case CSQL_OUTPUT_FILE_S:
217  if (csql_arg.out_file_name != NULL)
218  {
219  free ((void *) csql_arg.out_file_name);
220  }
221  csql_arg.out_file_name = strdup (optarg);
222  break;
223 
224  case CSQL_SINGLE_LINE_S:
225  explicit_single_line = true;
226  break;
227 
229  csql_arg.single_line_execution = false;
230  break;
231 
232  case CSQL_COMMAND_S:
233  if (csql_arg.command != NULL)
234  {
235  free ((void *) csql_arg.command);
236  }
237  csql_arg.command = strdup (optarg);
238  break;
239 
240  case CSQL_LINE_OUTPUT_S:
241  csql_arg.line_output = true;
242  break;
243 
244  case CSQL_READ_ONLY_S:
245  csql_arg.read_only = true;
246  break;
247 
249  csql_arg.auto_commit = false;
250  break;
251 
252  case CSQL_NO_PAGER_S:
253  csql_arg.nopager = true;
254  break;
255 
256  case CSQL_SYSADM_S:
257  csql_arg.sysadm = true;
258  break;
259 
261  csql_arg.write_on_standby = true;
262  break;
263 
264  case CSQL_STRING_WIDTH_S:
265  {
266  int string_width = 0, result;
267 
268  result = parse_int (&string_width, optarg, 10);
269 
270  if (result != 0 || string_width < 0)
271  {
272  goto print_usage;
273  }
274 
275  csql_arg.string_width = string_width;
276  }
277  break;
278 
280  csql_arg.trigger_action_flag = false;
281  break;
282 
283  case CSQL_PLAIN_OUTPUT_S:
284  csql_arg.plain_output = true;
285  break;
286 
288  csql_arg.skip_column_names = true;
289  break;
290 
291  case CSQL_SKIP_VACUUM_S:
292  csql_arg.skip_vacuum = true;
293  break;
294 
295  case CSQL_QUERY_OUTPUT_S:
296  csql_arg.query_output = true;
297  break;
298 
300  {
301  int len = strlen (optarg);
302 
303  if (len == 1)
304  {
305  csql_arg.column_delimiter = optarg[0];
306  }
307  else if (len >= 2 && optarg[0] == '\\')
308  {
309  if (optarg[1] == 't')
310  {
311  csql_arg.column_delimiter = '\t';
312  }
313  else if (optarg[1] == 'n')
314  {
315  csql_arg.column_delimiter = '\n';
316  }
317  else
318  {
319  csql_arg.column_delimiter = optarg[1];
320  }
321  }
322  else
323  {
324  csql_arg.column_delimiter = ',';
325  }
326  }
327  break;
328 
330  if (strlen (optarg) >= 1)
331  {
332  csql_arg.column_enclosure = optarg[0];
333  }
334  else
335  {
336  csql_arg.column_enclosure = '\'';
337  }
338  break;
339 
341  csql_arg.loaddb_output = true;
342  break;
343 
344  case VERSION_S:
346  goto exit_on_end;
347 
348  default:
349  goto print_usage;
350  }
351  }
352 
353  if (argc - optind == 1)
354  {
355  csql_arg.db_name = argv[optind];
356  }
357  else if (argc > optind)
358  {
360  goto print_usage;
361  }
362  else
363  {
365  goto print_usage;
366  }
367 
368  if ((csql_arg.command == NULL && csql_arg.in_file_name == NULL) || csql_arg.line_output == true)
369  {
370  csql_arg.skip_column_names = false;
371  csql_arg.plain_output = false;
372  csql_arg.query_output = false;
373  csql_arg.loaddb_output = false;
374  }
375 
376  if (csql_arg.plain_output == true)
377  {
378  check_output_style++;
379  }
380 
381  if (csql_arg.query_output == true)
382  {
383  if (csql_arg.column_delimiter == -1)
384  {
385  csql_arg.column_delimiter = ',';
386  }
387 
388  if (csql_arg.column_enclosure == -1)
389  {
390  csql_arg.column_enclosure = '\'';
391  }
392  check_output_style++;
393  }
394  else if (csql_arg.column_delimiter != -1 || csql_arg.column_enclosure != -1)
395  {
396  /* delimiter and enclosure can only use with query_output option */
397  goto print_usage;
398  }
399 
400  if (csql_arg.loaddb_output == true)
401  {
402  csql_arg.column_delimiter = ' ';
403  csql_arg.column_enclosure = '\'';
404  check_output_style++;
405  }
406 
407  if (check_output_style > 1)
408  {
409  /* can't use -p, -q, and --loaddb-output together */
410  goto print_usage;
411  }
412 
413  if (csql_arg.sysadm && (csql_arg.user_name == NULL || strcasecmp (csql_arg.user_name, "DBA")))
414  {
415  /* sysadm is allowed only to DBA */
416  goto print_usage;
417  }
418 
419  if (csql_arg.sysadm == false && csql_arg.write_on_standby == true)
420  {
421  /* write_on_standby must come with sysadm */
422  goto print_usage;
423  }
424 
425  if (csql_arg.sa_mode && (csql_arg.cs_mode || csql_arg.write_on_standby))
426  {
427  /* Don't allow both at once. */
428  goto print_usage;
429  }
430  else if (!csql_arg.sa_mode && csql_arg.skip_vacuum)
431  {
432  /* Don't allow to skip vacuum on CS mode */
433  goto print_usage;
434  }
435  else if (explicit_single_line && csql_arg.single_line_execution == false)
436  {
437  /* Don't allow both at once. */
438  goto print_usage;
439  }
440  else if (csql_arg.sa_mode)
441  {
442  utility_load_library (&util_library, LIB_UTIL_SA_NAME);
443  }
444  else
445  {
446  utility_load_library (&util_library, LIB_UTIL_CS_NAME);
447  }
448 
449  if (util_library == NULL)
450  {
451  utility_load_print_error (stderr);
452  goto exit_on_error;
453  }
454 
455  utility_load_symbol (util_library, (DSO_HANDLE *) (&csql), "csql");
456  if (csql == NULL)
457  {
458  utility_load_print_error (stderr);
459  goto exit_on_error;
460  }
461 
462  error = (*csql) (argv[0], &csql_arg);
463 
464 exit_on_end:
465  if (csql_arg.user_name != NULL)
466  {
467  free ((void *) csql_arg.user_name);
468  }
469  if (csql_arg.passwd != NULL)
470  {
471  free ((void *) csql_arg.passwd);
472  }
473  if (csql_arg.in_file_name != NULL)
474  {
475  free ((void *) csql_arg.in_file_name);
476  }
477  if (csql_arg.out_file_name != NULL)
478  {
479  free ((void *) csql_arg.out_file_name);
480  }
481  if (csql_arg.command != NULL)
482  {
483  free ((void *) csql_arg.command);
484  }
485 
486  return error;
487 
490  error = EXIT_FAILURE;
491  goto exit_on_end;
492 
493 exit_on_error:
494  error = ER_GENERIC_ERROR;
495  goto exit_on_end;
496 }
DllImport int optind
const char * csql_get_message(int message_index)
Definition: csql.c:2954
static void utility_csql_usage(void)
Definition: csql_launcher.c:46
#define CSQL_INPUT_FILE_S
Definition: utility.h:1348
bool auto_commit
Definition: csql.h:268
#define CSQL_SKIP_VACUUM_L
Definition: utility.h:1379
DllImport char * optarg
void * DSO_HANDLE
Definition: utility.h:706
#define CSQL_NO_TRIGGER_ACTION_L
Definition: utility.h:1373
bool line_output
Definition: csql.h:266
int string_width
Definition: csql.h:277
#define CSQL_LINE_OUTPUT_L
Definition: utility.h:1357
#define CSQL_CS_MODE_S
Definition: utility.h:1340
int utility_load_symbol(DSO_HANDLE library_handle, DSO_HANDLE *symbol_handle, const char *symbol_name)
Definition: util_support.c:115
#define CSQL_CS_MODE_L
Definition: utility.h:1341
int argc
Definition: dynamic_load.c:951
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
#define CSQL_NO_SINGLE_LINE_L
Definition: utility.h:1367
#define CSQL_OUTPUT_FILE_S
Definition: utility.h:1350
#define LIB_UTIL_SA_NAME
Definition: utility.h:1637
void util_hide_password(char *arg)
Definition: util_support.c:374
#define CSQL_OUTPUT_FILE_L
Definition: utility.h:1351
#define CSQL_NO_AUTO_COMMIT_S
Definition: utility.h:1360
bool read_only
Definition: csql.h:267
char column_enclosure
Definition: csql.h:280
#define CSQL_NO_AUTO_COMMIT_L
Definition: utility.h:1361
int getopt_long(int, char *const *, const char *, const struct option *, int *)
void utility_load_print_error(FILE *fp)
Definition: util_support.c:134
#define CSQL_PASSWORD_L
Definition: utility.h:1345
#define CSQL_INPUT_FILE_L
Definition: utility.h:1349
const char * db_name
Definition: csql.h:256
static void utility_csql_print(void)
bool trigger_action_flag
Definition: csql.h:273
#define CSQL_SYSADM_L
Definition: utility.h:1365
#define UTIL_CSQL_NAME
Definition: utility.h:834
int utility_load_library(DSO_HANDLE *handle, const char *path)
Definition: util_support.c:77
bool plain_output
Definition: csql.h:274
#define ER_GENERIC_ERROR
Definition: error_code.h:49
int(* CSQL)(const char *argv0, CSQL_ARGUMENT *csql_arg)
Definition: csql_launcher.c:37
const char * passwd
Definition: csql.h:258
int main(int argc, char *argv[])
bool write_on_standby
Definition: csql.h:272
const char * command
Definition: csql.h:261
#define CSQL_LINE_OUTPUT_S
Definition: utility.h:1356
bool sa_mode
Definition: csql.h:262
#define VERSION_L
Definition: utility.h:1556
#define CSQL_WRITE_ON_STANDBY_S
Definition: utility.h:1370
#define CSQL_SINGLE_LINE_L
Definition: utility.h:1353
const char * out_file_name
Definition: csql.h:260
#define CSQL_COMMAND_L
Definition: utility.h:1355
bool skip_column_names
Definition: csql.h:275
#define CSQL_QUERY_COLUMN_DELIMITER_L
Definition: utility.h:1383
#define CSQL_NO_SINGLE_LINE_S
Definition: utility.h:1366
#define CSQL_QUERY_COLUMN_ENCLOSURE_S
Definition: utility.h:1384
#define NULL
Definition: freelistheap.h:34
#define CSQL_COMMAND_S
Definition: utility.h:1354
#define CSQL_SKIP_VACUUM_S
Definition: utility.h:1378
bool query_output
Definition: csql.h:278
char * utility_make_getopt_optstring(const GETOPT_LONG *opt_array, char *buf)
Definition: util_support.c:49
#define CSQL_NO_TRIGGER_ACTION_S
Definition: utility.h:1372
bool loaddb_output
Definition: csql.h:281
#define CSQL_LOADDB_OUTPUT_L
Definition: utility.h:1387
#define CSQL_QUERY_COLUMN_ENCLOSURE_L
Definition: utility.h:1385
#define CSQL_QUERY_OUTPUT_L
Definition: utility.h:1381
bool continue_on_error
Definition: csql.h:270
#define CSQL_READ_ONLY_S
Definition: utility.h:1358
bool single_line_execution
Definition: csql.h:264
#define CSQL_PASSWORD_S
Definition: utility.h:1344
int csql(const char *argv0, CSQL_ARGUMENT *csql_arg)
Definition: csql.c:2703
#define CSQL_USER_L
Definition: utility.h:1343
const char *(* CSQL_GET_MESSAGE)(int message_index)
Definition: csql_launcher.c:36
#define CSQL_SINGLE_LINE_S
Definition: utility.h:1352
char column_delimiter
Definition: csql.h:279
static void error(const char *msg)
Definition: gencat.c:331
#define CSQL_LOADDB_OUTPUT_S
Definition: utility.h:1386
#define CSQL_PLAIN_OUTPUT_S
Definition: utility.h:1374
#define CSQL_ERROR_CONTINUE_S
Definition: utility.h:1346
#define CSQL_SKIP_COL_NAMES_L
Definition: utility.h:1377
const char ** argv
Definition: dynamic_load.c:952
#define CSQL_READ_ONLY_L
Definition: utility.h:1359
bool sysadm
Definition: csql.h:271
#define strlen(s1)
Definition: intl_support.c:43
static void print_usage(void)
#define CSQL_QUERY_COLUMN_DELIMITER_S
Definition: utility.h:1382
#define CSQL_SKIP_COL_NAMES_S
Definition: utility.h:1376
#define CSQL_STRING_WIDTH_S
Definition: utility.h:1368
#define CSQL_SA_MODE_L
Definition: utility.h:1339
#define CSQL_SA_MODE_S
Definition: utility.h:1338
#define CSQL_WRITE_ON_STANDBY_L
Definition: utility.h:1371
char * strdup(const char *str)
Definition: porting.c:901
#define CSQL_NO_PAGER_L
Definition: utility.h:1363
#define CSQL_SYSADM_S
Definition: utility.h:1364
bool cs_mode
Definition: csql.h:263
bool skip_vacuum
Definition: csql.h:276
#define CSQL_USER_S
Definition: utility.h:1342
bool nopager
Definition: csql.h:269
const char * user_name
Definition: csql.h:257
#define CSQL_STRING_WIDTH_L
Definition: utility.h:1369
const char * in_file_name
Definition: csql.h:259
#define LIB_UTIL_CS_NAME
Definition: utility.h:1636
#define CSQL_QUERY_OUTPUT_S
Definition: utility.h:1380
#define VERSION_S
Definition: utility.h:1555
#define UTILITY_GENERIC_MSG_FUNC_NAME
Definition: utility.h:1640
#define CSQL_ERROR_CONTINUE_L
Definition: utility.h:1347
#define CSQL_NO_PAGER_S
Definition: utility.h:1362
#define CSQL_PLAIN_OUTPUT_L
Definition: utility.h:1375