1 | /*************************************** 2 | $Revision: 1.21 $ 3 | 4 | Protocol config module (pc). This is the protocol that the admin uses to 5 | talk to the server. 6 | 7 | Status: NOT REVUED, NOT TESTED 8 | 9 | ******************/ /****************** 10 | Filename : protocol_config.c 11 | Authors : ottrey@ripe.net 12 | marek@ripe.net 13 | To Do : Add a facility to take callbacks instead of 14 | hard-coding menu options. 15 | Add in all the menu support provided by the GLib 16 | libraries. 17 | (Remove strtok if multiple threads are to be used.) 18 | use gnu readline with expansion and history 19 | ******************/ /****************** 20 | Copyright (c) 1999 RIPE NCC 21 | 22 | All Rights Reserved 23 | 24 | Permission to use, copy, modify, and distribute this software and its 25 | documentation for any purpose and without fee is hereby granted, 26 | provided that the above copyright notice appear in all copies and that 27 | both that copyright notice and this permission notice appear in 28 | supporting documentation, and that the name of the author not be 29 | used in advertising or publicity pertaining to distribution of the 30 | software without specific, written prior permission. 31 | 32 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 33 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 34 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 35 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 36 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 37 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 38 | ***************************************/ 39 | #include <stdio.h> 40 | #include <stdlib.h> 41 | /*** solaris' header file doesn't contain the crypt definition... 42 | #include <unistd.h> */ 43 | 44 | extern char* crypt(const char *, const char *); /* crypt stuff */ 45 | #include <time.h> /* Time stuff */ 46 | #include <sys/ioctl.h> /* Terminal control stuff */ 47 | #include <termio.h> /* Terminal control stuff */ 48 | 49 | #include "mysql_driver.h" 50 | #include "constants.h" 51 | #include "properties.h" 52 | #include "thread.h" 53 | #include "protocol_config.h" 54 | #include "access_control.h" 55 | #include "socket.h" 56 | #include "ta.h" 57 | 58 | /*+ Each command has a +*/ 59 | typedef struct _command { 60 | const char *name; /*+ Name to be invoked. +*/ 61 | char *(*function)(char *, sk_conn_st *); /*+ Function to be invoked. +*/ 62 | const char *help; /*+ Command help. +*/ 63 | } Command; 64 | 65 | /* 66 | * Forward declarations 67 | */ 68 | static char *command_help(char *input, sk_conn_st *condat); 69 | static char *command_quit(char *input, sk_conn_st *condat); 70 | static char *command_show(char *input, sk_conn_st *condat); 71 | static char *command_repeat(char *input, sk_conn_st *condat); 72 | static char *show_const(char *input, sk_conn_st *condat); 73 | static char *show_consts(char *input, sk_conn_st *condat); 74 | static char *show_props(char *input, sk_conn_st *condat); 75 | static char *show_threads(char *input, sk_conn_st *condat); 76 | static char *show_whois(char *input, sk_conn_st *condat); 77 | static char *show_access(char *input, sk_conn_st *condat); 78 | static char *show_acl(char *input, sk_conn_st *condat); 79 | static char *command_set(char *input, sk_conn_st *condat); 80 | static char *set_const(char *input, sk_conn_st *condat); 81 | static char *set_consts(char *input, sk_conn_st *condat); 82 | static char *set_props(char *input, sk_conn_st *condat); 83 | static char *command_sql(char *input, sk_conn_st *condat); 84 | static char *set_ban(char *input, sk_conn_st *condat); 85 | 86 | /*+ 87 | * Contains the command definitions 88 | +*/ 89 | static struct _command command[] = { 90 | {"help" , command_help , HELP_HELP }, 91 | {"quit" , command_quit , HELP_QUIT }, 92 | {"show" , command_show , HELP_SHOW }, 93 | {"repeat" , command_repeat , HELP_REPEAT }, 94 | {"set" , command_set , HELP_SET }, 95 | {"sql" , command_sql , HELP_SQL }, 96 | {NULL , NULL , NULL } 97 | }; 98 | 99 | /*+ 100 | * Contains the show commands 101 | +*/ 102 | static struct _command show[] = { 103 | {"const" , show_const , HELP_SHOW_CONST }, 104 | {"consts" , show_consts , HELP_SHOW_CONSTS }, 105 | {"props" , show_props , HELP_SHOW_PROPS }, 106 | {"threads" , show_threads , HELP_SHOW_THREAD }, 107 | {"whois" , show_whois , HELP_SHOW_WHOIS }, 108 | {"access" , show_access , HELP_SHOW_ACCESS }, 109 | {"acl" , show_acl , HELP_SHOW_ACL }, 110 | {NULL , NULL , NULL } 111 | }; 112 | 113 | /*+ 114 | * Contains the set commands 115 | +*/ 116 | static struct _command set[] = { 117 | {"const" , set_const , HELP_SET_CONST }, 118 | {"consts" , set_consts , HELP_SET_CONSTS }, 119 | {"props" , set_props , HELP_SET_PROPS }, 120 | {"ban" , set_ban , HELP_SET_BAN }, 121 | {NULL , NULL , NULL } 122 | }; 123 | 124 | static int find_command(char *comm_name, Command *comm) { 125 | int i, index; 126 | char comm_buffer[STR_L]; 127 | 128 | if (comm_name != NULL) { 129 | strcpy(comm_buffer, comm_name); 130 | strtok(comm_buffer, " \t"); 131 | for (i=0, index=-1; comm[i].name != NULL; i++) { 132 | if ( strcmp(comm_buffer, comm[i].name) == 0) { 133 | index = i; 134 | break; 135 | } 136 | } 137 | } 138 | else { 139 | index = -2; 140 | } 141 | 142 | return index; 143 | } /* find_command() */ 144 | 145 | static char *show_commands(Command *comm) { 146 | char *str; 147 | char help_buffer[STR_XL]; 148 | char help_comm[STR_M]; 149 | int i; 150 | 151 | sprintf(help_buffer, " commands are:\n\n"); 152 | i = 0; 153 | while (comm[i].name != NULL) { 154 | sprintf(help_comm, "%s\t%s\n", comm[i].name, comm[i].help); 155 | strcat(help_buffer, help_comm); 156 | i++; 157 | } 158 | 159 | /* str = (char *)calloc(1, strlen(help_buffer)+1); */ 160 | dieif( wr_malloc((void **)&str, strlen(help_buffer)+1) != UT_OK); 161 | strcpy(str, help_buffer); 162 | 163 | return str; 164 | } /* show_commands() */ 165 | 166 | 167 | /* 168 | * Command functions 169 | */ 170 | static char *command_help(char *input, sk_conn_st *condat) { 171 | char *str; 172 | char *str1; 173 | char output_buffer[STR_XXL]; 174 | char *command_name; 175 | int index; 176 | 177 | strcpy(output_buffer, ""); 178 | 179 | strtok(input, " \t"); 180 | command_name = (char *)strtok(NULL, " \t"); 181 | 182 | index = find_command(command_name, command); 183 | 184 | switch (index) { 185 | case -2: 186 | strcat(output_buffer, "Main"); 187 | str1 = show_commands(command); 188 | strcat(output_buffer, str1); 189 | wr_free(str1); 190 | break; 191 | 192 | case -1: 193 | strcat(output_buffer, HELP_ERROR); 194 | strcat(output_buffer, command_name); 195 | break; 196 | 197 | default: 198 | strcat(output_buffer, command[index].help); 199 | } 200 | 201 | /* 202 | str = (char *)CopyString(output_buffer); 203 | */ 204 | /* str = (char *)calloc(1, strlen(output_buffer)+1); */ 205 | dieif( wr_malloc((void **)&str, strlen(output_buffer)+1) != UT_OK); 206 | strcpy(str, output_buffer); 207 | 208 | return str; 209 | } /* command_help() */ 210 | 211 | static char *command_quit(char *input, sk_conn_st *condat) { 212 | /* Administrator wishes to quit. */ 213 | return NULL; 214 | } /* command_quit() */ 215 | 216 | static char *show_const(char *input, sk_conn_st *condat) { 217 | /* Administrator wishes to show constants. */ 218 | char *result; 219 | char *name; 220 | char *tmp_input; 221 | 222 | /* tmp_input = (char *)calloc(1, strlen(input)+1); */ 223 | dieif( wr_malloc((void **)&tmp_input, strlen(input)+1) != UT_OK); 224 | strcpy(tmp_input, input); 225 | 226 | /* The name will be the third token in stuff */ 227 | strtok(tmp_input, " "); 228 | strtok(NULL, " "); 229 | name = (char *)strtok(NULL, " "); 230 | 231 | result = CO_const_to_string(name); 232 | 233 | wr_free(tmp_input); 234 | return result; 235 | 236 | } /* show_const() */ 237 | 238 | static char *show_consts(char *input, sk_conn_st *condat) { 239 | /* Administrator wishes to show constants. */ 240 | return CO_to_string(); 241 | 242 | } /* show_consts() */ 243 | 244 | static char *show_props(char *input, sk_conn_st *condat) { 245 | /* Administrator wishes to show properties. */ 246 | return PR_to_string(); 247 | 248 | } /* show_props() */ 249 | 250 | static char *show_threads(char *input, sk_conn_st *condat) { 251 | /* Administrator wishes to show thread information. */ 252 | return TA_tostring(); 253 | 254 | } /* show_thread() */ 255 | 256 | static char *show_whois(char *input, sk_conn_st *condat) { 257 | /* Administrator wishes to show whois query information. */ 258 | return wr_string("WQ_to_string();"); 259 | 260 | } /* show_whois() */ 261 | 262 | static char *show_access(char *input, sk_conn_st *condat) { 263 | /* Administrator wishes to show whois query information. */ 264 | 265 | char line[128]; 266 | int cnt; 267 | er_ret_t err; 268 | 269 | if( act_runtime->top_ptr != NULL ) { 270 | char *header = AC_to_string_header(); 271 | 272 | /* print header */ 273 | SK_cd_puts(condat,header); 274 | wr_free(header); 275 | 276 | cnt = rx_walk_tree(act_runtime->top_ptr, AC_rxwalkhook_print, 277 | RX_WALK_SKPGLU, /* print no glue nodes */ 278 | 255, 0, 0, condat, &err); 279 | sprintf(line,"Found %d nodes\n", cnt); 280 | SK_cd_puts(condat,line); 281 | } 282 | 283 | return wr_string(""); 284 | 285 | } /* show_access() */ 286 | 287 | static char *show_acl(char *input, sk_conn_st *condat) { 288 | /* Administrator wishes to show access control list. */ 289 | 290 | char line[128]; 291 | int cnt; 292 | er_ret_t err; 293 | 294 | if( act_acl->top_ptr != NULL ) { 295 | char *header = AC_acl_to_string_header(); 296 | 297 | /* print header */ 298 | SK_cd_puts(condat,header); 299 | wr_free(header); 300 | 301 | cnt = rx_walk_tree(act_acl->top_ptr, AC_rxwalkhook_print_acl, 302 | RX_WALK_SKPGLU, /* print no glue nodes */ 303 | 255, 0, 0, condat, &err); 304 | sprintf(line,"Found %d nodes\n", cnt); 305 | SK_cd_puts(condat,line); 306 | } 307 | 308 | return wr_string(""); 309 | 310 | } /* show_acl() */ 311 | 312 | static char *command_execute(char *input, char *comm_name, 313 | Command *comm, sk_conn_st *condat) { 314 | char *str; 315 | char *str1; 316 | char output_buffer[STR_XXL]; 317 | char *name; 318 | int index; 319 | char *tmp_input; 320 | 321 | /* Make a copy of the input */ 322 | /* tmp_input = (char *)calloc(1, strlen(input)+1); */ 323 | dieif( wr_malloc((void **)&tmp_input, strlen(input)+1) != UT_OK); 324 | strcpy(tmp_input, input); 325 | 326 | strtok(tmp_input, " \t"); 327 | name = (char *)strtok(NULL, " \t"); 328 | 329 | index = find_command(name, comm); 330 | 331 | switch (index) { 332 | case -2: 333 | str1 = show_commands(comm); 334 | sprintf(output_buffer, "%s%s", comm_name, str1); 335 | wr_free(str1); 336 | break; 337 | 338 | case -1: 339 | sprintf(output_buffer, "%s invalid command: %s", comm_name, name); 340 | break; 341 | 342 | default: 343 | sprintf(output_buffer, "%s", comm[index].function(input, condat)); 344 | } 345 | 346 | /* 347 | str = (char *)CopyString(output_buffer); 348 | */ 349 | /* str = (char *)calloc(1, strlen(output_buffer)+1); */ 350 | dieif( wr_malloc((void **)&str, strlen(output_buffer)+1) != UT_OK); 351 | strcpy(str, output_buffer); 352 | 353 | wr_free(tmp_input); 354 | 355 | return str; 356 | } /* command_execute() */ 357 | 358 | static char *command_show(char *input, sk_conn_st *condat) { 359 | return command_execute(input, "Show", show, condat); 360 | } /* command_show() */ 361 | 362 | static char *command_repeat(char *input, sk_conn_st *condat) { 363 | char *command_ptr; 364 | 365 | /* Goto the bit after "repeat n " */ 366 | for (command_ptr=input+7; command_ptr[0] != ' ' || (command_ptr[0] >= '0' && command_ptr[0] <= '9'); command_ptr++); 367 | 368 | return command_ptr+1; 369 | 370 | } /* command_show() */ 371 | 372 | static char *set_const(char *input, sk_conn_st *condat) { 373 | /* Administrator wishes to set a constant. */ 374 | char *result; 375 | char result_buf[STR_M]; 376 | char *tmp_input; 377 | char *name; 378 | char *value; 379 | int value_len; 380 | char *stuff; 381 | char *str; 382 | 383 | /* tmp_input = (char *)calloc(1, strlen(input)+1); */ 384 | dieif( wr_malloc((void **)&tmp_input, strlen(input)+1) != UT_OK); 385 | strcpy(tmp_input, input); 386 | 387 | stuff = (char *)strtok(tmp_input, "="); 388 | 389 | /* The value will be after the '=' */ 390 | value = (char *)strtok(NULL, "="); 391 | 392 | /* The name will be the third token in stuff */ 393 | strtok(stuff, " "); 394 | strtok(NULL, " "); 395 | name = (char *)strtok(NULL, " "); 396 | 397 | /* Remove any quotes */ 398 | if (value[0] == '"') { 399 | value++; 400 | } 401 | value_len=strlen(value); 402 | if (value[value_len-1] == '"') { 403 | value[value_len-1]='\0'; 404 | } 405 | 406 | printf("set_const name=(%s), value=(%s)\n", name, value); 407 | if (CO_set_const(name, value) == 0) { 408 | strcpy(result_buf, "Constant successfully set\n"); 409 | } 410 | else { 411 | str = CO_const_to_string(name); 412 | sprintf(result_buf, "Constant not successfully set\nReverting to: %s=%s\n", name, str); 413 | wr_free(str); 414 | } 415 | 416 | /* result = (char *)calloc(1, strlen(result_buf)+1); */ 417 | dieif( wr_malloc((void **)&result, strlen(result_buf)+1) != UT_OK); 418 | strcpy(result, result_buf); 419 | 420 | wr_free(tmp_input); 421 | return result; 422 | } /* set_const() */ 423 | 424 | static char *set_consts(char *input, sk_conn_st *condat) { 425 | /* Administrator wishes to set constants. */ 426 | return CO_set(); 427 | } /* set_consts() */ 428 | 429 | static char *set_props(char *input, sk_conn_st *condat) { 430 | /* Administrator wishes to set properties. */ 431 | return PR_set(); 432 | } /* set_props() */ 433 | 434 | static char *set_ban(char *input, sk_conn_st *condat) { 435 | int flag; 436 | char addrstr[128]; 437 | 438 | if( sscanf(input,"set ban %d %127s", &flag, addrstr) < 2) { 439 | return wr_string("Invalid arguments"); 440 | } 441 | else { 442 | if( ! NOERR( AC_asc_ban_set( addrstr, "Manual", (flag!=0) ))) { 443 | return wr_string("Error\n"); 444 | } 445 | else { 446 | return wr_string("OK"); 447 | } 448 | } 449 | } 450 | 451 | static char *command_set(char *input, sk_conn_st *condat) { 452 | return command_execute(input, "Set", set, condat); 453 | } /* command_set() */ 454 | 455 | static char *command_sql(char *input, sk_conn_st *condat) { 456 | char *str; 457 | char output_buffer[STR_XXL]; 458 | char *sql_str; 459 | 460 | char *res=NULL; 461 | 462 | SQ_result_set_t *sql_result=NULL; 463 | SQ_connection_t *sql_connection; 464 | 465 | sql_connection = SQ_get_connection(CO_get_host(), CO_get_database_port(), CO_get_database(), CO_get_user(), CO_get_password() ); 466 | 467 | if (sql_connection == NULL) { 468 | printf("/* Check for errors */\n"); 469 | } 470 | 471 | /* skip over the "sql" */ 472 | sql_str = input+3; 473 | /* skip over white space */ 474 | while (sql_str[0] == ' ') { 475 | sql_str++; 476 | } 477 | 478 | strcpy(output_buffer, ""); 479 | 480 | if (sql_connection != NULL) { 481 | if (strcmp(sql_str, "status") == 0) { 482 | /* Get the status of the database */ 483 | res = SQ_info_to_string(sql_connection); 484 | } 485 | else { 486 | if (strcmp(sql_str, "") == 0) { 487 | /* Execute the default query (from the properties file) */ 488 | SQ_execute_query(sql_connection, CO_get_query(), &sql_result); 489 | } 490 | else { 491 | /* Execute an sql query */ 492 | SQ_execute_query(sql_connection, sql_str, &sql_result); 493 | } 494 | if (sql_result != NULL) { 495 | res = SQ_result_to_string(sql_result); 496 | } 497 | else { 498 | printf("no results\n"); 499 | } 500 | } 501 | if (res != NULL) { 502 | sprintf(output_buffer, "%s", res); 503 | } 504 | else { 505 | printf("empty results\n"); 506 | } 507 | } 508 | else { 509 | printf("Failed to make connection\n"); 510 | } 511 | 512 | /* 513 | strcat(output_buffer, mysql_info(sql_connection)); 514 | */ 515 | 516 | strcat(output_buffer, "XXX Results from mysql_info(sql_connection) is meant to go here. But it's not working!"); 517 | 518 | /* 519 | str = (char *)CopyString(output_buffer); 520 | */ 521 | /* str = (char *)calloc(1, strlen(output_buffer)+1); */ 522 | dieif( wr_malloc((void **)&str, strlen(output_buffer)+1) != UT_OK); 523 | strcpy(str, output_buffer); 524 | 525 | wr_free(res); 526 | SQ_free_result(sql_result); 527 | 528 | SQ_close_connection(sql_connection); 529 | 530 | return str; 531 | 532 | } /* command_sql() */ 533 | 534 | 535 | /* process_input() */ 536 | /*++++++++++++++++++++++++++++++++++++++ 537 | 538 | Process the input. 539 | 540 | sk_conn_st *condat connection data 541 | 542 | More: 543 | +html+ <PRE> 544 | Author: 545 | ottrey 546 | +html+ </PRE> 547 | ++++++++++++++++++++++++++++++++++++++*/ 548 | static int process_input(char *input, sk_conn_st *condat) { 549 | int connected = 1; 550 | char *input_ptr; 551 | char *output; 552 | int index; 553 | int repeat=0; 554 | 555 | input_ptr = input; 556 | 557 | if (strncmp(input, "repeat", 6) == 0) { 558 | /* XXX This is a really dodgy call, that hopefully converts 559 | the string to the value of the first found integer. */ 560 | repeat = atoi(input+7); 561 | input_ptr= command_repeat(input, condat); 562 | } 563 | 564 | index = find_command(input_ptr, command); 565 | 566 | do { 567 | switch (index) { 568 | case -1: 569 | /* Command not found */ 570 | output = command_help(NULL, condat); 571 | break; 572 | 573 | default: 574 | output = command[index].function(input_ptr, condat); 575 | } 576 | 577 | if(output == NULL) { 578 | connected = 0; 579 | } else { 580 | /* 581 | printf("thread output=\n%s\n", output); 582 | */ 583 | if ( CO_get_clear_screen() == 1 ) { 584 | SK_cd_puts(condat, CLEAR_SCREEN); 585 | } 586 | SK_cd_puts(condat, output); 587 | SK_cd_puts(condat, "\n"); 588 | SK_cd_puts(condat, CO_get_prompt()); 589 | 590 | wr_free(output); 591 | } 592 | 593 | if (repeat > 0) { 594 | repeat--; 595 | sleep(CO_get_sleep_time()); 596 | } 597 | 598 | } while (repeat > 0); 599 | 600 | return connected; 601 | 602 | } /* process_input() */ 603 | 604 | static void log_config(const char *user, const char *status) { 605 | FILE *logf; 606 | time_t now; 607 | char timebuf[26]; 608 | 609 | time(&now); 610 | 611 | if (CO_get_config_logging() == 1) { 612 | 613 | if (strcmp(CO_get_config_logfile(), "stdout") == 0) { 614 | printf(LOG_CONFIG, TH_get_id(), user, status, ctime_r(&now, timebuf)); 615 | } 616 | else { 617 | logf = fopen(CO_get_config_logfile(), "a"); 618 | fprintf(logf, LOG_CONFIG, TH_get_id(), user, status, ctime_r(&now, timebuf)); 619 | fclose(logf); 620 | } 621 | } 622 | 623 | } /* log_config() */ 624 | 625 | /* XXX Doh! These only change the server's terminal. We need some 626 | tricky escape sequence to send over the socket. 627 | static void echo_off(int sock) { 628 | struct termio state; 629 | 630 | ioctl(0, TIOCGETP, &state); 631 | state.c_lflag &= ~ECHO; 632 | ioctl(0, TIOCSETP, &state); 633 | } echo_off() */ 634 | 635 | /* XXX Doh! These only change the server's terminal. We need some 636 | tricky escape sequence to send over the socket. 637 | static void echo_on(int sock) { 638 | struct termio state; 639 | 640 | ioctl(0, TIOCGETP, &state); 641 | state.c_lflag |= ECHO; 642 | ioctl(0, TIOCSETP, &state); 643 | } echo_on() */ 644 | 645 | static char *authenticate_user(sk_conn_st *condat) { 646 | char *user = NULL; 647 | const char Salt[2] = "DB"; 648 | char input[MAX_INPUT_SIZE]; 649 | int read_result; 650 | char *password=NULL; 651 | char *user_password=NULL; 652 | char user_buf[10]; 653 | 654 | SK_cd_puts(condat, LOGIN_PROMPT); 655 | read_result = SK_cd_gets(condat, input, MAX_INPUT_SIZE); 656 | 657 | strncpy(user_buf, input, 10); 658 | 659 | SK_cd_puts(condat, PASSWD_PROMPT); 660 | /* XXX These aren't working. 661 | SK_puts(sock, ECHO_ON); 662 | echo_off(sock); 663 | */ 664 | read_result = SK_cd_gets(condat, input, MAX_INPUT_SIZE); 665 | /* XXX These aren't working. 666 | echo_on(sock); 667 | SK_puts(sock, ECHO_OFF); 668 | */ 669 | 670 | password = crypt(input, Salt); 671 | 672 | user_password = PR_get_property(user_buf, DEFAULT_USER_NAME); 673 | 674 | if (user_password != NULL) { 675 | if (strcmp(password, user_password) == 0) { 676 | /*user = (char *)calloc(1, strlen(user_buf)+1);*/ 677 | dieif( wr_malloc((void **)&user, strlen(user_buf)+1) != UT_OK); 678 | strcpy(user, user_buf); 679 | } 680 | } 681 | 682 | if (user == NULL) { 683 | log_config(user_buf, "unsuccesful login attempt"); 684 | } 685 | 686 | return user; 687 | 688 | } /* authenticate_user() */ 689 | 690 | void PC_interact(int sock) { 691 | char input[MAX_INPUT_SIZE]; 692 | int connected = 1; 693 | char *user=NULL; 694 | sk_conn_st condat; 695 | 696 | memset( &condat, 0, sizeof(condat)); 697 | condat.sock = sock; 698 | SK_getpeerip(sock, &(condat.rIP)); 699 | condat.ip = SK_getpeername(sock); /* XXX *alloc involved */ 700 | 701 | /* Welcome the client */ 702 | SK_cd_puts(&condat, CO_get_welcome()); 703 | 704 | /* Authenticate the user */ 705 | if (CO_get_authenticate() == 1) { 706 | user = authenticate_user(&condat); 707 | } 708 | else { 709 | user="nobody"; 710 | } 711 | 712 | if (user != NULL) { 713 | 714 | 715 | /* Log admin logging on */ 716 | log_config(user, "logged on"); 717 | 718 | 719 | { 720 | char timestring[26]; 721 | extern time_t SV_starttime; 722 | 723 | ctime_r(&SV_starttime, timestring); 724 | SK_cd_printf(&condat, 725 | "System running since %sUptime in seconds: %ld \n\n", 726 | timestring, 727 | time(NULL) - SV_starttime); 728 | } 729 | 730 | SK_cd_puts(&condat, CO_get_prompt()); 731 | 732 | while (condat.rtc==0 && connected) { 733 | char *ichr; 734 | char *icopy; 735 | char *chr; 736 | /* Read input */ 737 | SK_cd_gets(&condat, input, MAX_INPUT_SIZE); 738 | 739 | /* filter junk out: leading/trailing whitespaces */ 740 | 741 | /* 1. advance to non-whitespace */ 742 | for(ichr=input; *ichr != 0 && isspace(*ichr); ichr++) { 743 | /* EMPTY */ 744 | } 745 | /* 2. copy the rest (even if empty) */ 746 | dieif( (icopy = strdup(ichr)) == NULL); 747 | 748 | /* 3. chop trailing spaces */ 749 | for( chr = icopy + strlen(icopy)-1 ; 750 | chr != icopy && isspace(*chr); 751 | chr--) { 752 | *chr = 0; 753 | } 754 | 755 | /* set thread accounting */ 756 | TA_setactivity(icopy); 757 | TA_increment(); 758 | 759 | connected = process_input(icopy, &condat); 760 | 761 | TA_setactivity(""); 762 | 763 | free(icopy); 764 | } 765 | 766 | /* Log admin logging off */ 767 | log_config(user, "logged off"); 768 | } 769 | 770 | /* Close the socket */ 771 | SK_close(sock); 772 | 773 | wr_free(condat.ip); 774 | } /* PC_interact() */ 775 |