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 | Stops updates for a given source and 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 (CO_set_const("UD.do_update", "0") != 0) { 390 | g_string_append(output, "Could not stop updates"); 391 | res = PC_RET_ERR; 392 | } 393 | else if(RP_init_trees( source_hdl ) != RP_OK ) { 394 | g_string_append(output, "Could not re-initialize radix trees"); 395 | res = PC_RET_ERR; 396 | } 397 | else if(RP_sql_load_reg( source_hdl ) != RP_OK ) { 398 | g_string_append(output, "Could not load radix trees"); 399 | res = PC_RET_ERR; 400 | } 401 | else { 402 | g_string_append(output, "radix trees reloaded successfully\nplease resume updates"); 403 | } 404 | return res; 405 | } 406 | /*++++++++++++++++++++++++++++++++++++++ 407 | 408 | Reset the "session time" and "# of tasks" 409 | of a specific thread registered with the TA module. 410 | 411 | ++++++++++++++++++++++++++++++++++++++*/ 412 | int set_counter(char *input, GString *output, sk_conn_st *condat) 413 | { 414 | unsigned thr_id; 415 | 416 | if( sscanf(input, "%d", &thr_id) == 1) { 417 | TA_reset_counters(thr_id); 418 | } 419 | return 0; 420 | } 421 | 422 | 423 | 424 | /*++++++++++++++++++++++++++++++++++++++ 425 | 426 | Execute a command in the ER path processor of the ER module. 427 | (first subject to macro expansion of the first word). 428 | 429 | Argument is passed entirely to ER_macro_spec(). 430 | 431 | ++++++++++++++++++++++++++++++++++++++*/ 432 | int set_err(char *input, GString *output, sk_conn_st *condat) 433 | { 434 | char *erret = NULL; 435 | int res; 436 | 437 | res = ER_macro_spec(input, &erret); 438 | g_string_append(output, erret); 439 | free(erret); 440 | 441 | return res; 442 | } 443 | 444 | 445 | /*++++++++++++++++++++++++++++++++++++++ 446 | 447 | Show the current setup of the ER path system of the ER module. 448 | 449 | ++++++++++++++++++++++++++++++++++++++*/ 450 | int show_err(char *input, GString *output, sk_conn_st *condat) 451 | { 452 | char *erret = NULL; 453 | 454 | er_print_paths(&erret); 455 | g_string_append(output, erret); 456 | free(erret); 457 | 458 | return 0; 459 | } 460 | 461 | 462 | /*++++++++++++++++++++++++++++++++++++++ 463 | 464 | Show the currently defined macros for the ER path system of the ER module. 465 | 466 | ++++++++++++++++++++++++++++++++++++++*/ 467 | int show_macros(char *input, GString *output, sk_conn_st *condat) 468 | { 469 | ER_macro_list(condat); 470 | return 0; 471 | } 472 | 473 | 474 | 475 | /*++++++++++++++++++++++++++++++++++++++ 476 | 477 | (re)define a macro for the ER path processor. 478 | 479 | Arguments: The first word is treated as a macro name. 480 | The rest of the line is treated as a macro definition. 481 | 482 | ++++++++++++++++++++++++++++++++++++++*/ 483 | int set_macro(char *input, GString *output, sk_conn_st *condat) 484 | { 485 | char *name, *body; 486 | 487 | if( strlen(input) > 0 ) { 488 | body = input; 489 | name = (char *)strsep(&body, " "); 490 | 491 | ER_make_macro( name, body ); 492 | } 493 | 494 | return 0; 495 | } 496 | 497 | 498 | 499 | 500 | /*++++++++++++++++++++++++++++++++++++++ 501 | 502 | Trigger running of the socket watchdog actions for a specific thread 503 | (typically resulting in shutting down of a query thread). 504 | 505 | Arguments are "<socket_id> <thread_id>" as in the output of "show threads". 506 | 507 | Assumes the command is like "stop query 11 17". 508 | This is to limit ambiguities (a new thread on the same socket, for example). 509 | . 510 | ++++++++++++++++++++++++++++++++++++++*/ 511 | int stop_query(char *input, GString *output, sk_conn_st *condat) 512 | { 513 | int fd; 514 | unsigned thr; 515 | 516 | 517 | if( sscanf(input, "%d %ud", &fd, &thr) < 2 ) { 518 | g_string_append(output,"error!!"); 519 | return PC_RET_ERR; 520 | } 521 | else { 522 | TA_trigger("whois", fd, thr); 523 | return 0; 524 | } 525 | }