Source File pc/pc_commands.c

    1    | /******************
    2    |   Copyright (c) 1999,2000,2001,2002               RIPE NCC
    3    |
    4    |   All Rights Reserved
    5    |
    6    |   Permission to use, copy, modify, and distribute this software and its
    7    |   documentation for any purpose and without fee is hereby granted,
    8    |   provided that the above copyright notice appear in all copies and that
    9    |   both that copyright notice and this permission notice appear in
    10   |   supporting documentation, and that the name of the author not be
    11   |   used in advertising or publicity pertaining to distribution of the
    12   |   software without specific, written prior permission.
    13   |
    14   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    15   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    16   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    17   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    18   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    19   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    20   |   ***************************************/
    21   |
    22   | #include "rip.h"
    23   |
    24   | /* this is for purify - to display the memory allocation records */
    25   | extern void purify_new_inuse(void);
    26   |
    27   |
    28   | /*++++++++++++++++++++++++++++++++++++++
    29   |
    30   |   All functions in this file share the same interface: they take the
    31   |   arguments to the command given by the user, pointer to a dynamic
    32   |   GString to which the command output should be appended and the
    33   |   connection data, so that some things can be displayed directly to it,
    34   |   bypassing the GString.
    35   |
    36   |   int <command_something>     return code. 0 indicates success.
    37   |                               PC_RET_QUIT is a reserved code
    38   |                               that indicates that the connection
    39   | 			      should be closed.
    40   |
    41   |   char *input                 command arguments
    42   |
    43   |   GString *output             (dynamic) output string
    44   |
    45   |   sk_conn_st *condat          connection data
    46   |
    47   |   ++++++++++++++++++++++++++++++++++++++*/
    48   |
    49   | /*++++++++++++++++++++++++++++++++++++++
    50   |
    51   |   Relay functions for composed commands (eg. "set counter").
    52   |
    53   |   They run the second word as a command from a specific array
    54   |   (show/set/stop/whatever). The hardcoded text is used only for help
    55   |   messages, printed in case the command is wrong as
    56   |
    57   |  "<hardcoded> commands are: <list of possible commands>".
    58   |
    59   |  ++++++++++++++++++++++++++++++++++++++*/
    60   | int command_save(char *input, GString *output, sk_conn_st *condat) {
    61   |   return command_execute(save, "save ", input, output, condat);
    62   | }
    63   |
    64   | int command_show(char *input, GString *output, sk_conn_st *condat) {
    65   |   return command_execute(show, "show ", input, output, condat);
    66   | }
    67   |
    68   | int command_set( char *input, GString *output, sk_conn_st *condat) {
    69   |   return command_execute(set,  "set ",  input, output, condat);
    70   | }
    71   |
    72   | int command_stop(char *input, GString *output, sk_conn_st *condat) {
    73   |   return command_execute(stop, "stop ", input, output, condat);
    74   | }
    75   |
    76   |
    77   | /*++++++++++++++++++++++++++++++++++++++
    78   |
    79   |   Display available commands.
    80   |
    81   |   ++++++++++++++++++++++++++++++++++++++*/
    82   | int command_help(char *input, GString *output, sk_conn_st *condat)
    83   | {
    84   |   /* by the time it came here, the "help" bit is already taken away. */
    85   |   return show_commands(command, "", output);
    86   |
    87   | }
    88   |
    89   |
    90   | /*++++++++++++++++++++++++++++++++++++++
    91   |
    92   |   Quit the config session.
    93   |
    94   |   ++++++++++++++++++++++++++++++++++++++*/
    95   | int command_quit(char *input, GString *output, sk_conn_st *condat) {
    96   |     /* Administrator wishes to quit. */
    97   |   return PC_RET_QUIT;
    98   | } /* command_quit() */
    99   |
    100  | /*++++++++++++++++++++++++++++++++++++++
    101  |
    102  |   Display the memory allocation records of purify(tm).
    103  |   The #define must be changed to activate this.
    104  |   The program will link only with purify.
    105  |
    106  |   ++++++++++++++++++++++++++++++++++++++*/
    107  | int command_purify(char *input, GString *output, sk_conn_st *condat)
    108  | {
    109  | #if 0
    110  |   purify_new_inuse();
    111  | #else
    112  |   g_string_append(output, "NOP");
    113  | #endif
    114  |
    115  |   return 0;
    116  | }
    117  |
    118  | int save_access_tree(char *input, GString *output, sk_conn_st *condat) {
    119  |   er_ret_t ret_err;
    120  |
    121  |   ret_err = AC_persistence_save();
    122  |
    123  |   switch (ret_err) {
    124  |   case AC_OK:
    125  |     g_string_append(output, "Save successful");
    126  |     break;
    127  |   case AC_SAVING:
    128  |     g_string_append(output, "Already saving");
    129  |     break;
    130  |   default:
    131  |     g_string_append(output, "Unknown error");
    132  |     return PC_RET_ERR;
    133  |   }
    134  |   return 0;
    135  | }
    136  |
    137  | /*++++++++++++++++++++++++++++++++++++++
    138  |
    139  |   Display a specific constant of the CO module.
    140  |
    141  |   Argument: name of the constant.
    142  |
    143  |   ++++++++++++++++++++++++++++++++++++++*/
    144  | int show_const(char *input, GString *output, sk_conn_st *condat) {
    145  |   /* Administrator wishes to show constants. */
    146  |   char *result, *name, *cursor;
    147  |   int res = 0;
    148  |
    149  |   if( strlen(input) > 0 ) {
    150  |     cursor = input;
    151  |     name = (char *)strsep(&cursor, " ");
    152  |
    153  |     if( (result = CO_const_to_string(name)) != NULL ) {
    154  |       g_string_append(output, result);
    155  |       UT_free(result);
    156  |     }
    157  |     else {
    158  |       g_string_append(output,  "unknown constant");
    159  |       res = PC_RET_ERR;
    160  |     }
    161  |   }
    162  |   else {
    163  |     g_string_append(output,  "name required");
    164  |     res = PC_RET_ERR;
    165  |   }
    166  |
    167  |   return res;
    168  |
    169  | } /* show_const() */
    170  |
    171  |
    172  | /*++++++++++++++++++++++++++++++++++++++
    173  |
    174  |   Display all the constants of the CO module.
    175  |
    176  |   ++++++++++++++++++++++++++++++++++++++*/
    177  | int show_consts(char *input, GString *output, sk_conn_st *condat)
    178  | {
    179  |   /* Administrator wishes to show constants. */
    180  |   char *s =  CO_to_string();
    181  |   g_string_append(output, s);
    182  |   UT_free(s);
    183  |   return 0;
    184  | } /* show_consts() */
    185  |
    186  |
    187  | /*++++++++++++++++++++++++++++++++++++++
    188  |
    189  |   Display all the properties of the PR module.
    190  |
    191  |   ++++++++++++++++++++++++++++++++++++++*/
    192  | int show_props(char *input, GString *output, sk_conn_st *condat)
    193  | {
    194  |   /* Administrator wishes to show properties. */
    195  |   char *s =  PR_to_string();
    196  |   g_string_append(output, s);
    197  |   UT_free(s);
    198  |   return 0;
    199  | } /* show_props() */
    200  |
    201  |
    202  | /*++++++++++++++++++++++++++++++++++++++
    203  |
    204  |   Display all running threads registered with the TA module.
    205  |
    206  |   ++++++++++++++++++++++++++++++++++++++*/
    207  | int show_threads(char *input, GString *output, sk_conn_st *condat)
    208  | {
    209  |   /* Administrator wishes to show thread information. */
    210  |   char *s = TA_tostring();
    211  |   g_string_append(output, s);
    212  |   UT_free(s);
    213  |   return 0;
    214  | } /* show_thread() */
    215  |
    216  |
    217  | /*++++++++++++++++++++++++++++++++++++++
    218  |
    219  |   Switch the session to a whois session.
    220  |
    221  |   ++++++++++++++++++++++++++++++++++++++*/
    222  | int show_whois(char *input, GString *output, sk_conn_st *condat)
    223  | {
    224  |   /*  Go to whois mode */
    225  |   PW_interact(condat->sock);
    226  |   return 0;
    227  | } /* show_whois() */
    228  |
    229  |
    230  | /*++++++++++++++++++++++++++++++++++++++
    231  |
    232  |   Display the statistics about the server.
    233  |
    234  |   ++++++++++++++++++++++++++++++++++++++*/
    235  | int show_uptime(char *input, GString *output, sk_conn_st *condat)
    236  | {
    237  |   char timestring[26];
    238  |   extern time_t SV_starttime;
    239  |
    240  |   ctime_r(&SV_starttime, timestring);
    241  |   SK_cd_printf( condat,
    242  | 	       "System running since %sUptime in seconds: %ld \n\n",
    243  | 	       timestring,
    244  | 	       time(NULL) - SV_starttime);
    245  |
    246  |   return 0;
    247  | }
    248  |
    249  | /*++++++++++++++++++++++++++++++++++++++
    250  |
    251  |   Display the whois access statistics from the AC module.
    252  |
    253  |   ++++++++++++++++++++++++++++++++++++++*/
    254  | int show_access(char *input, GString *output, sk_conn_st *condat)
    255  | {
    256  |   int cnt = AC_print_access(output);
    257  |
    258  |   g_string_sprintfa(output, "Found %d nodes\n", cnt);
    259  |
    260  |   return 0;
    261  | } /* show_access() */
    262  |
    263  |
    264  | /*++++++++++++++++++++++++++++++++++++++
    265  |
    266  |   Display the whois access control list from the AC module.
    267  |
    268  |   ++++++++++++++++++++++++++++++++++++++*/
    269  | int show_acl(char *input, GString *output, sk_conn_st *condat)
    270  | {
    271  |   int cnt = AC_print_acl(output);
    272  |
    273  |   g_string_sprintfa(output, "Found %d nodes\n", cnt);
    274  |
    275  |   return 0;
    276  | } /* show_acl() */
    277  |
    278  | /*++++++++++++++++++++++++++++++++++++++
    279  |
    280  |   Display the access tree auto save state.
    281  |
    282  |   ++++++++++++++++++++++++++++++++++++++*/
    283  | int show_auto_save(char *input, GString *output, sk_conn_st *condat)
    284  | {
    285  |   g_string_sprintfa(output, "Auto save is %d\n", ac_auto_save);
    286  |
    287  |   return 0;
    288  | } /* show_auto_save() */
    289  |
    290  |
    291  | /*++++++++++++++++++++++++++++++++++++++
    292  |
    293  |   Modify the whois access control list in the AC module.
    294  |
    295  |   Arguments: IP[/prefixlength] column=value,column=value...
    296  |
    297  |   Column names as in acl display. Unset columns are inherited.
    298  |
    299  |   ++++++++++++++++++++++++++++++++++++++*/
    300  | int set_acl(char *input, GString *output, sk_conn_st *condat)
    301  | {
    302  |   int res = 0;
    303  |
    304  |   /* first 8 characters ("set acl ") are already skipped */
    305  |   if( ! NOERR( AC_asc_acl_command_set( input, "Manual"))) {
    306  |     g_string_append(output, "Error!\n");
    307  |     res = PC_RET_ERR;
    308  |   }
    309  |   return res;
    310  | }
    311  |
    312  | /*++++++++++++++++++++++++++++++++++++++
    313  |
    314  |   Sets the auto save status of the access tree.
    315  |
    316  |   Arguments: 0 = don't auto save, 1 = auto save
    317  |
    318  |   ++++++++++++++++++++++++++++++++++++++*/
    319  | int set_auto_save(char *input, GString *output, sk_conn_st *condat)
    320  | {
    321  |   int res = 0;
    322  |
    323  |   /* Lame */
    324  |   switch (input[0]) {
    325  |   case '0':
    326  |     ac_auto_save  = 0;
    327  | printf("0\n");
    328  |     break;
    329  |   case '1':
    330  |     ac_auto_save  = 1;
    331  | printf("1\n");
    332  |     break;
    333  |   default:
    334  | printf("X\n");
    335  |     res = PC_RET_ERR;
    336  |   }
    337  |   return res;
    338  | }
    339  |
    340  | /*++++++++++++++++++++++++++++++++++++++
    341  |
    342  |   Reset the deny counter in the access tree to 0 (after reenabling)
    343  |   (AC module).
    344  |
    345  |   Argument: IP address.
    346  |
    347  |   ++++++++++++++++++++++++++++++++++++++*/
    348  | int set_nodeny(char *input, GString *output, sk_conn_st *condat) {
    349  |
    350  |   /* first 11 characters ("set nodeny ")  are already skipped */
    351  |
    352  |   if( ! NOERR( AC_asc_set_nodeny(input) )) {
    353  |     g_string_append(output, "Error\n");
    354  |     return PC_RET_ERR;
    355  |   }
    356  |   else {
    357  |     return 0;
    358  |   }
    359  |
    360  | } /* set_nodeny() */
    361  |
    362  |
    363  | /*++++++++++++++++++++++++++++++++++++++
    364  |
    365  |   Pause/resume update capability of the UD module.
    366  |
    367  |   Argument: the word "pause" or "resume".
    368  |
    369  |   ++++++++++++++++++++++++++++++++++++++*/
    370  | int set_updates(char *input, GString *output, sk_conn_st *condat)
    371  | {
    372  |   char argstr[17];
    373  |   int pause=0, resume=0;
    374  |   int res = 0;
    375  |
    376  |   if( sscanf(input, "%16s", argstr) == 1) {
    377  |     pause = (strcmp(argstr,"pause") == 0);
    378  |     resume = (strcmp(argstr,"resume") == 0);
    379  |   }
    380  |
    381  |   if( !pause && !resume ) {
    382  |     g_string_append(output,  "syntax error.");
    383  |     res = PC_RET_ERR;
    384  |   }
    385  |   else {
    386  |     /* all params ok. just set the property */
    387  |     char *value = pause ? "0" : "1";
    388  |
    389  |     if (CO_set_const("UD.do_update", value) == 0) {
    390  |       g_string_append(output, "Constant successfully set\n");
    391  |     }
    392  |     else {
    393  |       g_string_append(output, "Could not set\n");
    394  |       res = PC_RET_ERR;
    395  |     }
    396  |   }
    397  |   return res;
    398  | }
    399  | /*++++++++++++++++++++++++++++++++++++++
    400  |
    401  |   Pause/resume queries.
    402  |
    403  |   Argument: the word "pause" or "resume".
    404  |
    405  |   ++++++++++++++++++++++++++++++++++++++*/
    406  | int set_queries(char *input, GString *output, sk_conn_st *condat)
    407  | {
    408  |   char argstr[17];
    409  |   int pause=0, resume=0;
    410  |   int res = 0;
    411  |
    412  |   if( sscanf(input, "%16s", argstr) == 1) {
    413  |     pause = (strcmp(argstr,"pause") == 0);
    414  |     resume = (strcmp(argstr,"resume") == 0);
    415  |   }
    416  |
    417  |   if( !pause && !resume ) {
    418  |     g_string_append(output,  "syntax error.");
    419  |     res = PC_RET_ERR;
    420  |   }
    421  |   else {
    422  |
    423  |     if(pause){
    424  | 	    PW_stopqueries();
    425  | 	    g_string_append(output, "Queries are stopped\n");
    426  |     }else {
    427  | 	    PW_startqueries();
    428  | 	    g_string_append(output, "Queries are unblocked\n");
    429  |     }
    430  |   }
    431  |   return res;
    432  | }
    433  |
    434  |
    435  | /*++++++++++++++++++++++++++++++++++++++
    436  |
    437  |   Reset the source.
    438  |
    439  |   Reloads the radix tree.
    440  |
    441  |   Argument: the source name.
    442  |
    443  |   ++++++++++++++++++++++++++++++++++++++*/
    444  | int set_initrx(char *input, GString *output, sk_conn_st *condat)
    445  | {
    446  | ca_dbSource_t *source_hdl;
    447  | int res = 0;
    448  |
    449  | 	source_hdl = ca_get_SourceHandleByName(input);
    450  |         if (source_hdl == NULL){
    451  | 		g_string_append(output,  "Unknown source");
    452  | 		res = PC_RET_ERR;
    453  | 	}
    454  | 	else if(RP_init_trees( source_hdl ) != RP_OK ) {
    455  | 		g_string_append(output, "Could not re-initialize radix trees");
    456  |                 res = PC_RET_ERR;
    457  | 	}
    458  | 	else if(RP_sql_load_reg( source_hdl ) != RP_OK ) {
    459  | 		g_string_append(output, "Could not load radix trees");
    460  |                 res = PC_RET_ERR;
    461  | 	}
    462  |         else {
    463  |          g_string_append(output, "radix trees reloaded successfully\n");
    464  |         }
    465  |  return res;
    466  | }
    467  | /*++++++++++++++++++++++++++++++++++++++
    468  |
    469  |   Reset the "session time" and "# of tasks"
    470  |   of a specific thread registered with the TA module.
    471  |
    472  |   ++++++++++++++++++++++++++++++++++++++*/
    473  | #if 0
    474  |
    475  | /*
    476  | XXX:
    477  | I've removed this function because it is supposed to pass a pthread_t
    478  | to the TA_reset_counters() function.  But pthread_t is an opaque
    479  | type - on FreeBSD it is a pointer to a structure, so you can't simply
    480  | use sscanf() to get one!
    481  |
    482  | Shane
    483  | 2001-09-05
    484  |
    485  | int set_counter(char *input, GString *output, sk_conn_st *condat)
    486  | {
    487  |   unsigned thr_id;
    488  |
    489  |   if( sscanf(input, "%d", &thr_id) == 1) {
    490  |     TA_reset_counters(thr_id);
    491  |   }
    492  |   return 0;
    493  | }
    494  | */
    495  | #endif /* 0 */
    496  |
    497  |
    498  |
    499  | /*++++++++++++++++++++++++++++++++++++++
    500  |
    501  |   Execute a command in the ER path processor of the ER module.
    502  |   (first subject to macro expansion of the first word).
    503  |
    504  |   Argument is passed entirely to ER_macro_spec().
    505  |
    506  |   ++++++++++++++++++++++++++++++++++++++*/
    507  | int set_err(char *input, GString *output, sk_conn_st *condat)
    508  | {
    509  |   char *erret = NULL;
    510  |   int res;
    511  |
    512  |   res = ER_macro_spec(input, &erret);
    513  |   g_string_append(output, erret);
    514  |   UT_free(erret);
    515  |
    516  |   return res;
    517  | }
    518  |
    519  |
    520  | /*++++++++++++++++++++++++++++++++++++++
    521  |
    522  |   Show the current setup of the ER path system of the ER module.
    523  |
    524  |   ++++++++++++++++++++++++++++++++++++++*/
    525  | int show_err(char *input, GString *output, sk_conn_st *condat)
    526  | {
    527  |   char *erret = NULL;
    528  |
    529  |   er_print_paths(&erret);
    530  |   g_string_append(output, erret);
    531  |   UT_free(erret);
    532  |
    533  |   return 0;
    534  | }
    535  |
    536  |
    537  | /*++++++++++++++++++++++++++++++++++++++
    538  |
    539  |   Show the currently defined macros for the ER path system of the ER module.
    540  |
    541  |   ++++++++++++++++++++++++++++++++++++++*/
    542  | int show_macros(char *input, GString *output, sk_conn_st *condat)
    543  | {
    544  |   ER_macro_list(condat);
    545  |   return 0;
    546  | }
    547  |
    548  |
    549  |
    550  | /*++++++++++++++++++++++++++++++++++++++
    551  |
    552  |   (re)define a macro for the ER path processor.
    553  |
    554  |   Arguments: The first word is treated as a macro name.
    555  |   The rest of the line is treated as a macro definition.
    556  |
    557  |   ++++++++++++++++++++++++++++++++++++++*/
    558  | int set_macro(char *input, GString *output, sk_conn_st *condat)
    559  | {
    560  |   char *name, *body;
    561  |
    562  |   if( strlen(input) > 0 ) {
    563  |     body = input;
    564  |     name = (char *)strsep(&body, " ");
    565  |
    566  |     ER_make_macro( name, body );
    567  |   }
    568  |
    569  |   return 0;
    570  | }
    571  |
    572  |
    573  |
    574  |
    575  | /*++++++++++++++++++++++++++++++++++++++
    576  |
    577  |   Trigger running of the socket watchdog actions for a specific thread
    578  |   (typically resulting in shutting down of a query thread).
    579  |
    580  |   Arguments are "<socket_id> <thread_id>" as in the output of "show threads".
    581  |
    582  |   Assumes the command is like "stop query 11 17".
    583  |   This is to limit ambiguities (a new thread on the same socket, for example).
    584  | .
    585  |   ++++++++++++++++++++++++++++++++++++++*/
    586  | #if 0
    587  | /*
    588  | XXX:
    589  | I've removed this function because it is supposed to pass a pthread_t
    590  | to the TA_trigger() function.  But pthread_t is an opaque
    591  | type - on FreeBSD it is a pointer to a structure, so you can't simply
    592  | use sscanf() to get one!
    593  |
    594  | Shane
    595  | 2001-09-05
    596  |
    597  | int stop_query(char *input, GString *output, sk_conn_st *condat)
    598  | {
    599  |   int fd;
    600  |   unsigned thr;
    601  |
    602  |
    603  |   if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) {
    604  |     g_string_append(output,"error!!");
    605  |     return PC_RET_ERR;
    606  |   }
    607  |   else {
    608  |     TA_trigger("whois", fd, thr);
    609  |     return 0;
    610  |   }
    611  | }
    612  | */
    613  | #endif /* 0 */