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