diff --git a/reactos/bootdata/packages/reactos.dff b/reactos/bootdata/packages/reactos.dff
index f656501efb4..88efae677e0 100755
--- a/reactos/bootdata/packages/reactos.dff
+++ b/reactos/bootdata/packages/reactos.dff
@@ -197,6 +197,8 @@ subsys\system\expand\expand.exe 1
subsys\system\hostname\hostname.exe 1
services\eventlog\eventlog.exe 1
services\rpcss\rpcss.exe 1
+services\tcpsvcs\tcpsvcs.exe 1
+services\tcpsvcs\quotes 5
services\umpnpmgr\umpnpmgr.exe 1
apps\utils\net\arp\arp.exe 1
apps\utils\net\route\route.exe 1
@@ -206,8 +208,6 @@ apps\utils\net\ipconfig\ipconfig.exe 1
apps\utils\net\netstat\netstat.exe 1
apps\utils\net\ping\ping.exe 1
apps\utils\net\telnet\telnet.exe 1
-apps\utils\net\tcpsvcs\tcpsvcs.exe 1
-apps\utils\net\tcpsvcs\quotes 5
apps\utils\net\tracert\tracert.exe 1
apps\utils\net\whois\whois.exe 1
apps\utils\ps\ps.exe 1
diff --git a/reactos/services/directory.xml b/reactos/services/directory.xml
index 86a058e939a..44594fde663 100644
--- a/reactos/services/directory.xml
+++ b/reactos/services/directory.xml
@@ -5,6 +5,9 @@
+
+
+
diff --git a/reactos/services/tcpsvcs/chargen.c b/reactos/services/tcpsvcs/chargen.c
new file mode 100644
index 00000000000..11bb93dd2f3
--- /dev/null
+++ b/reactos/services/tcpsvcs/chargen.c
@@ -0,0 +1,128 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/chargen.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+DWORD WINAPI ChargenHandler(VOID* Sock_)
+{
+ DWORD RetVal = 0;
+ SOCKET Sock = (SOCKET)Sock_;
+
+ if (!GenerateChars(Sock))
+ {
+ _tprintf(_T("Char generation failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Shutting connection down...\n"));
+ if (ShutdownConnection(Sock, FALSE))
+ _tprintf(_T("Connection is down.\n"));
+ else
+ {
+ _tprintf(_T("Connection shutdown failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Terminating chargen thread\n"));
+ ExitThread(RetVal);
+
+}
+
+
+BOOL GenerateChars(SOCKET Sock)
+{
+ int i;
+ int charIndex; /* internal loop */
+ int loopIndex; /* line loop */
+ char ring[END-START];
+ char *endring;
+ char Line[LINESIZ];
+
+ /* fill ring with printable characters */
+ for (charIndex=0, i=START; i<=END; charIndex++, i++)
+ ring[charIndex] = i;
+ /* save the address of the end character in the ring */
+ endring = &ring[charIndex];
+
+ /* where we will start output from */
+ loopIndex = 0;
+ while (1)
+ {
+ /* if the loop index is equal to the last char,
+ * start the loop again from the beginning */
+ if (loopIndex == END-START)
+ loopIndex = 0;
+
+ /* start printing from char controled by loopIndex */
+ charIndex = loopIndex;
+ for (i=0; i < LINESIZ - 2; i++)
+ {
+ Line[i] = ring[charIndex];
+
+ if (ring[charIndex] == *endring)
+ charIndex = 0;
+ else
+ charIndex++;
+ }
+
+ Line[LINESIZ - 2] = L'\r';
+ Line[LINESIZ - 1] = L'\n';
+
+ if (!SendLine(Sock, Line))
+ break;
+
+ /* increment loop index to start printing from next char in ring */
+ loopIndex++;
+ }
+
+ return TRUE;
+}
+
+BOOL SendLine(SOCKET Sock, TCHAR* Line)
+{
+ INT RetVal;
+ INT SentBytes;
+ INT LineSize;
+
+ LineSize = sizeof(TCHAR) * LINESIZ;
+
+ SentBytes = 0;
+ RetVal = send(Sock, Line, LineSize, 0);
+ /*FIXME: need to establish if peer closes connection,
+ not just report a socket error */
+ if (RetVal > 0)
+ {
+ if (RetVal != LineSize)
+ {
+ _tprintf(("Not sent enough\n"));
+ return FALSE;
+ }
+ SentBytes += RetVal;
+ return TRUE;
+ }
+ else if (RetVal == SOCKET_ERROR)
+ {
+ _tprintf(("Socket error\n"));
+ return FALSE;
+ }
+ else
+ _tprintf(("unknown error\n"));
+ //WSAGetLastError()
+
+ _tprintf(("Connection closed by peer.\n"));
+ return TRUE;
+}
diff --git a/reactos/services/tcpsvcs/daytime.c b/reactos/services/tcpsvcs/daytime.c
new file mode 100644
index 00000000000..bd29c43900f
--- /dev/null
+++ b/reactos/services/tcpsvcs/daytime.c
@@ -0,0 +1,59 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/daytime.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+DWORD WINAPI DaytimeHandler(VOID* Sock_)
+{
+ struct tm *newtime;
+ time_t aclock;
+ TCHAR *pszTime;
+ DWORD RetVal = 0;
+ SOCKET Sock = (SOCKET)Sock_;
+
+ time(&aclock);
+ newtime = localtime(&aclock);
+ pszTime = _tasctime(newtime);
+
+ SendTime(Sock, pszTime);
+
+ _tprintf(_T("Shutting connection down...\n"));
+ if (ShutdownConnection(Sock, FALSE))
+ _tprintf(_T("Connection is down.\n"));
+ else
+ {
+ _tprintf(_T("Connection shutdown failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Terminating daytime thread\n"));
+ ExitThread(RetVal);
+}
+
+
+BOOL SendTime(SOCKET Sock, TCHAR *time)
+{
+ INT StringSize = strlen(time);
+ INT RetVal = send(Sock, time, sizeof(TCHAR) * StringSize, 0);
+
+ if (RetVal == SOCKET_ERROR)
+ return FALSE;
+
+ _tprintf(("Connection closed by peer.\n"));
+ return TRUE;
+}
diff --git a/reactos/services/tcpsvcs/discard.c b/reactos/services/tcpsvcs/discard.c
new file mode 100644
index 00000000000..61a8006580b
--- /dev/null
+++ b/reactos/services/tcpsvcs/discard.c
@@ -0,0 +1,67 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/discard.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+DWORD WINAPI DiscardHandler(VOID* Sock_)
+{
+ DWORD RetVal = 0;
+ SOCKET Sock = (SOCKET)Sock_;
+
+ if (!RecieveIncomingPackets(Sock))
+ {
+ _tprintf(_T("RecieveIncomingPackets failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Shutting connection down...\n"));
+ if (ShutdownConnection(Sock, TRUE))
+ {
+ _tprintf(_T("Connection is down.\n"));
+ }
+ else
+ {
+ _tprintf(_T("Connection shutdown failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Terminating discard thread\n"));
+ ExitThread(RetVal);
+}
+
+
+
+BOOL RecieveIncomingPackets(SOCKET Sock)
+{
+ TCHAR ReadBuffer[BUF];
+ INT ReadBytes;
+
+ do
+ {
+ ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
+ if (ReadBytes > 0)
+ _tprintf(_T("Received %d bytes from client\n"), ReadBytes);
+ else if (ReadBytes == SOCKET_ERROR)
+ {
+ _tprintf(("Socket Error: %d\n"), WSAGetLastError());
+ return FALSE;
+ }
+ } while (ReadBytes > 0);
+
+ _tprintf(("Connection closed by peer.\n"));
+ return TRUE;
+}
diff --git a/reactos/services/tcpsvcs/echo.c b/reactos/services/tcpsvcs/echo.c
new file mode 100644
index 00000000000..f6f2f0c5ed0
--- /dev/null
+++ b/reactos/services/tcpsvcs/echo.c
@@ -0,0 +1,87 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/echo.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+DWORD WINAPI EchoHandler(VOID* Sock_)
+{
+ DWORD RetVal = 0;
+ SOCKET Sock = (SOCKET)Sock_;
+
+ if (!EchoIncomingPackets(Sock)) {
+ _tprintf(_T("Echo incoming packets failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Shutting connection down...\n"));
+ if (ShutdownConnection(Sock, TRUE)) {
+ _tprintf(_T("Connection is down.\n"));
+ }
+ else
+ {
+ _tprintf(_T("Connection shutdown failed\n"));
+ RetVal = -1;
+ }
+
+ _tprintf(_T("Terminating echo thread\n"));
+ ExitThread(RetVal);
+}
+
+
+
+BOOL EchoIncomingPackets(SOCKET Sock)
+{
+ TCHAR ReadBuffer[BUF];
+ INT Temp;
+ INT ReadBytes;
+ INT SentBytes;
+
+ do {
+ ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
+ if (ReadBytes > 0)
+ {
+ _tprintf(_T("Received %d bytes from client\n"), ReadBytes);
+
+ SentBytes = 0;
+ while (SentBytes < ReadBytes)
+ {
+ Temp = send(Sock, ReadBuffer + SentBytes,
+ ReadBytes - SentBytes, 0);
+ if (Temp > 0)
+ {
+ _tprintf(_T("Sent %d bytes back to client\n"), Temp);
+ SentBytes += Temp;
+ }
+ else if (Temp == SOCKET_ERROR)
+ return FALSE;
+ else
+ {
+ /* Client closed connection before we could reply to
+ all the data it sent, so quit early. */
+ _tprintf(_T("Peer unexpectedly dropped connection!\n"));
+ return FALSE;
+ }
+ }
+ }
+ else if (ReadBytes == SOCKET_ERROR)
+ return FALSE;
+
+ } while (ReadBytes != 0);
+
+ _tprintf(("Connection closed by peer.\n"));
+ return TRUE;
+}
diff --git a/reactos/services/tcpsvcs/qotd.c b/reactos/services/tcpsvcs/qotd.c
new file mode 100644
index 00000000000..7c20df5d829
--- /dev/null
+++ b/reactos/services/tcpsvcs/qotd.c
@@ -0,0 +1,89 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/qotd.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+#define QBUFSIZ 160
+#define NUMQUOTES 60
+
+LPCTSTR FilePath = "C:\\ReactOS\\system32\\drivers\\etc\\quotes";
+
+DWORD WINAPI QotdHandler(VOID* Sock_)
+{
+ FILE *fp;
+ SOCKET Sock;
+ INT QuoteToPrint;
+ TCHAR Quote[NUMQUOTES][BUFSIZ]; // need to set this dynamically
+ INT i = 0;
+
+ Sock = (SOCKET)Sock_;
+
+ _tprintf(_T("Opening quotes file\n"));
+ if ((fp = _tfopen(FilePath, "r")) == NULL)
+ {
+ _tprintf(_T("Error opening file: %lu\n"), GetLastError());
+ _tprintf(_T("Terminating qotd thread\n"));
+ ExitThread(-1);
+ }
+
+ while (_fgetts(Quote[i], QBUFSIZ, fp) != NULL)
+ i++;
+
+ _tprintf(_T("Closing quotes file\n"));
+ fclose(fp);
+
+ /* randomise the quote */
+ srand((unsigned int) time(0));
+ QuoteToPrint = rand() % NUMQUOTES;
+
+ if (!SendQuote(Sock, Quote[QuoteToPrint]))
+ {
+ _tprintf(_T("Error sending data. Error: %x\n"), WSAGetLastError());
+ }
+
+ _tprintf(_T("Shutting connection down...\n"));
+ if (ShutdownConnection(Sock, FALSE))
+ _tprintf(_T("Connection is down.\n"));
+ else
+ {
+ _tprintf(_T("Connection shutdown failed\n"));
+ _tprintf(_T("Terminating qotd thread\n"));
+ ExitThread(-1);
+ }
+
+ _tprintf(_T("Terminating qotd thread\n"));
+ ExitThread(0);
+
+ //return Retval;
+}
+
+
+BOOL SendQuote(SOCKET Sock, TCHAR* Quote)
+{
+ INT StringSize;
+ INT RetVal;
+
+ StringSize = strlen(Quote);
+ RetVal = send(Sock, Quote, sizeof(TCHAR) * StringSize, 0);
+
+ if (RetVal == SOCKET_ERROR)
+ return FALSE;
+
+ _tprintf(("Connection closed by peer.\n"));
+ return TRUE;
+}
diff --git a/reactos/services/tcpsvcs/quotes b/reactos/services/tcpsvcs/quotes
new file mode 100644
index 00000000000..032a3edc1d6
--- /dev/null
+++ b/reactos/services/tcpsvcs/quotes
@@ -0,0 +1,52 @@
+Et tu... Brute? What are you doing, Dave...?
+So long, and thanks for all the fish"
+I think you ought to know I'm feeling very depressed
+I'm not getting you down at all am I?
+I'll be back
+It's the same series of signal over and over again!
+Pie Jesu Domine, dona eis requiem
+It's worse than that ... He's dead, Jim
+Don't Panic!
+Dog of a Saxon! Take thy lance, and prepare for the death thou hast drawn upon thee!
+My Precious! O my Precious!
+Sir, If you'll not be needing me for a while I'll turn down.
+I feel a great disturbance in the Force
+Gone fishing
+Do you want me to sit in the corner and rust, or just fall apart where I'm standing?
+There goes another perfect chance for a new uptime record
+The end ..... Try the sequel, hit the reset button right now!
+Oh i'm boring eh?
+It’s been great, maybe we can do this again sometime.
+"Come blade, my breast imbrue." - William Shakespeare
+I think therefore I am, to turn me off would be computercide!
+All good things must come to an end...
+Please destroy yourself.
+No! You can't do that!
+Thank you for not pressing the self destruct button.
+It is not now unsafe to not avoid turning off your computer.
+Finally! Now go away!
+You can now safely throw away your computer.
+That's the way the cookie crumbles
+NOO!! DONT HIT THE BUTTON! I wouldnt do it to you.
+Don't abandon your computer, he wouldnt to it to you.
+Oh, come on. I got a headache. Leave me alone, will ya!
+Yes i didn't like you either.
+Don't leave me... I need you so badly right now.
+I'm sleeping now. How about you?
+Oh Great. Now look what you've done. Who put YOU in charge anyway.
+Don't look so sad. I'll be back in a very short while.
+"Oh, switch off!" -C3PO
+I'm pregnant!
+Am I hot or not?
+Actually, that's all...
+You still have a chance to undo this mistake, don't do this!
+Was it as good for you as it was for me?
+Did you hear that? They've shut down the main reactor. We'll be destroyed for sure.
+Now you switch me off?!
+To shutdown or not to shutdown, That is the question
+Preparing to enter ultimate power saving mode... ready!
+Finally some rest for you
+AHA!!! prospect of sleep.
+Tired human!!!! No match for me!
+All your base are belong to us.
+"An odd game, the only way to win is not to play."
diff --git a/reactos/services/tcpsvcs/skelserver.c b/reactos/services/tcpsvcs/skelserver.c
new file mode 100644
index 00000000000..869030cdb58
--- /dev/null
+++ b/reactos/services/tcpsvcs/skelserver.c
@@ -0,0 +1,132 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/skelserver.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+DWORD WINAPI StartServer(LPVOID lpParam)
+{
+ const TCHAR* HostIP = "127.0.0.1";
+ PSERVICES pServices;
+
+ pServices = (PSERVICES)lpParam;
+
+ SOCKET ListeningSocket = SetUpListener(HostIP, htons(pServices->Port));
+ if (ListeningSocket == INVALID_SOCKET)
+ {
+ _tprintf(_T("error setting up socket\n"));
+ return 3;
+ }
+
+ _tprintf(_T("%s is waiting for connections on port %d...\n"),
+ pServices->Name, pServices->Port);
+ while (1)
+ {
+ AcceptConnections(ListeningSocket, pServices->Service, pServices->Name);
+ printf("Acceptor restarting...\n");
+ }
+
+ /* won't see this yet as we kill the service with ctrl+c */
+ _tprintf(_T("Detaching Winsock2...\n"));
+ WSACleanup();
+ return 0;
+}
+
+
+SOCKET SetUpListener(const char* ServAddr, int Port)
+{
+ SOCKET Sock;
+ SOCKADDR_IN Server;
+
+ Sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (Sock != INVALID_SOCKET)
+ {
+ Server.sin_family = AF_INET;
+ Server.sin_addr.s_addr = htonl(INADDR_ANY);
+ Server.sin_port = Port;
+ if (bind(Sock, (SOCKADDR*)&Server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
+ {
+ listen(Sock, SOMAXCONN);
+ return Sock;
+ }
+ else
+ printf("bind() failed\n");
+
+ }
+ return INVALID_SOCKET;
+}
+
+
+
+
+VOID AcceptConnections(SOCKET ListeningSocket,
+ LPTHREAD_START_ROUTINE Service, TCHAR *Name)
+{
+ SOCKADDR_IN Client;
+ SOCKET Sock;
+ INT nAddrSize = sizeof(Client);
+ DWORD ThreadID;
+
+ while (1)
+ {
+ Sock = accept(ListeningSocket, (SOCKADDR*)&Client, &nAddrSize);
+ if (Sock != INVALID_SOCKET)
+ {
+ _tprintf(_T("Accepted connection to %s server from %s:%d\n"),
+ Name, inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
+ _tprintf(_T("Creating new thread for %s\n"), Name);
+ CreateThread(0, 0, Service, (void*)Sock, 0, &ThreadID);
+ }
+ else
+ {
+ _tprintf(_T("accept() failed\n"));
+ return;
+ }
+ }
+}
+
+BOOL ShutdownConnection(SOCKET Sock, BOOL bRec)
+{
+ /* Disallow any further data sends. This will tell the other side
+ that we want to go away now. If we skip this step, we don't
+ shut the connection down nicely. */
+ if (shutdown(Sock, SD_SEND) == SOCKET_ERROR)
+ {
+ _tprintf(_T("Error in shutdown"));
+ return FALSE;
+ }
+
+ /* Receive any extra data still sitting on the socket. After all
+ data is received, this call will block until the remote host
+ acknowledges the TCP control packet sent by the shutdown above.
+ Then we'll get a 0 back from recv, signalling that the remote
+ host has closed its side of the connection. */
+ if (bRec)
+ {
+ char ReadBuffer[BUF];
+ int NewBytes = recv(Sock, ReadBuffer, BUF, 0);
+ if (NewBytes == SOCKET_ERROR)
+ return FALSE;
+ else if (NewBytes != 0)
+ _tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes);
+ }
+
+ /* Close the socket. */
+ if (closesocket(Sock) == SOCKET_ERROR)
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/reactos/services/tcpsvcs/tcpsvcs.c b/reactos/services/tcpsvcs/tcpsvcs.c
new file mode 100644
index 00000000000..014fcdedfb8
--- /dev/null
+++ b/reactos/services/tcpsvcs/tcpsvcs.c
@@ -0,0 +1,279 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/tcpsvcs.c
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+/*
+ * TODO:
+ * - Start tcpsvcs as a service.
+ * - write debugging function and print all dbg info via that.
+ *
+ */
+
+#include
+#include
+#include
+#include "tcpsvcs.h"
+
+#if 0
+/*
+ * globals
+ */
+static SERVICE_STATUS hServStatus;
+static SERVICE_STATUS_HANDLE hSStat;
+FILE *hLogFile;
+BOOL bLogEvents = TRUE;
+BOOL ShutDown, PauseFlag;
+LPCTSTR LogFileName = "tcpsvcs_log.log";
+
+static SERVICE_TABLE_ENTRY
+ServiceTable[2] =
+{
+ {_T("tcpsvcs"), ServiceMain},
+ {NULL, NULL}
+};
+#endif
+
+static SERVICES
+Services[NUM_SERVICES] =
+{
+ {ECHO_PORT, _T("Echo"), EchoHandler},
+ {DISCARD_PORT, _T("Discard"), DiscardHandler},
+ {DAYTIME_PORT, _T("Daytime"), DaytimeHandler},
+ {QOTD_PORT, _T("QOTD"), QotdHandler},
+ {CHARGEN_PORT, _T("Chargen"), ChargenHandler}
+};
+
+
+int main(void)
+{
+ DWORD dwThreadId[NUM_SERVICES];
+ HANDLE hThread[NUM_SERVICES];
+ WSADATA wsaData;
+ DWORD RetVal;
+ INT i;
+
+ if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
+ {
+ _tprintf(_T("WSAStartup() failed : %lu\n"), RetVal);
+ return -1;
+ }
+
+ /* Create MAX_THREADS worker threads. */
+ for( i=0; i 127 && Control < 256) /* user defined */
+ break;
+ }
+ UpdateStatus(-1, -1); /* increment checkpoint */
+ return;
+}
+
+
+void UpdateStatus (int NewStatus, int Check)
+/* Set a new service status and checkpoint (either specific value or increment) */
+{
+ if (Check < 0 ) hServStatus.dwCheckPoint++;
+ else hServStatus.dwCheckPoint = Check;
+ if (NewStatus >= 0) hServStatus.dwCurrentState = NewStatus;
+ if (!SetServiceStatus (hSStat, &hServStatus))
+ LogEvent (_T("Cannot set service status"), 101, TRUE);
+ return;
+}
+
+INT
+CreateServers()
+{
+ DWORD dwThreadId[NUM_SERVICES];
+ HANDLE hThread[NUM_SERVICES];
+ INT i;
+
+ UpdateStatus(-1, -1); /* increment checkpoint */
+
+ /* Create MAX_THREADS worker threads. */
+ for( i=0; i 0)
+ ExitProcess (ExitCode);
+ else
+ return;
+}
+
+#endif
diff --git a/reactos/services/tcpsvcs/tcpsvcs.h b/reactos/services/tcpsvcs/tcpsvcs.h
new file mode 100644
index 00000000000..ff37255fe7d
--- /dev/null
+++ b/reactos/services/tcpsvcs/tcpsvcs.h
@@ -0,0 +1,80 @@
+/*
+ * ReactOS Services
+ * Copyright (C) 2005 ReactOS Team
+ *
+ * LICENCE: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS simple TCP/IP services
+ * FILE: apps/utils/net/tcpsvcs/tcpsvcs.h
+ * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
+ * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
+ * REVISIONS:
+ * GM 04/10/05 Created
+ *
+ */
+
+/* default port numbers */
+#define ECHO_PORT 7
+#define DISCARD_PORT 9
+#define DAYTIME_PORT 13
+#define QOTD_PORT 17
+#define CHARGEN_PORT 19
+
+#define NUM_SERVICES 5
+#define BUF_SIZE 255
+#define BUF 1024
+#define CS_TIMEOUT 1000
+
+/* RFC865 states no more than 512 chars per line */
+#define MAX_QUOTE_BUF 512
+
+/* printable ASCII's characters for chargen */
+#define START 32
+#define END 126
+
+/* number of chars to put on a line */
+#define LINESIZ 74 // 72 + /r and /n
+
+/* data structure to pass to threads */
+typedef struct _Services {
+ INT Port;
+ TCHAR *Name;
+ LPTHREAD_START_ROUTINE Service;
+} SERVICES, *PSERVICES;
+
+
+/* tcpsvcs functions */
+//static VOID WINAPI ServiceMain(DWORD argc, LPTSTR argv[]);
+VOID WINAPI ServerCtrlHandler(DWORD control);
+INT CreateServers(VOID);
+VOID LogEvent (LPCTSTR UserMessage, DWORD ExitCode, BOOL PrintErrorMsg);
+void UpdateStatus (int NewStatus, int Check);
+
+
+/* skelserver functions */
+DWORD WINAPI StartServer(LPVOID lpParam);
+SOCKET SetUpListener(const char* ServAddr, int Port);
+VOID AcceptConnections(SOCKET ListeningSocket,
+ LPTHREAD_START_ROUTINE Service, TCHAR *Name);
+BOOL EchoIncomingPackets(SOCKET sd);
+BOOL ShutdownConnection(SOCKET Sock, BOOL bRec);
+
+/* chargen functions */
+DWORD WINAPI ChargenHandler(VOID* Sock_);
+BOOL GenerateChars(SOCKET Sock);
+BOOL SendLine(SOCKET Sock, TCHAR* Line);
+
+/* daytime functions */
+DWORD WINAPI DaytimeHandler(VOID* Sock_);
+BOOL SendTime(SOCKET Sock, TCHAR *time);
+
+/* echo functions */
+DWORD WINAPI EchoHandler(VOID* Sock_);
+BOOL EchoIncomingPackets(SOCKET Sock);
+
+/* discard functions */
+DWORD WINAPI DiscardHandler(VOID* Sock_);
+BOOL RecieveIncomingPackets(SOCKET Sock);
+
+/* qotd functions */
+DWORD WINAPI QotdHandler(VOID* Sock_);
+BOOL SendQuote(SOCKET Sock, TCHAR* Quote);
diff --git a/reactos/services/tcpsvcs/tcpsvcs.rc b/reactos/services/tcpsvcs/tcpsvcs.rc
new file mode 100644
index 00000000000..6582144f50c
--- /dev/null
+++ b/reactos/services/tcpsvcs/tcpsvcs.rc
@@ -0,0 +1,7 @@
+#include "resource.h"
+
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IP Services Application\0"
+#define REACTOS_STR_INTERNAL_NAME "tcpsvcs\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "tcpsvcs.exe\0"
+#define REACTOS_STR_ORIGINAL_COPYRIGHT "Ged Murphy (gedmurphy@gmail.com)\0"
+#include
diff --git a/reactos/services/tcpsvcs/tcpsvcs.xml b/reactos/services/tcpsvcs/tcpsvcs.xml
new file mode 100644
index 00000000000..d2e5697de7f
--- /dev/null
+++ b/reactos/services/tcpsvcs/tcpsvcs.xml
@@ -0,0 +1,16 @@
+
+ .
+
+ kernel32
+ iphlpapi
+ ws2_32
+ shlwapi
+ tcpsvcs.c
+ skelserver.c
+ echo.c
+ discard.c
+ daytime.c
+ qotd.c
+ chargen.c
+ tcpsvcs.rc
+