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