<directory name="arp">
- <xi:include href="arp/arp.xml" />
+ <xi:include href="arp/arp.xml" />
</directory>
<directory name="finger">
- <xi:include href="finger/finger.xml" />
+ <xi:include href="finger/finger.xml" />
</directory>
<directory name="ftp">
- <xi:include href="ftp/ftp.xml" />
+ <xi:include href="ftp/ftp.xml" />
</directory>
<directory name="ipconfig">
- <xi:include href="ipconfig/ipconfig.xml" />
+ <xi:include href="ipconfig/ipconfig.xml" />
</directory>
<directory name="netstat">
- <xi:include href="netstat/netstat.xml" />
+ <xi:include href="netstat/netstat.xml" />
</directory>
<directory name="ping">
- <xi:include href="ping/ping.xml" />
+ <xi:include href="ping/ping.xml" />
</directory>
<directory name="route">
- <xi:include href="route/route.xml" />
+ <xi:include href="route/route.xml" />
+</directory>
+<directory name="tcpsvcs">
+ <xi:include href="tcpsvcs/tcpsvcs.xml" />
</directory>
<directory name="telnet">
- <xi:include href="telnet/telnet.xml" />
+ <xi:include href="telnet/telnet.xml" />
</directory>
<directory name="tracert">
- <xi:include href="tracert/tracert.xml" />
+ <xi:include href="tracert/tracert.xml" />
</directory>
<directory name="whois">
- <xi:include href="whois/whois.xml" />
+ <xi:include href="whois/whois.xml" />
</directory>
#include <stdio.h>
#include <winsock2.h>
#include <tchar.h>
-#include "chargen.h"
-#include "../skelserver/skelserver.h"
+#include "tcpsvcs.h"
DWORD WINAPI ChargenHandler(VOID* Sock_)
{
SOCKET Sock = (SOCKET)Sock_;
if (!GenerateChars(Sock)) {
- _tprintf(_T("Echo incoming packets failed\n"));
+ _tprintf(_T("Char generation failed\n"));
Retval = 3;
}
_tprintf(_T("Shutting connection down...\n"));
- if (ShutdownConnection(Sock)) {
+ if (ShutdownConnection(Sock, FALSE)) {
_tprintf(_T("Connection is down.\n"));
}
else
_tprintf(_T("Connection shutdown failed\n"));
Retval = 3;
}
+ _tprintf(_T("Terminating thread\n"));
+ ExitThread(0);
return Retval;
}
loopIndex; /* line loop */
char ring[END-START];
char *endring;
+ BOOL bLoop = TRUE;
/* fill ring with printable characters */
for (charIndex=0, i=START; i<=END; charIndex++, i++)
/* where we will start output from */
loopIndex = 0;
- while (1)
+ while (bLoop)
{
/* if the loop index is equal to number of chars previously
* printed, start the loop from the beginning */
charIndex = loopIndex;
for (i=0; i<LINESIZ; i++)
{
- SendChar(Sock, ring[charIndex]);
+ /* 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 */
if (ring[charIndex] == *endring)
charIndex = 0;
else
charIndex++;
}
- SendChar(Sock, L'\r');
- SendChar(Sock, L'\n');
+
+ if (bLoop)
+ if ((!SendChar(Sock, L'\r')) || (!SendChar(Sock, L'\n')))
+ return FALSE;
/* increment loop index to start printing from next char in ring */
loopIndex++;
}
- return 0;
+ return TRUE;
}
BOOL SendChar(SOCKET Sock, TCHAR c)
SentBytes = 0;
RetVal = send(Sock, &c, sizeof(TCHAR), 0);
- if (RetVal > 0) {
+ /*FIXME: need to establish if peer closes connection,
+ not just report a socket error */
+ if (RetVal > 0)
+ {
SentBytes += RetVal;
+ return TRUE;
}
- else if (RetVal == SOCKET_ERROR) {
- return FALSE;
- }
- else
+ else if (RetVal == SOCKET_ERROR)
{
- /* Client closed connection before we could reply to
- all the data it sent, so quit early. */
- _tprintf(_T("Peer unexpectedly dropped connection!\n"));
+ _tprintf(("Socket error\n"));
return FALSE;
}
+ else
+ _tprintf(("unknown error\n"));
+ //WSAGetLastError()
_tprintf(("Connection closed by peer.\n"));
return TRUE;
}
-
-
-
-
-
+++ /dev/null
-#define START 32
-#define END 126
-#define LINESIZ 72
-#define BUF 1024
-
-DWORD WINAPI ChargenHandler(VOID* Sock_);
-BOOL GenerateChars(SOCKET Sock);
-BOOL SendChar(SOCKET Sock, CHAR c);
+++ /dev/null
-<module name="chargen" type="win32cui" installbase="system32" installname="chargen.exe">\r
- <include base="arp">.</include>\r
- <define name="__USE_W32API" />\r
- <library>kernel32</library>\r
- <library>iphlpapi</library>\r
- <library>ws2_32</library>\r
- <file>chargen/chargen.c</file>\r
-</module>\r
-\r
--- /dev/null
+#include <stdio.h>
+#include <winsock2.h>
+#include <tchar.h>
+#include <time.h>
+#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 = 3;
+ }
+ _tprintf(_T("Terminating thread\n"));
+ ExitThread(0);
+
+ return 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;
+}
#include <stdio.h>
#include <winsock2.h>
#include <tchar.h>
-#include "echo.h"
-#include "../skelserver/skelserver.h"
+#include "tcpsvcs.h"
DWORD WINAPI EchoHandler(VOID* Sock_)
{
}
_tprintf(_T("Shutting connection down...\n"));
- if (ShutdownConnection(Sock)) {
+ 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;
}
_tprintf(("Connection closed by peer.\n"));
return TRUE;
}
-
+++ /dev/null
-#define BUF 1024
-
-DWORD WINAPI EchoHandler(VOID* Sock_);
-BOOL EchoIncomingPackets(SOCKET Sock);
--- /dev/null
+#include <stdio.h>
+#include <winsock2.h>
+#include <tchar.h>
+#include <time.h>
+#include "tcpsvcs.h"
+
+//these need putting in an RC file.
+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")
+};
+
+DWORD WINAPI QotdHandler(VOID* Sock_)
+{
+ DWORD Retval = 0;
+ SOCKET Sock;
+ INT NumOfQuotes;
+
+ Sock = (SOCKET)Sock_;
+ NumOfQuotes = sizeof(Quotes) / MAX_QUOTE_BUF;
+
+ SendQuote(Sock, Quotes[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 = 3;
+ }
+ _tprintf(_T("Terminating 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;
+}
#include <stdio.h>
#include <winsock2.h>
#include <tchar.h>
-#include "../tcpsvcs.h"
-#include "skelserver.h"
+#include "tcpsvcs.h"
DWORD WINAPI StartServer(LPVOID lpParam)
const TCHAR* HostIP = "127.0.0.1";
DWORD RetVal;
WSADATA wsaData;
- PMYDATA pData;
+ PSERVICES pServices;
- pData = (PMYDATA)lpParam;
+ pServices = (PSERVICES)lpParam;
if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{
return -1;
}
- SOCKET ListeningSocket = SetUpListener(HostIP, htons(pData->Port));
+ SOCKET ListeningSocket = SetUpListener(HostIP, htons(pServices->Port));
if (ListeningSocket == INVALID_SOCKET)
{
_tprintf(_T("error setting up socket\n"));
return 3;
}
- printf("Waiting for connections...\n");
+ _tprintf(_T("Waiting for connections...\n"));
while (1)
{
- AcceptConnections(ListeningSocket, pData->Service);
+ AcceptConnections(ListeningSocket, pServices->Service);
printf("Acceptor restarting...\n");
}
+ /* won't see this yet as we kill the service */
+ _tprintf(_T("Detaching Winsock2...\n"));
WSACleanup();
return 0;
}
{
SOCKET Sock;
SOCKADDR_IN Server;
- DWORD InterfaceAddr = inet_addr(ServAddr);
- if (InterfaceAddr != INADDR_NONE)
+ Sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (Sock != INVALID_SOCKET)
{
- 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)
{
- Server.sin_family = AF_INET;
- Server.sin_addr.s_addr = InterfaceAddr;
- Server.sin_port = Port;
- if (bind(Sock, (SOCKADDR*)&Server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
- {
- listen(Sock, SOMAXCONN);
- return Sock;
- }
- else
- printf("bind() failed\n");
-
+ listen(Sock, SOMAXCONN);
+ return Sock;
}
+ else
+ printf("bind() failed\n");
+
}
return INVALID_SOCKET;
}
{
_tprintf(_T("Accepted connection from %s:%d\n"),
inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
-
+ _tprintf(_T("About to create thread\n"));
CreateThread(0, 0, Service, (void*)Sock, 0, &ThreadID);
}
else
}
}
-BOOL ShutdownConnection(SOCKET Sock)
+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. */
- while (1)
+ if (bRec)
{
char ReadBuffer[BUF];
int NewBytes = recv(Sock, ReadBuffer, BUF, 0);
return FALSE;
else if (NewBytes != 0)
_tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes);
- else
- break;
}
/* Close the socket. */
+++ /dev/null
-#define BUF 1024
-
-DWORD WINAPI StartServer(LPVOID lpParam);
-SOCKET SetUpListener(const char* ServAddr, int Port);
-VOID AcceptConnections(SOCKET ListeningSocket, LPTHREAD_START_ROUTINE Service);
-BOOL EchoIncomingPackets(SOCKET sd);
-BOOL ShutdownConnection(SOCKET Sock);
#include <winsock2.h>
#include <tchar.h>
#include "tcpsvcs.h"
-#include "skelserver/skelserver.h"
-#include "echo/echo.h"
-#include "chargen/chargen.h"
+
+LPTHREAD_START_ROUTINE
+ServiceHandler[NUM_SERVICES] = {
+ EchoHandler,
+ ChargenHandler,
+ DaytimeHandler,
+ NULL,
+ QotdHandler
+};
+
+INT ServicePort[NUM_SERVICES] = {
+ ECHO_PORT,
+ CHARGEN_PORT,
+ DAYTIME_PORT,
+ DISCARD_PORT,
+ QOTD_PORT
+};
int main(int argc, char *argv[])
{
- PMYDATA pData[MAX_THREADS];
- DWORD dwThreadId[MAX_THREADS];
- HANDLE hThread[MAX_THREADS];
+ PSERVICES pServices[NUM_SERVICES];
+ DWORD dwThreadId[NUM_SERVICES];
+ HANDLE hThread[NUM_SERVICES];
INT i;
/* Create MAX_THREADS worker threads. */
- for( i=0; i<MAX_THREADS; i++ )
+ for( i=0; i<NUM_SERVICES; i++ )
{
/* Allocate memory for thread data. */
- pData[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA));
-
- if( pData == NULL )
+ pServices[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SERVICES));
+
+ if( pServices[i] == NULL )
ExitProcess(2);
/* Generate unique data for each thread. */
- pData[0]->Port = ECHO_PORT;
- pData[0]->Service = EchoHandler;
- pData[1]->Port = CHARGEN_PORT;
- pData[1]->Service = ChargenHandler;
+ 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
- pData[i], // argument to thread function
+ pServices[i], // argument to thread function
0, // use default creation flags
&dwThreadId[i]); // returns the thread identifier
}
/* Wait until all threads have terminated. */
- WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);
+ WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE);
/* Close all thread handles upon completion. */
- for(i=0; i<MAX_THREADS; i++)
+ for(i=0; i<NUM_SERVICES; i++)
{
CloseHandle(hThread[i]);
}
return 0;
}
-
+/* default port numbers */
#define ECHO_PORT 7
#define CHARGEN_PORT 19
#define DAYTIME_PORT 13
#define DISCARD_PORT 9
#define QOTD_PORT 17
-#define MAX_THREADS 2
+#define NUM_SERVICES 6
#define BUF_SIZE 255
+#define BUF 1024
-typedef struct _MyData {
+/* 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 72
+
+/* data structure to pass to threads */
+typedef struct _Services {
INT Port;
LPTHREAD_START_ROUTINE Service;
-} MYDATA, *PMYDATA;
+} SERVICES, *PSERVICES;
+
+/* skelserver functions */
+DWORD WINAPI StartServer(LPVOID lpParam);
+SOCKET SetUpListener(const char* ServAddr, int Port);
+VOID AcceptConnections(SOCKET ListeningSocket, LPTHREAD_START_ROUTINE Service);
+BOOL EchoIncomingPackets(SOCKET sd);
+BOOL ShutdownConnection(SOCKET Sock, BOOL bRec);
+
+/* chargen functions */
+DWORD WINAPI ChargenHandler(VOID* Sock_);
+BOOL GenerateChars(SOCKET Sock);
+BOOL SendChar(SOCKET Sock, CHAR c);
+
+/* 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 */
+
+
+/* qotd functions */
+DWORD WINAPI QotdHandler(VOID* Sock_);
+BOOL SendQuote(SOCKET Sock, TCHAR* Quote);
--- /dev/null
+#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 <reactos/version.rc>
-<module name="tcpsvcs" type="win32cui" installbase="system32" installname="tcpsvcs.exe">\r
- <include base="arp">.</include>\r
- <define name="__USE_W32API" />\r
- <library>kernel32</library>\r
- <library>iphlpapi</library>\r
- <library>ws2_32</library>\r
- <library>shlwapi</library>\r
- <file>tcpsvcs.c</file>\r
- <file>skelserver/skelserver.c</file>\r
- <file>echo/echo.c</file>\r
- <file>chargen/chargen.c</file>\r
-</module>\r
-\r
+<module name="tcpsvcs" type="win32cui" installbase="system32" installname="tcpsvcs.exe">
+ <include base="arp">.</include>
+ <define name="__USE_W32API" />
+ <library>kernel32</library>
+ <library>iphlpapi</library>
+ <library>ws2_32</library>
+ <library>shlwapi</library>
+ <file>tcpsvcs.c</file>
+ <file>skelserver.c</file>
+ <file>echo.c</file>
+ <file>chargen.c</file>
+ <file>daytime.c</file>
+ <file>qotd.c</file>
+</module>
+