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  |