- Use the Wine spooler service as the service entry template as I was
[reactos.git] / rosapps / applications / sysutils / telnetd / telnetd.c
index 0aa105e..f8058d0 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * File: TelnetD.c
- *
  * Abstract: a simple telnet 'daemon' for Windows hosts.
  *
  * Compiled & run successfully using MSVC 5.0 under Windows95 (requires 
  * TODO: 
  * - access control
  * - will/won't handshake
- * - (run as) Windows NT service
+ * - Unify Debugging output and return StatusCodes
  */
 
 #include <stdio.h> 
-#include <windows.h>  
-
-/*
-** macro definitions
-*/
-#define TELNET_PORT      (23)
+#include <windows.h>
 
-#define BUFSIZE        (4096)  
-#define USERID_SIZE      (64)
-#define CTRLC             (3)
-#define BS                (8)
-#define CR               (13)
-#define LF               (10)
-#define DEL             (127)
+#include "telnetd.h"
 
-#define IAC             (255)
-#define DONT            (254)
-#define WONT            (253)
-#define DO              (252)
-#define WILL            (251)
-#define ECHO            (1)
-
-#define HANDSHAKE_TIMEOUT (3)
-
-/*
-** types
-*/
-
-typedef struct client_s
-{
-  char     userID[USERID_SIZE];
-  int      socket;
-  BOOLEAN  bTerminate;
-  BOOLEAN  bReadFromPipe;
-  BOOLEAN  bWriteToPipe;
-  HANDLE   hProcess;
-  DWORD    dwProcessId;
-  HANDLE   hChildStdinWr;   
-  HANDLE   hChildStdoutRd;
-} client_t;
-
-typedef enum
-{
-  NoEcho = 0,
-  Echo = 1,
-  Password = 2
-} EchoMode;
-
-/*
-** Local data
-*/
+/* Local data */
 
 static BOOLEAN bShutdown = 0;
 static BOOLEAN bSocketInterfaceInitialised = 0;
 
 static int sock;
 
-/*
-** Forward function declarations
-*/
-static BOOL WINAPI Cleanup(DWORD dwControlType);
-static void WaitForConnect(void);
-static BOOLEAN StartSocketInterface(void);
-static void CreateSocket(void);
-static void UserLogin(int client_socket);
-static DWORD WINAPI UserLoginThread(LPVOID);
-static int DoTelnetHandshake(int sock);
-static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo);
-static void RunShell(client_t *client); 
-static BOOL CreateChildProcess(const char *); 
-static DWORD WINAPI MonitorChildThread(LPVOID);
-static DWORD WINAPI WriteToPipeThread(LPVOID); 
-static DWORD WINAPI ReadFromPipeThread(LPVOID); 
-static void TerminateShell(client_t *client);
-static VOID ErrorExit(LPTSTR); 
-
-
-/*
-** main
-*/
-DWORD telnetd_main() 
+/* In the future, some options might be passed here to handle
+ * authentication options in the registry or command line
+ * options passed to the service
+ *
+ * Once you are ready to turn on the service
+ * rename this function
+ * int kickoff_telnetd(void)
+ */
+int main(int argc, char **argv)
 {
   SetConsoleCtrlHandler(Cleanup, 1);
 
@@ -118,9 +55,7 @@ DWORD telnetd_main()
   return 0;
 }
 
-/*
-** Cleanup
-*/
+/* Cleanup */
 static BOOL WINAPI Cleanup(DWORD dwControlType)
 {
   if (bSocketInterfaceInitialised) {
@@ -130,9 +65,7 @@ static BOOL WINAPI Cleanup(DWORD dwControlType)
   return 0;
 }
 
-/*
-** StartSocketInterface
-*/
+/* StartSocketInterface */
 static BOOLEAN StartSocketInterface(void)
 {
   WORD    wVersionRequested;
@@ -224,8 +157,8 @@ static DWORD WINAPI UserLoginThread(LPVOID data)
   char       welcome[256];
   char       hostname[64] = "Unknown";
   char      *pwdPrompt = "\r\npass:";
-  char      *logonPrompt = "\r\nLogin OK, please wait...";
-  char      *byebye = "\r\nWrong! bye bye...\r\n";
+  //char      *logonPrompt = "\r\nLogin OK, please wait...";
+  //char      *byebye = "\r\nWrong! bye bye...\r\n";
   char       userID[USERID_SIZE];
   char       password[USERID_SIZE];
   int        received;
@@ -300,10 +233,23 @@ static int DoTelnetHandshake(int sock)
   int received;
   fd_set set;
   struct timeval timeout = { HANDSHAKE_TIMEOUT, 0 };
-  unsigned char will_echo[3] = { IAC, WILL, ECHO };
+
+  char will_echo[]=
+      IAC DONT ECHO
+      IAC WILL ECHO
+      IAC WILL NAWS
+      IAC WILL SUPPRESS_GO_AHEAD
+      IAC DO SUPPRESS_GO_AHEAD
+      IAC DONT NEWENVIRON
+      IAC WONT NEWENVIRON
+      IAC WONT LINEMODE
+      IAC DO NAWS
+      IAC SB TERMINAL_TYPE "\x01" IAC SE
+      ;
+
   unsigned char client_reply[256];
 
-  if (send(sock, (const char *) will_echo, sizeof(will_echo), 0) < 0) {   
+  if (send(sock, will_echo, sizeof(will_echo), 0) < 0) {   
     return -1;
   }
 
@@ -321,7 +267,7 @@ static int DoTelnetHandshake(int sock)
       return 0;
     }
     /* no error and no timeout, we have data in our sock */
-    received = recv(sock, client_reply, sizeof(client_reply), 0);
+    received = recv(sock, (char *) client_reply, sizeof(client_reply), 0);
     if (received <= 0) {
      return -1;
     }
@@ -466,7 +412,7 @@ static void RunShell(client_t *client)
                       NULL,                      // process security attributes 
                       NULL,                      // primary thread security attributes 
                       TRUE,                      // handles are inherited 
-                      //DETACHED_PROCESS +         // creation flags 
+                      DETACHED_PROCESS +         // creation flags 
                       CREATE_NEW_PROCESS_GROUP,
                       NULL,                      // use parent's environment 
                       NULL,                      // use parent's current directory 
@@ -507,7 +453,7 @@ static DWORD WINAPI MonitorChildThread(LPVOID data)
   WaitForSingleObject(client->hProcess, INFINITE);
 
   GetExitCodeProcess(client->hProcess, &exitCode);
-  printf("Child process terminated with code %d\n", exitCode);
+  printf("Child process terminated with code %lx\n", exitCode);
 
   /* signal the other threads to give up */
   client->bTerminate = TRUE;
@@ -589,7 +535,7 @@ static DWORD WINAPI ReadFromPipeThread(LPVOID data)
   CHAR chBuf[BUFSIZE];
   CHAR txBuf[BUFSIZE*2];
   DWORD from,to;
-  char warning[] = "warning: rl_prep_terminal: cannot get terminal settings";
+  //char warning[] = "warning: rl_prep_terminal: cannot get terminal settings";
 
   client_t *client = (client_t *) data;
 
@@ -682,3 +628,4 @@ static VOID ErrorExit (LPTSTR lpszMessage)
    }
    ExitProcess(0); 
 } 
+