Source File modules/pc/protocol_config.c

    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  |