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