Source File modules/pc/protocol_config.c

    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  |