Source File modules/pc/pc_commands.c

    1    | #include "mysql_driver.h"
    2    | #include "access_control.h"
    3    | #include "thread.h"
    4    | #include "constants.h"
    5    | #include "properties.h"
    6    | #include "protocol_config.h"
    7    | #include "protocol_whois.h"
    8    | #include "ta.h"
    9    | #include "pc_commands.h"
    10   |
    11   | #include "er_paths.h"
    12   | #include "er_macro.h"
    13   |
    14   | /* this is for purify - to display the memory allocation records */
    15   | extern void purify_new_inuse(void);
    16   |
    17   |
    18   |
    19   | /*++++++++++++++++++++++++++++++++++++++
    20   |
    21   |   All functions in this file share the same interface: they take the
    22   |   arguments to the command given by the user, pointer to a dynamic
    23   |   GString to which the command output should be appended and the
    24   |   connection data, so that some things can be displayed directly to it,
    25   |   bypassing the GString.
    26   |
    27   |   int <command_something>     return code. 0 indicates success.
    28   |                               PC_RET_QUIT is a reserved code
    29   |                               that indicates that the connection
    30   | 			      should be closed.
    31   |
    32   |   char *input                 command arguments
    33   |
    34   |   GString *output             (dynamic) output string
    35   |
    36   |   sk_conn_st *condat          connection data
    37   |
    38   |   ++++++++++++++++++++++++++++++++++++++*/
    39   |
    40   | /*++++++++++++++++++++++++++++++++++++++
    41   |
    42   |   Relay functions for composed commands (eg. "set counter").
    43   |
    44   |   They run the second word as a command from a specific array
    45   |   (show/set/stop/whatever). The hardcoded text is used only for help
    46   |   messages, printed in case the command is wrong as
    47   |
    48   |  "<hardcoded> commands are: <list of possible commands>".
    49   |
    50   |  ++++++++++++++++++++++++++++++++++++++*/
    51   | int command_show(char *input, GString *output, sk_conn_st *condat) {
    52   |   return command_execute(show, "show ", input, output, condat);
    53   | }
    54   |
    55   | int command_set( char *input, GString *output, sk_conn_st *condat) {
    56   |   return command_execute(set,  "set ",  input, output, condat);
    57   | }
    58   |
    59   | int command_stop(char *input, GString *output, sk_conn_st *condat) {
    60   |   return command_execute(stop, "stop ", input, output, condat);
    61   | }
    62   |
    63   |
    64   | /*++++++++++++++++++++++++++++++++++++++
    65   |
    66   |   Display available commands.
    67   |
    68   |   ++++++++++++++++++++++++++++++++++++++*/
    69   | int command_help(char *input, GString *output, sk_conn_st *condat)
    70   | {
    71   |   /* by the time it came here, the "help" bit is already taken away. */
    72   |   return show_commands(command, "", output);
    73   |
    74   | }
    75   |
    76   |
    77   | /*++++++++++++++++++++++++++++++++++++++
    78   |
    79   |   Quit the config session.
    80   |
    81   |   ++++++++++++++++++++++++++++++++++++++*/
    82   | int command_quit(char *input, GString *output, sk_conn_st *condat) {
    83   |     /* Administrator wishes to quit. */
    84   |   return PC_RET_QUIT;
    85   | } /* command_quit() */
    86   |
    87   | /*++++++++++++++++++++++++++++++++++++++
    88   |
    89   |   Display the memory allocation records of purify(tm).
    90   |   The #define must be changed to activate this.
    91   |   The program will link only with purify.
    92   |
    93   |   ++++++++++++++++++++++++++++++++++++++*/
    94   | int command_purify(char *input, GString *output, sk_conn_st *condat)
    95   | {
    96   | #if 0
    97   |   purify_new_inuse();
    98   | #else
    99   |   g_string_append(output, "NOP");
    100  | #endif
    101  |
    102  |   return 0;
    103  | }
    104  |
    105  |
    106  | /*++++++++++++++++++++++++++++++++++++++
    107  |
    108  |   Display a specific constant of the CO module.
    109  |
    110  |   Argument: name of the constant.
    111  |
    112  |   ++++++++++++++++++++++++++++++++++++++*/
    113  | int show_const(char *input, GString *output, sk_conn_st *condat) {
    114  |   /* Administrator wishes to show constants. */
    115  |   char *result, *name, *cursor;
    116  |   int res = 0;
    117  |
    118  |   if( strlen(input) > 0 ) {
    119  |     cursor = input;
    120  |     name = (char *)strsep(&cursor, " ");
    121  |
    122  |     if( (result = CO_const_to_string(name)) != NULL ) {
    123  |       g_string_append(output, result);
    124  |       wr_free(result);
    125  |     }
    126  |     else {
    127  |       g_string_append(output,  "unknown constant");
    128  |       res = PC_RET_ERR;
    129  |     }
    130  |   }
    131  |   else {
    132  |     g_string_append(output,  "name required");
    133  |     res = PC_RET_ERR;
    134  |   }
    135  |
    136  |   return res;
    137  |
    138  | } /* show_const() */
    139  |
    140  |
    141  | /*++++++++++++++++++++++++++++++++++++++
    142  |
    143  |   Display all the constants of the CO module.
    144  |
    145  |   ++++++++++++++++++++++++++++++++++++++*/
    146  | int show_consts(char *input, GString *output, sk_conn_st *condat)
    147  | {
    148  |   /* Administrator wishes to show constants. */
    149  |   char *s =  CO_to_string();
    150  |   g_string_append(output, s);
    151  |   free(s);
    152  |   return 0;
    153  | } /* show_consts() */
    154  |
    155  |
    156  | /*++++++++++++++++++++++++++++++++++++++
    157  |
    158  |   Display all the properties of the PR module.
    159  |
    160  |   ++++++++++++++++++++++++++++++++++++++*/
    161  | int show_props(char *input, GString *output, sk_conn_st *condat)
    162  | {
    163  |   /* Administrator wishes to show properties. */
    164  |   char *s =  PR_to_string();
    165  |   g_string_append(output, s);
    166  |   free(s);
    167  |   return 0;
    168  | } /* show_props() */
    169  |
    170  |
    171  | /*++++++++++++++++++++++++++++++++++++++
    172  |
    173  |   Display all running threads registered with the TA module.
    174  |
    175  |   ++++++++++++++++++++++++++++++++++++++*/
    176  | int show_threads(char *input, GString *output, sk_conn_st *condat)
    177  | {
    178  |   /* Administrator wishes to show thread information. */
    179  |   char *s = TA_tostring();
    180  |   g_string_append(output, s);
    181  |   free(s);
    182  |   return 0;
    183  | } /* show_thread() */
    184  |
    185  |
    186  | /*++++++++++++++++++++++++++++++++++++++
    187  |
    188  |   Switch the session to a whois session.
    189  |
    190  |   ++++++++++++++++++++++++++++++++++++++*/
    191  | int show_whois(char *input, GString *output, sk_conn_st *condat)
    192  | {
    193  |   /*  Go to whois mode */
    194  |   PW_interact(condat->sock);
    195  |   return 0;
    196  | } /* show_whois() */
    197  |
    198  |
    199  | /*++++++++++++++++++++++++++++++++++++++
    200  |
    201  |   Display the statistics about the server.
    202  |
    203  |   ++++++++++++++++++++++++++++++++++++++*/
    204  | int show_uptime(char *input, GString *output, sk_conn_st *condat)
    205  | {
    206  |   char timestring[26];
    207  |   extern time_t SV_starttime;
    208  |
    209  |   ctime_r(&SV_starttime, timestring);
    210  |   SK_cd_printf( condat,
    211  | 	       "System running since %sUptime in seconds: %ld \n\n",
    212  | 	       timestring,
    213  | 	       time(NULL) - SV_starttime);
    214  |
    215  |   return 0;
    216  | }
    217  |
    218  | /*++++++++++++++++++++++++++++++++++++++
    219  |
    220  |   Display the whois access statistics from the AC module.
    221  |
    222  |   ++++++++++++++++++++++++++++++++++++++*/
    223  | int show_access(char *input, GString *output, sk_conn_st *condat)
    224  | {
    225  |   int cnt = AC_print_access(output);
    226  |
    227  |   g_string_sprintfa(output, "Found %d nodes\n", cnt);
    228  |
    229  |   return 0;
    230  | } /* show_access() */
    231  |
    232  |
    233  | /*++++++++++++++++++++++++++++++++++++++
    234  |
    235  |   Display the whois access control list from the AC module.
    236  |
    237  |   ++++++++++++++++++++++++++++++++++++++*/
    238  | int show_acl(char *input, GString *output, sk_conn_st *condat)
    239  | {
    240  |   int cnt = AC_print_acl(output);
    241  |
    242  |   g_string_sprintfa(output, "Found %d nodes\n", cnt);
    243  |
    244  |   return 0;
    245  | } /* show_acl() */
    246  |
    247  |
    248  | /*++++++++++++++++++++++++++++++++++++++
    249  |
    250  |   Modify the whois access control list in the AC module.
    251  |
    252  |   Arguments: IP[/prefixlength] column=value,column=value...
    253  |
    254  |   Column names as in acl display. Unset columns are inherited.
    255  |
    256  |   ++++++++++++++++++++++++++++++++++++++*/
    257  | int set_acl(char *input, GString *output, sk_conn_st *condat)
    258  | {
    259  |   int res = 0;
    260  |
    261  |   /* first 8 characters ("set acl ") are already skipped */
    262  |   if( ! NOERR( AC_asc_acl_command_set( input, "Manual"))) {
    263  |     g_string_append(output, "Error!\n");
    264  |     res = PC_RET_ERR;
    265  |   }
    266  |   return res;
    267  | }
    268  |
    269  | /*++++++++++++++++++++++++++++++++++++++
    270  |
    271  |   Reset the deny counter in the access tree to 0 (after reenabling)
    272  |   (AC module).
    273  |
    274  |   Argument: IP address.
    275  |
    276  |   ++++++++++++++++++++++++++++++++++++++*/
    277  | int set_nodeny(char *input, GString *output, sk_conn_st *condat) {
    278  |
    279  |   /* first 11 characters ("set nodeny ")  are already skipped */
    280  |
    281  |   if( ! NOERR( AC_asc_set_nodeny(input) )) {
    282  |     g_string_append(output, "Error\n");
    283  |     return PC_RET_ERR;
    284  |   }
    285  |   else {
    286  |     return 0;
    287  |   }
    288  |
    289  | } /* set_nodeny() */
    290  |
    291  |
    292  | /*++++++++++++++++++++++++++++++++++++++
    293  |
    294  |   Pause/resume update capability of the UD module.
    295  |
    296  |   Argument: the word "pause" or "resume".
    297  |
    298  |   ++++++++++++++++++++++++++++++++++++++*/
    299  | int set_updates(char *input, GString *output, sk_conn_st *condat)
    300  | {
    301  |   char argstr[17];
    302  |   int pause=0, resume=0;
    303  |   int res = 0;
    304  |
    305  |   if( sscanf(input, "%16s", argstr) == 1) {
    306  |     pause = (strcmp(argstr,"pause") == 0);
    307  |     resume = (strcmp(argstr,"resume") == 0);
    308  |   }
    309  |
    310  |   if( !pause && !resume ) {
    311  |     g_string_append(output,  "syntax error.");
    312  |     res = PC_RET_ERR;
    313  |   }
    314  |   else {
    315  |     /* all params ok. just set the property */
    316  |     char *value = pause ? "0" : "1";
    317  |
    318  |     if (CO_set_const("UD.do_update", value) == 0) {
    319  |       g_string_append(output, "Constant successfully set\n");
    320  |     }
    321  |     else {
    322  |       g_string_append(output, "Could not set\n");
    323  |       res = PC_RET_ERR;
    324  |     }
    325  |   }
    326  |   return res;
    327  | }
    328  |
    329  |
    330  | /*++++++++++++++++++++++++++++++++++++++
    331  |
    332  |   Reset the "session time" and "# of tasks"
    333  |   of a specific thread registered with the TA module.
    334  |
    335  |   ++++++++++++++++++++++++++++++++++++++*/
    336  | int set_counter(char *input, GString *output, sk_conn_st *condat)
    337  | {
    338  |   unsigned thr_id;
    339  |
    340  |   if( sscanf(input, "%d", &thr_id) == 1) {
    341  |     TA_reset_counters(thr_id);
    342  |   }
    343  |   return 0;
    344  | }
    345  |
    346  |
    347  |
    348  | /*++++++++++++++++++++++++++++++++++++++
    349  |
    350  |   Execute a command in the ER path processor of the ER module.
    351  |   (first subject to macro expansion of the first word).
    352  |
    353  |   Argument is passed entirely to ER_macro_spec().
    354  |
    355  |   ++++++++++++++++++++++++++++++++++++++*/
    356  | int set_err(char *input, GString *output, sk_conn_st *condat)
    357  | {
    358  |   char *erret = NULL;
    359  |   int res;
    360  |
    361  |   res = ER_macro_spec(input, &erret);
    362  |   g_string_append(output, erret);
    363  |   free(erret);
    364  |
    365  |   return res;
    366  | }
    367  |
    368  |
    369  | /*++++++++++++++++++++++++++++++++++++++
    370  |
    371  |   Show the current setup of the ER path system of the ER module.
    372  |
    373  |   ++++++++++++++++++++++++++++++++++++++*/
    374  | int show_err(char *input, GString *output, sk_conn_st *condat)
    375  | {
    376  |   char *erret = NULL;
    377  |
    378  |   er_print_paths(&erret);
    379  |   g_string_append(output, erret);
    380  |   free(erret);
    381  |
    382  |   return 0;
    383  | }
    384  |
    385  |
    386  | /*++++++++++++++++++++++++++++++++++++++
    387  |
    388  |   Show the currently defined macros for the ER path system of the ER module.
    389  |
    390  |   ++++++++++++++++++++++++++++++++++++++*/
    391  | int show_macros(char *input, GString *output, sk_conn_st *condat)
    392  | {
    393  |   ER_macro_list(condat);
    394  |   return 0;
    395  | }
    396  |
    397  |
    398  |
    399  | /*++++++++++++++++++++++++++++++++++++++
    400  |
    401  |   (re)define a macro for the ER path processor.
    402  |
    403  |   Arguments: The first word is treated as a macro name.
    404  |   The rest of the line is treated as a macro definition.
    405  |
    406  |   ++++++++++++++++++++++++++++++++++++++*/
    407  | int set_macro(char *input, GString *output, sk_conn_st *condat)
    408  | {
    409  |   char *name, *body;
    410  |
    411  |   if( strlen(input) > 0 ) {
    412  |     body = input;
    413  |     name = (char *)strsep(&body, " ");
    414  |
    415  |     ER_make_macro( name, body );
    416  |   }
    417  |
    418  |   return 0;
    419  | }
    420  |
    421  |
    422  |
    423  |
    424  | /*++++++++++++++++++++++++++++++++++++++
    425  |
    426  |   Trigger running of the socket watchdog actions for a specific thread
    427  |   (typically resulting in shutting down of a query thread).
    428  |
    429  |   Arguments are "<socket_id> <thread_id>" as in the output of "show threads".
    430  |
    431  |   Assumes the command is like "stop query 11 17".
    432  |   This is to limit ambiguities (a new thread on the same socket, for example).
    433  | .
    434  |   ++++++++++++++++++++++++++++++++++++++*/
    435  | int stop_query(char *input, GString *output, sk_conn_st *condat)
    436  | {
    437  |   int fd;
    438  |   unsigned thr;
    439  |
    440  |
    441  |   if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) {
    442  |     g_string_append(output,"error!!");
    443  |     return PC_RET_ERR;
    444  |   }
    445  |   else {
    446  |     TA_trigger("whois", fd, thr);
    447  |     return 0;
    448  |   }
    449  | }