1 /*
2    Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
23 
24 /*
25   Return error-text for NDB error messages in same
26   fashion as "perror --ndb <error>"
27 */
28 
29 #include "ndb_global.h"
30 #include "ndb_opts.h"
31 
32 #include "ndbapi/ndberror.h"
33 #include "mgmapi/ndbd_exit_codes.h"
34 #include "mgmapi/mgmapi_error.h"
35 #include "my_alloc.h"
36 
37 static bool opt_verbose;
38 static bool opt_silent; // Overrides verbose and sets it to 0
39 
40 static struct my_option my_long_options[] =
41 {
42   {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG,
43    NO_ARG, 0, 0, 0, 0, 0, 0},
44   {"ndb", NDB_OPT_NOSHORT,
45    "For command line compatibility with 'perror --ndb', ignored.", 0,
46    0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
47   {"silent", 's', "Only print the error message.", &opt_silent,
48    &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
49   {"verbose", 'v', "Print error code and message (default).", &opt_verbose,
50    &opt_verbose, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
51   {"version", 'V', "Displays version information and exits.",
52    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
53   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
54 };
55 
56 const char *load_default_groups[] = { 0 };
57 
short_usage_sub(void)58 static void short_usage_sub(void)
59 {
60   ndb_short_usage_sub("[ERRORCODE [ERRORCODE...]]");
61 }
62 
63 
64 static
mgmapi_error_string(int err_no,char * str,int size)65 int mgmapi_error_string(int err_no, char *str, int size)
66 {
67   for (int i = 0; i < ndb_mgm_noOfErrorMsgs; i++)
68   {
69     if ((int)ndb_mgm_error_msgs[i].code == err_no)
70     {
71       snprintf(str, size - 1, "%s", ndb_mgm_error_msgs[i].msg);
72       str[size - 1] = '\0';
73       return 1; // Found a message
74     }
75   }
76   return -1;
77 }
78 
79 
80 // Forward declare function from ndbd_exit_codes.cc which is not
81 // declared in any header
82 int ndbd_exit_string(int err_no, char *str, unsigned int size);
83 
84 
main(int argc,char ** argv)85 int main(int argc, char** argv)
86 {
87   NDB_INIT(argv[0]);
88   Ndb_opts opts(argc, argv, my_long_options, load_default_groups);
89   opts.set_usage_funcs(short_usage_sub);
90 
91   if (opts.handle_options() != 0)
92     exit(255);
93 
94   if (opt_silent)
95   {
96     // --silent overrides any verbose setting
97     opt_verbose = 0;
98   }
99 
100   if (!argc)
101   {
102     opts.usage();
103     exit(1);
104   }
105 
106   int error = 0;
107   for ( ; argc-- > 0 ; argv++)
108   {
109     int code=atoi(*argv);
110 
111     char error_string[1024];
112     if ((ndb_error_string(code, error_string, sizeof(error_string)) > 0) ||
113         (ndbd_exit_string(code, error_string, sizeof(error_string)) > 0) ||
114         (mgmapi_error_string(code, error_string, sizeof(error_string)) > 0))
115     {
116       if (opt_verbose)
117         printf("NDB error code %3d: %s\n", code, error_string);
118       else
119         puts(error_string);
120     }
121     else
122     {
123       fprintf(stderr, "Illegal ndb error code: %d\n", code);
124       error= 1;
125     }
126   }
127 
128   exit(error);
129   return error;
130 }
131