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 | }