discard.c
- implemented discard.

chargen.c
- improve efficiency sending full line instead of singular chars.
TCP will generally wait until the packet is full anyway, so it's pointless to keep calling send for each char.

tcpsvcs.c
- implement the beginnings of the code to start tcpsvcs as a service. #if 0'd out at the moment. Fix bug from calling non existant DiscardHandler.

Surely this is enough info to satisfy lkcl this time :p
Modified: trunk/reactos/apps/utils/net/tcpsvcs/chargen.c
Added: trunk/reactos/apps/utils/net/tcpsvcs/discard.c
Modified: trunk/reactos/apps/utils/net/tcpsvcs/echo.c
Modified: trunk/reactos/apps/utils/net/tcpsvcs/qotd.c
Modified: trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c
Modified: trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.h
Modified: trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.xml

Modified: trunk/reactos/apps/utils/net/tcpsvcs/chargen.c
--- trunk/reactos/apps/utils/net/tcpsvcs/chargen.c	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/chargen.c	2005-09-29 20:41:12 UTC (rev 18159)
@@ -8,15 +8,15 @@
     DWORD Retval = 0;
     SOCKET Sock = (SOCKET)Sock_;
 
-    if (!GenerateChars(Sock)) {
+    if (!GenerateChars(Sock))
+    {
         _tprintf(_T("Char generation failed\n"));
         Retval = 3;
     }
 
     _tprintf(_T("Shutting connection down...\n"));
-    if (ShutdownConnection(Sock, FALSE)) {
+    if (ShutdownConnection(Sock, FALSE))
         _tprintf(_T("Connection is down.\n"));
-    }
     else
     {
         _tprintf(_T("Connection shutdown failed\n"));
@@ -31,12 +31,12 @@
 
 BOOL GenerateChars(SOCKET Sock)
 {
-    int i,
-        charIndex, /* internal loop */
-        loopIndex; /* line loop */
+    int i;
+    int charIndex; /* internal loop */
+    int loopIndex; /* line loop */
     char ring[END-START];
     char *endring;
-    BOOL bLoop = TRUE;
+    char Line[LINESIZ];
 
     /* fill ring with printable characters */
     for (charIndex=0, i=START; i<=END; charIndex++, i++)
@@ -46,36 +46,31 @@
 
     /* where we will start output from */
     loopIndex = 0;
-
-    while (bLoop)
+    while (1)
     {
-        /* if the loop index is equal to number of chars previously
-         * printed, start the loop from the beginning */
+        /* 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; i++)
+        for (i=0; i < LINESIZ - 2; i++)
         {
-            /* FIXME: Should send lines instead of chars to improve efficiency
-             * TCP will wait until it fills a packet anway before putting on
-             * the wire, so it's pointless to keep polling send */
-            if (!SendChar(Sock, ring[charIndex]))
-            {
-                return FALSE;
-            }
-            /* if current char equal last char, reset */
+            Line[i] = ring[charIndex];
+
             if (ring[charIndex] == *endring)
                 charIndex = 0;
             else
                 charIndex++;
         }
 
-        if (bLoop)
-            if ((!SendChar(Sock, L'\r')) ||   (!SendChar(Sock, L'\n')))
-                return FALSE;
+        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++;
     }
@@ -83,17 +78,25 @@
     return TRUE;
 }
 
-BOOL SendChar(SOCKET Sock, TCHAR c)
+BOOL SendLine(SOCKET Sock, TCHAR* Line)
 {
     INT RetVal;
     INT SentBytes;
+    INT LineSize;
 
+    LineSize = sizeof(TCHAR) * LINESIZ;
+
     SentBytes = 0;
-    RetVal = send(Sock, &c, sizeof(TCHAR), 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;
     }

Added: trunk/reactos/apps/utils/net/tcpsvcs/discard.c
--- trunk/reactos/apps/utils/net/tcpsvcs/discard.c	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/discard.c	2005-09-29 20:41:12 UTC (rev 18159)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <winsock2.h>
+#include <tchar.h>
+#include "tcpsvcs.h"
+
+DWORD WINAPI DiscardHandler(VOID* Sock_)
+{
+    DWORD Retval = 0;
+    SOCKET Sock = (SOCKET)Sock_;
+
+    if (!RecieveIncomingPackets(Sock))
+    {
+        _tprintf(_T("RecieveIncomingPackets failed\n"));
+        Retval = 3;
+    }
+
+    _tprintf(_T("Shutting connection down...\n"));
+    if (ShutdownConnection(Sock, TRUE))
+    {
+        _tprintf(_T("Connection is down.\n"));
+    }
+    else
+    {
+        _tprintf(_T("Connection shutdown failed\n"));
+        Retval = 3;
+    }
+    _tprintf(_T("Terminating thread\n"));
+    ExitThread(0);
+
+    return 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;
+}

Modified: trunk/reactos/apps/utils/net/tcpsvcs/echo.c
--- trunk/reactos/apps/utils/net/tcpsvcs/echo.c	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/echo.c	2005-09-29 20:41:12 UTC (rev 18159)
@@ -39,21 +39,24 @@
 
     do {
         ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
-        if (ReadBytes > 0) {
+        if (ReadBytes > 0)
+        {
             _tprintf(_T("Received %d bytes from client\n"), ReadBytes);
 
             SentBytes = 0;
-            while (SentBytes < ReadBytes) {
+            while (SentBytes < ReadBytes)
+            {
                 Temp = send(Sock, ReadBuffer + SentBytes,
                         ReadBytes - SentBytes, 0);
-                if (Temp > 0) {
+                if (Temp > 0)
+                {
                     _tprintf(_T("Sent %d bytes back to client\n"), Temp);
                     SentBytes += Temp;
                 }
-                else if (Temp == SOCKET_ERROR) {
+                else if (Temp == SOCKET_ERROR)
                     return FALSE;
-                }
-                else {
+                else
+                {
                     /* Client closed connection before we could reply to
                        all the data it sent, so quit early. */
                     _tprintf(_T("Peer unexpectedly dropped connection!\n"));
@@ -61,9 +64,9 @@
                 }
             }
         }
-        else if (ReadBytes == SOCKET_ERROR) {
+        else if (ReadBytes == SOCKET_ERROR)
             return FALSE;
-        }
+
     } while (ReadBytes != 0);
 
     _tprintf(("Connection closed by peer.\n"));

Modified: trunk/reactos/apps/utils/net/tcpsvcs/qotd.c
--- trunk/reactos/apps/utils/net/tcpsvcs/qotd.c	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/qotd.c	2005-09-29 20:41:12 UTC (rev 18159)
@@ -5,13 +5,15 @@
 #include "tcpsvcs.h"
 
 //these need putting in an RC file.
-TCHAR Quotes[][MAX_QUOTE_BUF] = {
+TCHAR Quotes[][MAX_QUOTE_BUF] =
+{
     _T("\"I have a penchant for mischief, property damage, stalking and cheesecake, of course\" - kjk hyperion"),
     _T("\"Wow! I fixed a setmenu bug.\" - jimtabor"),
     _T("\"if the code is broken though, your free to call it ur own\" - Alex Ionescu"),
     _T("\"i don't know about any bug; none exist; ReactOS is prefect\" - filip2307"),
     _T("\"if you were kernel code, cutler would rewrite you.\" - Alex Ionescu"),
     _T("\"Looks like Hartmut is cleaning out his WC. working copy, that is\" - WaxDragon")
+    _T("\"don't question it ... it's clearly an optimization\" - arty")
 };
 
 DWORD WINAPI QotdHandler(VOID* Sock_)

Modified: trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c
--- trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c	2005-09-29 20:41:12 UTC (rev 18159)
@@ -3,25 +3,39 @@
 #include <tchar.h>
 #include "tcpsvcs.h"
 
+static
 LPTHREAD_START_ROUTINE
-ServiceHandler[NUM_SERVICES] = {
+ServiceHandler[NUM_SERVICES] =
+{
     EchoHandler,
-    ChargenHandler,
+    DiscardHandler,
     DaytimeHandler,
-    NULL,
-    QotdHandler
+    QotdHandler,
+    ChargenHandler
 };
 
-INT ServicePort[NUM_SERVICES] = {
+static int
+ServicePort[NUM_SERVICES] =
+{
     ECHO_PORT,
-    CHARGEN_PORT,
+    DISCARD_PORT,
     DAYTIME_PORT,
-    DISCARD_PORT,
-    QOTD_PORT
+    QOTD_PORT,
+    CHARGEN_PORT
 };
 
-int main(int argc, char *argv[])
+#if 0
+static
+SERVICE_TABLE_ENTRY
+ServiceTable[2] =
 {
+    {TEXT("tcpsvcs"), ServiceMain},
+    {NULL, NULL}
+};
+#endif
+
+int main(void)
+{
     PSERVICES pServices[NUM_SERVICES];
     DWORD dwThreadId[NUM_SERVICES];
     HANDLE hThread[NUM_SERVICES];
@@ -32,7 +46,7 @@
     {
         /* Allocate memory for thread data. */
         pServices[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SERVICES));
-        
+
         if( pServices[i] == NULL )
             ExitProcess(2);
 
@@ -63,6 +77,68 @@
     {
         CloseHandle(hThread[i]);
     }
+    return 0;
+}
 
+#if 0
+static VOID CALLBACK
+ServiceMain(DWORD argc, LPTSTR *argv)
+{
+    PSERVICES pServices[NUM_SERVICES];
+    DWORD dwThreadId[NUM_SERVICES];
+    HANDLE hThread[NUM_SERVICES];
+    INT i;
+
+    /* Create MAX_THREADS worker threads. */
+    for( i=0; i<NUM_SERVICES; i++ )
+    {
+        /* Allocate memory for thread data. */
+        pServices[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SERVICES));
+
+        if( pServices[i] == NULL )
+            ExitProcess(2);
+
+        /* Generate unique data for each thread. */
+        pServices[i]->Service = ServiceHandler[i];
+        pServices[i]->Port = ServicePort[i];
+
+        hThread[i] = CreateThread(
+            NULL,              // default security attributes
+            0,                 // use default stack size
+            StartServer,       // thread function
+            pServices[i],      // argument to thread function
+            0,                 // use default creation flags
+            &dwThreadId[i]);   // returns the thread identifier
+
+        /* Check the return value for success. */
+        if (hThread[i] == NULL)
+        {
+            ExitProcess(i);
+        }
+    }
+
+    /* Wait until all threads have terminated. */
+    WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE);
+
+    /* Close all thread handles upon completion. */
+    for(i=0; i<NUM_SERVICES; i++)
+    {
+        CloseHandle(hThread[i]);
+    }
+
+}
+
+int
+main(int argc, char *argv[])
+{
+    DPRINT("tcpsvcs: main() started\n");
+
+    StartServiceCtrlDispatcher(ServiceTable);
+
+    DPRINT("Umpnpmgr: main() done\n");
+
+    ExitThread(0);
+
     return 0;
 }
+#endif

Modified: trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.h
--- trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.h	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.h	2005-09-29 20:41:12 UTC (rev 18159)
@@ -1,9 +1,9 @@
 /* default port numbers */
 #define ECHO_PORT 7
-#define CHARGEN_PORT 19
+#define DISCARD_PORT 9
 #define DAYTIME_PORT 13
-#define DISCARD_PORT 9
 #define QOTD_PORT 17
+#define CHARGEN_PORT 19
 
 #define NUM_SERVICES 6
 #define BUF_SIZE 255
@@ -17,7 +17,7 @@
 #define END 126
 
 /* number of chars to put on a line */
-#define LINESIZ 72
+#define LINESIZ 74 // 72 + /r and /n
 
 /* data structure to pass to threads */
 typedef struct _Services {
@@ -25,6 +25,9 @@
     LPTHREAD_START_ROUTINE Service;
 } SERVICES, *PSERVICES;
 
+/* tcpsvcs functions */
+//static VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv);
+
 /* skelserver functions */
 DWORD WINAPI StartServer(LPVOID lpParam);
 SOCKET SetUpListener(const char* ServAddr, int Port);
@@ -35,7 +38,7 @@
 /* chargen functions */
 DWORD WINAPI ChargenHandler(VOID* Sock_);
 BOOL GenerateChars(SOCKET Sock);
-BOOL SendChar(SOCKET Sock, CHAR c);
+BOOL SendLine(SOCKET Sock, TCHAR* Line);
 
 /* daytime functions */
 DWORD WINAPI DaytimeHandler(VOID* Sock_);
@@ -46,8 +49,9 @@
 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);

Modified: trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.xml
--- trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.xml	2005-09-29 19:34:53 UTC (rev 18158)
+++ trunk/reactos/apps/utils/net/tcpsvcs/tcpsvcs.xml	2005-09-29 20:41:12 UTC (rev 18159)
@@ -8,8 +8,9 @@
     <file>tcpsvcs.c</file>
     <file>skelserver.c</file>
     <file>echo.c</file>
-    <file>chargen.c</file>
+    <file>discard.c</file>
     <file>daytime.c</file>
     <file>qotd.c</file>
+    <file>chargen.c</file>
+    <file>tcpsvcs.rc</file>
 </module>
-