Author: gedmurphy
Date: Wed Apr 2 11:54:55 2008
New Revision: 32819
URL:
http://svn.reactos.org/svn/reactos?rev=32819&view=rev
Log:
Complete rewrite of the tcpsvcs service in response to me doing some network stress
testing.
It now supports multiple connections from multiple clients across all services.
For anyone interested in doing some network stress testing, start the simple tcp/ip
services from the service manager, then run 'telnet <ip> 19' from a
networked machine. Other ports to try are 7, 9, 13 and 17. Have fun.
Added:
trunk/reactos/base/services/tcpsvcs/log.c (with props)
Modified:
trunk/reactos/base/services/tcpsvcs/chargen.c
trunk/reactos/base/services/tcpsvcs/daytime.c
trunk/reactos/base/services/tcpsvcs/discard.c
trunk/reactos/base/services/tcpsvcs/echo.c
trunk/reactos/base/services/tcpsvcs/qotd.c
trunk/reactos/base/services/tcpsvcs/quotes
trunk/reactos/base/services/tcpsvcs/skelserver.c
trunk/reactos/base/services/tcpsvcs/tcpsvcs.c
trunk/reactos/base/services/tcpsvcs/tcpsvcs.h
trunk/reactos/base/services/tcpsvcs/tcpsvcs.rbuild
Modified: trunk/reactos/base/services/tcpsvcs/chargen.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/char…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/chargen.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/chargen.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -2,122 +2,119 @@
* PROJECT: ReactOS simple TCP/IP services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/chargen.c
- * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * PURPOSE: Sends continous lines of chars to the client
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)reactos.org>
*
*/
#include "tcpsvcs.h"
-extern BOOL bShutDown;
+/* printable ASCII's characters for chargen */
+#define ASCII_START 32
+#define ASCII_END 126
+#define NUM_CHARS ASCII_END - ASCII_START
-BOOL SendLine(SOCKET Sock, char* Line)
+/* number of chars to put on a line */
+#define LINESIZE 74 // 72 + CR + NL
+
+static BOOL
+SendLine(SOCKET sock, LPSTR lpLine)
{
- INT RetVal;
- INT SentBytes;
- INT LineSize;
+ BOOL bRet = FALSE;
- 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)
+ /*FIXME: need to establish if peer closes connection, not just report a socket error
*/
+ INT retVal = send(sock, lpLine, LINESIZE, 0);
+ if (retVal > 0)
{
- if (RetVal != LineSize)
+ if (retVal == LINESIZE)
{
- LogEvent(_T("Chargen: Not sent enough bytes\n"), 0, FALSE);
- return FALSE;
+ bRet = TRUE;
}
- SentBytes += RetVal;
- return TRUE;
+ else
+ {
+ LogEvent(_T("Chargen: Not sent enough bytes"), 0, 0, LOG_FILE);
+ }
}
- else if (RetVal == SOCKET_ERROR)
+ else if (retVal == SOCKET_ERROR)
{
- LogEvent(_T("Chargen: Socket error\n"), 0, FALSE);
- return FALSE;
+ LogEvent(_T("Chargen: Socket error\n"), WSAGetLastError(), 0,
LOG_ERROR);
}
else
- LogEvent(_T("Chargen: unknown error\n"), 0, FALSE);
- // return FALSE;
+ {
+ LogEvent(_T("Chargen: unknown error\n"), WSAGetLastError(), 0,
LOG_ERROR);
+ }
- LogEvent(_T("Chargen: Connection closed by peer.\n"), 0, FALSE);
- return TRUE;
+ return bRet;;
}
-BOOL GenerateChars(SOCKET Sock)
+static BOOL
+GenerateChars(SOCKET sock)
{
- int i;
- int charIndex; /* internal loop */
- int loopIndex; /* line loop */
- char ring[ASCII_END - ASCII_START];
- char *endring;
- char Line[LINESIZ];
+ CHAR chars[NUM_CHARS];
+ CHAR line[LINESIZE];
+ INT charIndex;
+ INT loopIndex;
+ INT i;
- /* fill ring with printable characters */
- for (charIndex=0, i=ASCII_START; i<=ASCII_END; charIndex++, i++)
- ring[charIndex] = (char)i;
- /* save the address of the end character in the ring */
- endring = &ring[charIndex];
+ /* fill the array with printable characters */
+ for (charIndex = 0, i = ASCII_START; i <= ASCII_END; charIndex++, i++)
+ chars[charIndex] = (char)i;
- /* where we will start output from */
loopIndex = 0;
- while (! bShutDown)
+ while (!bShutdown)
{
- /* if the loop index is equal to the last char,
- * start the loop again from the beginning */
- if (loopIndex == ASCII_END-ASCII_START)
+ /* reset the loop when we hit the last char */
+ if (loopIndex == NUM_CHARS)
loopIndex = 0;
- /* start printing from char controled by loopIndex */
+ /* fill a line array to send */
charIndex = loopIndex;
- for (i=0; i < LINESIZ - 2; i++)
+ for (i=0; i < LINESIZE - 2; i++)
{
- Line[i] = ring[charIndex];
+ line[i] = chars[charIndex];
- if (ring[charIndex] == *endring)
+ /* if we hit the end char, reset it */
+ if (chars[charIndex] == chars[NUM_CHARS])
charIndex = 0;
else
charIndex++;
}
+ line[LINESIZE - 2] = '\r';
+ line[LINESIZE - 1] = '\n';
- Line[LINESIZ - 2] = '\r';
- Line[LINESIZ - 1] = '\n';
-
- if (! SendLine(Sock, Line))
+ if (!SendLine(sock, line))
break;
- /* increment loop index to start printing from next char in ring */
+ /* start printing from next char in the array */
loopIndex++;
}
- if (bShutDown)
- return FALSE;
- else
- return TRUE;
+ return TRUE;
}
-DWORD WINAPI ChargenHandler(VOID* Sock_)
+DWORD WINAPI
+ChargenHandler(VOID* sock_)
{
- INT RetVal = 0;
- SOCKET Sock = (SOCKET)Sock_;
+ INT retVal = 0;
+ SOCKET sock = (SOCKET)sock_;
- if (!GenerateChars(Sock))
+ if (!GenerateChars(sock))
{
- LogEvent(_T("Chargen: Char generation failed\n"), 0, FALSE);
- RetVal = 1;
+ LogEvent(_T("Chargen: Char generation failed"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("Chargen: Shutting connection down...\n"), 0, FALSE);
- if (ShutdownConnection(Sock, FALSE))
- LogEvent(_T("Chargen: Connection is down.\n"), 0, FALSE);
+ LogEvent(_T("Chargen: Shutting connection down..."), 0, 0, LOG_FILE);
+ if (ShutdownConnection(sock, FALSE))
+ {
+ LogEvent(_T("Chargen: Connection is down"), 0, 0, LOG_FILE);
+ }
else
{
- LogEvent(_T("Chargen: Connection shutdown failed\n"), 0, FALSE);
- RetVal = 1;
+ LogEvent(_T("Chargen: Connection shutdown failed"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("Chargen: Terminating thread\n"), 0, FALSE);
- ExitThread(RetVal);
+ LogEvent(_T("Chargen: Terminating thread"), 0, 0, LOG_FILE);
+ ExitThread(retVal);
}
Modified: trunk/reactos/base/services/tcpsvcs/daytime.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/dayt…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/daytime.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/daytime.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -2,49 +2,54 @@
* PROJECT: ReactOS simple TCP/IP services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/daytime.c
- * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * PURPOSE: Sends the current date and time to the client
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)reactos.org>
*
*/
#include "tcpsvcs.h"
-BOOL SendTime(SOCKET Sock, CHAR *time)
+static BOOL
+SendTime(SOCKET sock, CHAR *time)
{
- INT StringSize = (INT)strlen(time);
- INT RetVal = send(Sock, time, sizeof(CHAR) * StringSize, 0);
+ DWORD stringSize = strlen(time) + 1;
+ if (send(sock, time, stringSize, 0) == SOCKET_ERROR)
+ {
+ LogEvent(_T("DayTime: Error sending data"), WSAGetLastError(), 0,
LOG_ERROR);
+ return FALSE;
+ }
- if (RetVal == SOCKET_ERROR)
- return FALSE;
-
- LogEvent(_T("DayTime: Connection closed by peer.\n"), 0, FALSE);
return TRUE;
}
-DWORD WINAPI DaytimeHandler(VOID* Sock_)
+DWORD WINAPI
+DaytimeHandler(VOID* Sock_)
{
- struct tm *newtime;
+ struct tm *localTime;
time_t aclock;
CHAR *pszTime;
- DWORD RetVal = 0;
+ DWORD retVal = 0;
SOCKET Sock = (SOCKET)Sock_;
time(&aclock);
- newtime = localtime(&aclock);
- pszTime = asctime(newtime);
+ localTime = localtime(&aclock);
+ if (localTime)
+ {
+ pszTime = asctime(localTime);
+ if (!SendTime(Sock, pszTime))
+ retVal = 1;
+ }
- SendTime(Sock, pszTime);
-
- LogEvent(_T("DayTime: Shutting connection down...\n"), 0, FALSE);
+ LogEvent(_T("DayTime: Shutting connection down"), 0, 0, LOG_FILE);
if (ShutdownConnection(Sock, FALSE))
- LogEvent(_T("DayTime: Connection is down.\n"), 0, FALSE);
+ LogEvent(_T("DayTime: Connection is down"), 0, 0, LOG_FILE);
else
{
- LogEvent(_T("DayTime: Connection shutdown failed\n"), 0, FALSE);
- RetVal = 1;
+ LogEvent(_T("DayTime: Connection shutdown failed"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("DayTime: Terminating thread\n"), 0, FALSE);
- ExitThread(RetVal);
+ LogEvent(_T("DayTime: Terminating thread"), 0, 0, LOG_FILE);
+ ExitThread(retVal);
}
Modified: trunk/reactos/base/services/tcpsvcs/discard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/disc…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/discard.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/discard.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -2,63 +2,67 @@
* PROJECT: ReactOS simple TCP/IP services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/discard.c
- * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * PURPOSE: Recieves input from a client and discards it
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)reactos.org>
*
*/
#include "tcpsvcs.h"
-extern BOOL bShutDown;
+#define BUFSIZE 1024
-BOOL RecieveIncomingPackets(SOCKET Sock)
+static BOOL
+RecieveIncomingPackets(SOCKET sock)
{
- char ReadBuffer[BUF];
- TCHAR buf[256];
- INT ReadBytes;
+ char readBuffer[BUFSIZE];
+ INT readBytes;
do
{
- ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
- if (ReadBytes > 0)
+ readBytes = recv(sock, readBuffer, BUFSIZE, 0);
+ if (readBytes > 0)
{
- _stprintf(buf, _T("Received %d bytes from client\n"), ReadBytes);
- LogEvent(buf, 0, FALSE);
+ TCHAR logBuf[256];
+
+ _stprintf(logBuf, _T("Discard: Received %d bytes from client"),
readBytes);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
}
- else if (ReadBytes == SOCKET_ERROR)
+ else if (readBytes == SOCKET_ERROR)
{
- _stprintf(buf, _T("Socket Error: %d\n"), WSAGetLastError());
- LogEvent(buf, 0, TRUE);
+ LogEvent(_T("Discard: Socket Error"), WSAGetLastError(), 0,
LOG_ERROR);
return FALSE;
}
- } while ((ReadBytes > 0) && (! bShutDown));
+ } while ((readBytes > 0) && (!bShutdown));
- if (! bShutDown)
- LogEvent(_T("Discard: Connection closed by peer.\n"), 0, FALSE);
+ if (!bShutdown)
+ LogEvent(_T("Discard: Connection closed by peer"), 0, 0, LOG_FILE);
return TRUE;
}
-DWORD WINAPI DiscardHandler(VOID* Sock_)
+DWORD WINAPI
+DiscardHandler(VOID* sock_)
{
- DWORD RetVal = 0;
- SOCKET Sock = (SOCKET)Sock_;
+ DWORD retVal = 0;
+ SOCKET sock = (SOCKET)sock_;
- if (!RecieveIncomingPackets(Sock))
+ if (!RecieveIncomingPackets(sock))
{
- LogEvent(_T("Discard: RecieveIncomingPackets failed\n"), 0, FALSE);
- RetVal = 1;
+ LogEvent(_T("Discard: RecieveIncomingPackets failed"), 0, 0,
LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("Discard: Shutting connection down...\n"), 0, FALSE);
- if (ShutdownConnection(Sock, TRUE))
- LogEvent(_T("Discard: Connection is down.\n"), 0, FALSE);
+ LogEvent(_T("Discard: Shutting connection down"), 0, 0, LOG_FILE);
+ if (ShutdownConnection(sock, TRUE))
+ {
+ LogEvent(_T("Discard: Connection is down."), 0, 0, LOG_FILE);
+ }
else
{
- LogEvent(_T("Discard: Connection shutdown failed\n"), 0, FALSE);
- RetVal = 1;
+ LogEvent(_T("Discard: Connection shutdown failed"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("Discard: Terminating thread\n"), 0, FALSE);
- ExitThread(RetVal);
+ LogEvent(_T("Discard: Terminating thread"), 0, 0, LOG_FILE);
+ ExitThread(retVal);
}
Modified: trunk/reactos/base/services/tcpsvcs/echo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/echo…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/echo.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/echo.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -2,87 +2,93 @@
* PROJECT: ReactOS simple TCP/IP services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/echo.c
- * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * PURPOSE: Returns whatever input the client sends
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)reactos.org>
*
*/
#include "tcpsvcs.h"
-extern BOOL bShutDown;
+#define RECV_BUF 1024
-BOOL EchoIncomingPackets(SOCKET Sock)
+static BOOL
+EchoIncomingPackets(SOCKET sock)
{
- char ReadBuffer[BUF];
- TCHAR buf[256]; // temp for holding LogEvent text
- INT Temp;
- INT ReadBytes;
- INT SentBytes;
+ CHAR readBuffer[RECV_BUF];
+ TCHAR logBuf[256];
+ INT totalSentBytes;
+ INT readBytes;
+ INT retVal;
- do {
- ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
- if (ReadBytes > 0)
+ do
+ {
+ readBytes = recv(sock, readBuffer, RECV_BUF, 0);
+ if (readBytes > 0)
{
- _stprintf(buf, _T("Received %d bytes from client\n"), ReadBytes);
- LogEvent(buf, 0, FALSE);
+ _stprintf(logBuf, _T("Received %d bytes from client"), readBytes);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
- SentBytes = 0;
- while (SentBytes < ReadBytes)
+ totalSentBytes = 0;
+ while (!bShutdown && totalSentBytes < readBytes)
{
- Temp = send(Sock, ReadBuffer + SentBytes,
- ReadBytes - SentBytes, 0);
- if (Temp > 0)
+ retVal = send(sock, readBuffer + totalSentBytes, readBytes -
totalSentBytes, 0);
+ if (retVal > 0)
{
- _stprintf(buf, _T("Sent %d bytes back to client\n"),
Temp);
- LogEvent(buf, 0, FALSE);
- SentBytes += Temp;
+ _stprintf(logBuf, _T("Sent %d bytes back to client"),
retVal);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
+ totalSentBytes += retVal;
}
- else if (Temp == SOCKET_ERROR)
+ else if (retVal == SOCKET_ERROR)
+ {
+ LogEvent(_T("Echo: socket error"), WSAGetLastError(), 0,
LOG_ERROR);
return FALSE;
+ }
else
{
/* Client closed connection before we could reply to
all the data it sent, so quit early. */
- _stprintf(buf, _T("Peer unexpectedly dropped
connection!\n"));
- LogEvent(buf, 0, FALSE);
+ LogEvent(_T("Peer unexpectedly dropped connection!"), 0, 0,
LOG_FILE);
return FALSE;
}
}
}
- else if (ReadBytes == SOCKET_ERROR)
+ else if (readBytes == SOCKET_ERROR)
+ {
+ LogEvent(_T("Echo: socket error"), WSAGetLastError(), 0,
LOG_ERROR);
return FALSE;
+ }
+ } while ((readBytes != 0) && (!bShutdown));
- } while ((ReadBytes != 0) && (! bShutDown));
-
- if (! bShutDown)
- LogEvent(_T("Echo: Connection closed by peer.\n"), 0, FALSE);
-
- if (bShutDown)
- LogEvent(_T("Echo: thread recieved shutdown signal\n"), 0, FALSE);
+ if (!bShutdown)
+ LogEvent(_T("Echo: Connection closed by peer"), 0, 0, LOG_FILE);
return TRUE;
}
-DWORD WINAPI EchoHandler(VOID* Sock_)
+DWORD WINAPI
+EchoHandler(VOID* sock_)
{
- DWORD RetVal = 0;
- SOCKET Sock = (SOCKET)Sock_;
+ DWORD retVal = 0;
+ SOCKET sock = (SOCKET)sock_;
- if (!EchoIncomingPackets(Sock)) {
- LogEvent(_T("Echo: EchoIncomingPackets failed\n"), 0, FALSE);
- RetVal = 1;
+ if (!EchoIncomingPackets(sock))
+ {
+ LogEvent(_T("Echo: EchoIncomingPackets failed"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("Echo: Shutting connection down...\n"), 0, FALSE);
+ LogEvent(_T("Echo: Shutting connection down"), 0, 0, LOG_FILE);
- if (ShutdownConnection(Sock, TRUE))
- LogEvent(_T("Echo: Connection is down\n"), 0, FALSE);
+ if (ShutdownConnection(sock, TRUE))
+ {
+ LogEvent(_T("Echo: Connection is down"), 0, 0, LOG_FILE);
+ }
else
{
- LogEvent(_T("Echo: Connection shutdown failed\n"), 0, FALSE);
- RetVal = 1;
+ LogEvent(_T("Echo: Connection shutdown failed"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("Echo: Terminating thread\n"), 0, FALSE);
- ExitThread(RetVal);
+ LogEvent(_T("Echo: Terminating thread"), 0, 0, LOG_FILE);
+ ExitThread(retVal);
}
Added: trunk/reactos/base/services/tcpsvcs/log.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/log.…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/log.c (added)
+++ trunk/reactos/base/services/tcpsvcs/log.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -1,0 +1,203 @@
+/*
+ * PROJECT: ReactOS simple TCP/IP services
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: /base/services/tcpsvcs/log.c
+ * PURPOSE: Logging functionality for the service
+ * COPYRIGHT: Copyright 2008 Ged Murphy <gedmurphy(a)reactos.org>
+ *
+ */
+
+#include "tcpsvcs.h"
+
+#define DEBUG
+
+static LPTSTR lpEventSource = _T("tcpsvcs");
+static LPCTSTR lpLogFileName = _T("C:\\tcpsvcs_log.log");
+static HANDLE hLogFile;
+
+// needs work
+static VOID
+LogToEventLog(LPCTSTR lpMsg,
+ DWORD errNum,
+ DWORD exitCode,
+ UINT flags)
+{
+ HANDLE hEventLog;
+
+ hEventLog = RegisterEventSource(NULL, lpEventSource);
+ if (hEventLog)
+ {
+ ReportEvent(hEventLog,
+ (flags & LOG_ERROR) ? EVENTLOG_ERROR_TYPE : EVENTLOG_SUCCESS,
+ 0,
+ 0,
+ NULL,
+ 1,
+ 0,
+ &lpMsg,
+ NULL);
+
+ CloseEventLog(hEventLog);
+ }
+}
+
+static BOOL
+OpenLogFile()
+{
+ hLogFile = CreateFile(lpLogFileName,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hLogFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static VOID
+LogToFile(LPCTSTR lpMsg,
+ DWORD errNum,
+ DWORD exitCode,
+ UINT flags)
+{
+ LPTSTR lpFullMsg = NULL;
+ DWORD msgLen;
+
+ if (!OpenLogFile())
+ return;
+
+ msgLen = _tcslen(lpMsg) + 1;
+
+ if (flags & LOG_ERROR)
+ {
+ LPVOID lpSysMsg;
+ DWORD eMsgLen;
+
+ eMsgLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ errNum,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpSysMsg,
+ 0,
+ NULL);
+
+ msgLen = msgLen + eMsgLen + 40;
+
+ lpFullMsg = HeapAlloc(GetProcessHeap(),
+ 0,
+ msgLen * sizeof(TCHAR));
+ if (lpFullMsg)
+ {
+ _sntprintf(lpFullMsg,
+ msgLen,
+ _T("%s : %s\tErrNum = %lu ExitCode = %lu\r\n"),
+ lpMsg,
+ lpSysMsg,
+ errNum,
+ exitCode);
+ }
+
+ LocalFree(lpSysMsg);
+
+ }
+ else
+ {
+ msgLen += 2;
+
+ lpFullMsg = HeapAlloc(GetProcessHeap(),
+ 0,
+ msgLen * sizeof(TCHAR));
+ if (lpFullMsg)
+ {
+ _sntprintf(lpFullMsg,
+ msgLen,
+ _T("%s\r\n"),
+ lpMsg);
+ }
+ }
+
+ if (lpFullMsg)
+ {
+ DWORD bytesWritten;
+
+ SetFilePointer(hLogFile, 0, NULL, FILE_END);
+
+ WriteFile(hLogFile,
+ lpFullMsg,
+ _tcslen(lpFullMsg) * sizeof(TCHAR),
+ &bytesWritten,
+ NULL);
+ if (bytesWritten == 0)
+ {
+ LogToEventLog(_T("Failed to write to log file"),
+ GetLastError(),
+ 0,
+ LOG_EVENTLOG | LOG_ERROR);
+ }
+
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpFullMsg);
+ }
+
+ CloseHandle(hLogFile);
+
+ if (exitCode > 0)
+ ExitProcess(exitCode);
+}
+
+
+
+VOID
+LogEvent(LPCTSTR lpMsg,
+ DWORD errNum,
+ DWORD exitCode,
+ UINT flags)
+{
+#ifdef DEBUG
+ if (flags & LOG_FILE || flags & LOG_ERROR)
+ LogToFile(lpMsg, errNum, exitCode, flags);
+#endif
+ if (flags & LOG_EVENTLOG)
+ LogToEventLog(lpMsg, errNum, exitCode, flags);
+}
+
+VOID
+InitLogging()
+{
+ WCHAR wcBom = 0xFEFF;
+
+ DeleteFile(lpLogFileName);
+
+#ifdef _UNICODE
+ if (OpenLogFile())
+ {
+ DWORD bytesWritten;
+
+ WriteFile(hLogFile,
+ &wcBom,
+ sizeof(WCHAR),
+ &bytesWritten,
+ NULL);
+ if (bytesWritten == 0)
+ {
+ LogToEventLog(_T("Failed to write to log file"),
+ GetLastError(),
+ 0,
+ LOG_EVENTLOG | LOG_ERROR);
+ }
+
+ CloseHandle(hLogFile);
+ }
+#endif
+}
+
+VOID
+UninitLogging()
+{
+ FlushFileBuffers(hLogFile);
+ CloseHandle(hLogFile);
+}
Propchange: trunk/reactos/base/services/tcpsvcs/log.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/services/tcpsvcs/qotd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/qotd…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/qotd.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/qotd.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -2,91 +2,153 @@
* PROJECT: ReactOS simple TCP/IP services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/qotd.c
- * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * PURPOSE: Sends a random quote to the client
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)reactos.org>
*
*/
#include "tcpsvcs.h"
-#define QBUFSIZ 60
+static LPCTSTR lpFilePath = _T("\\drivers\\etc\\quotes");
-LPCTSTR FilePath = _T("\\drivers\\etc\\quotes"); /* 19 chars */
-
-BOOL SendQuote(SOCKET Sock, char* Quote)
+static BOOL
+SendQuote(SOCKET sock, char* Quote)
{
- INT StringSize;
- INT RetVal;
-
- StringSize = (INT)strlen(Quote);
- RetVal = send(Sock, Quote, sizeof(char) * StringSize, 0);
-
- if (RetVal == SOCKET_ERROR)
+ INT strSize = strlen(Quote);
+ if (send(sock, Quote, strSize, 0) == SOCKET_ERROR)
return FALSE;
- LogEvent(_T("QOTD: Connection closed by peer\n"), 0, FALSE);
return TRUE;
}
+static BOOL
+RetrieveQuote(SOCKET sock)
+{
+ HANDLE hFile;
+ TCHAR lpFullPath[MAX_PATH + 20];
+ DWORD dwBytesRead;
+ LPSTR lpQuotes;
+ LPSTR lpStr;
+ DWORD quoteNum;
+ DWORD NumQuotes = 0;
+ INT i;
-DWORD WINAPI QotdHandler(VOID* Sock_)
-{
- FILE *fp;
- SOCKET Sock;
- TCHAR Sys[MAX_PATH + 20];
- char Quote[QBUFSIZ][BUFSIZ]; // need to set this dynamically
- INT QuoteToPrint;
- INT NumQuotes;
+ if(!GetSystemDirectory(lpFullPath, MAX_PATH))
+ {
+ LogEvent(_T("QOTD: Getting system path failed"), GetLastError(), 0,
LOG_FILE);
+ return FALSE;
+ }
+ _tcscat(lpFullPath, lpFilePath);
- Sock = (SOCKET)Sock_;
- if(! GetSystemDirectory(Sys, MAX_PATH))
+ LogEvent(_T("QOTD: Opening quotes file"), 0, 0, LOG_FILE);
+ hFile = CreateFile(lpFullPath,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
{
- LogEvent(_T("QOTD: Getting system path failed.\n"), 0, TRUE);
- ExitThread(1);
+ LogEvent(_T("QOTD: Error opening quotes file"), GetLastError(), 0,
LOG_FILE);
+ }
+ else
+ {
+ DWORD dwSize = GetFileSize(hFile, NULL);
+ lpQuotes = (LPSTR)HeapAlloc(GetProcessHeap(), 0, dwSize);
+ if (!lpQuotes)
+ {
+ CloseHandle(hFile);
+ return FALSE;
+ }
+
+ ReadFile(hFile,
+ lpQuotes,
+ dwSize,
+ &dwBytesRead,
+ NULL);
+ CloseHandle(hFile);
+
+ lpQuotes[dwSize] = 0;
+
+ if (dwBytesRead != dwSize)
+ return FALSE;
+
+ lpStr = lpQuotes;
+ while (*lpStr)
+ {
+ if (*lpStr == '%')
+ NumQuotes++;
+ lpStr++;
+ }
+
+ /* pick a random quote */
+ srand((unsigned int) GetTickCount());
+ quoteNum = rand() % NumQuotes;
+
+ /* retrieve the full quote */
+ lpStr = lpQuotes;
+ for (i = 1; i <= quoteNum; i++)
+ {
+ /* move past proceding quote */
+ lpStr++;
+
+ if (i == quoteNum)
+ {
+ LPSTR lpStart = lpStr;
+
+ while (*lpStr != '%' && *lpStr != '\0')
+ lpStr++;
+
+ *lpStr = 0;
+
+ /* send the quote */
+ if (!SendQuote(sock, lpStart))
+ LogEvent(_T("QOTD: Error sending data"), 0, 0, LOG_FILE);
+ break;
+ }
+ else
+ {
+ while (*lpStr != '%' && *lpStr != '\0')
+ lpStr++;
+
+ /* move past % and RN */
+ lpStr += 3;
+ }
+ }
+
+ return TRUE;
}
- _tcsncat(Sys, FilePath, _tcslen(FilePath));
+ return FALSE;
+}
- LogEvent(_T("QOTD: Opening quotes file\n"), 0, FALSE);
- if ((fp = _tfopen(Sys, _T("r"))) == NULL)
+
+DWORD WINAPI
+QotdHandler(VOID* sock_)
+{
+ SOCKET sock = (SOCKET)sock_;
+ DWORD retVal = 0;
+
+ if (!RetrieveQuote(sock))
{
- TCHAR buf[320];
-
- _sntprintf(buf, 320, _T("QOTD: Error opening quote file : %s\n"), Sys);
- LogEvent(buf, 0, TRUE);
- LogEvent(_T("QOTD: Terminating thread\n"), 0, FALSE);
- ExitThread(1);
+ LogEvent(_T("QOTD: Error retrieving quote"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- /* read all quotes in the file into an array */
- NumQuotes = 0;
- while ((fgets(Quote[NumQuotes], QBUFSIZ, fp) != NULL) &&
- (NumQuotes != QBUFSIZ))
- NumQuotes++;
-
- LogEvent(_T("QOTD: Closing quotes file\n"), 0, FALSE);
- fclose(fp);
-
- /* randomise the quote */
- srand((unsigned int) time(0));
- QuoteToPrint = rand() % NumQuotes;
-
- if (!SendQuote(Sock, Quote[QuoteToPrint]))
- LogEvent(_T("QOTD: Error sending data\n"), 0, TRUE);
-
-
- LogEvent(_T("QOTD: Shutting connection down...\n"), 0, FALSE);
- if (ShutdownConnection(Sock, FALSE))
- LogEvent(_T("QOTD: Connection is down\n"), 0, FALSE);
+ LogEvent(_T("QOTD: Shutting connection down"), 0, 0, LOG_FILE);
+ if (ShutdownConnection(sock, FALSE))
+ {
+ LogEvent(_T("QOTD: Connection is down"), 0, 0, LOG_FILE);
+ }
else
{
- LogEvent(_T("QOTD: Connection shutdown failed\n"), 0, FALSE);
- LogEvent(_T("QOTD: Terminating thread\n"), 0, FALSE);
- ExitThread(1);
+ LogEvent(_T("QOTD: Connection shutdown failed"), 0, 0, LOG_FILE);
+ LogEvent(_T("QOTD: Terminating thread"), 0, 0, LOG_FILE);
+ retVal = 1;
}
- LogEvent(_T("QOTD: Terminating thread\n"), 0, FALSE);
- ExitThread(0);
-
+ LogEvent(_T("QOTD: Terminating thread"), 0, 0, LOG_FILE);
+ ExitThread(retVal);
}
Modified: trunk/reactos/base/services/tcpsvcs/quotes
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/quot…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/quotes [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/quotes [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -1,52 +1,104 @@
-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?
-Its 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."
+"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?
+%
+"Its 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."
+%
Modified: trunk/reactos/base/services/tcpsvcs/skelserver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/skel…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/skelserver.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/skelserver.c [iso-8859-1] Wed Apr 2 11:54:55
2008
@@ -2,149 +2,159 @@
* PROJECT: ReactOS simple TCP/IP services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/skelserver.c
- * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy(a)gmail.com>
+ * PURPOSE: Sets up a server and listens for connections
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)gmail.com>
*
*/
#include "tcpsvcs.h"
-extern BOOL bShutDown;
-extern BOOL bPause;
+#define BUF 1024
static SOCKET
SetUpListener(USHORT Port)
{
- SOCKET Sock;
- SOCKADDR_IN Server;
+ SOCKET sock;
+ SOCKADDR_IN server;
+ BOOL bSetup = FALSE;
- 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 = htonl(INADDR_ANY);
+ server.sin_port = Port;
+
+ if (bind(sock, (SOCKADDR*)&server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
{
- listen(Sock, SOMAXCONN);
- return Sock;
+ if (listen(sock, SOMAXCONN) != SOCKET_ERROR)
+ {
+ bSetup = TRUE;
+ }
+ else
+ {
+ LogEvent(_T("listen() failed"), WSAGetLastError(), 0,
LOG_ERROR);
+ }
}
else
- LogEvent(_T("bind() failed\n"), 0, TRUE);
-
+ {
+ LogEvent(_T("bind() failed"), WSAGetLastError(), 0, LOG_ERROR);
+ }
+ }
+ else
+ {
+ LogEvent(_T("socket() failed"), WSAGetLastError(), 0, LOG_ERROR);
}
- return INVALID_SOCKET;
+ return bSetup ? sock : INVALID_SOCKET;
}
static VOID
-AcceptConnections(SOCKET ListeningSocket,
- LPTHREAD_START_ROUTINE Service,
- TCHAR *Name)
+AcceptConnections(SOCKET listeningSocket,
+ LPTHREAD_START_ROUTINE lpService,
+ LPTSTR lpName)
{
- SOCKADDR_IN Client;
- SOCKET Sock;
+ SOCKADDR_IN client;
+ SOCKET sock;
HANDLE hThread;
- TIMEVAL TimeVal;
- FD_SET ReadFDS;
- INT nAddrSize = sizeof(Client);
- DWORD ThreadID;
- TCHAR buf[256];
- INT TimeOut = 2000;
+ TIMEVAL timeVal;
+ FD_SET readFD;
+ TCHAR logBuf[256];
+ INT timeOut = 2000;
- /* set timeout values */
- TimeVal.tv_sec = TimeOut / 1000;
- TimeVal.tv_usec = TimeOut % 1000;
+ timeVal.tv_sec = timeOut / 1000;
+ timeVal.tv_usec = timeOut % 1000;
- while (!bShutDown)
+ while (!bShutdown)
{
- INT SelRet = 0;
+ INT selRet = 0;
- FD_ZERO(&ReadFDS);
- FD_SET(ListeningSocket, &ReadFDS);
+ FD_ZERO(&readFD);
+ FD_SET(listeningSocket, &readFD);
- SelRet = select(0, &ReadFDS, NULL, NULL, &TimeVal);
- if (SelRet == SOCKET_ERROR)
+ selRet = select(0, &readFD, NULL, NULL, &timeVal);
+ if (selRet > 0)
{
- LogEvent(_T("select failed\n"), 0, TRUE);
- return;
- }
- else if (SelRet > 0)
- {
- /* don't call FD_ISSET if bShutDown flag is set */
- if ((! bShutDown) || (FD_ISSET(ListeningSocket, &ReadFDS)))
+ if (!bShutdown || FD_ISSET(listeningSocket, &readFD))
{
- Sock = accept(ListeningSocket, (SOCKADDR*)&Client, &nAddrSize);
- if (Sock != INVALID_SOCKET)
+ INT addrSize = sizeof(SOCKADDR_IN);
+
+ sock = accept(listeningSocket, (SOCKADDR*)&client, &addrSize);
+ if (sock != INVALID_SOCKET)
{
- _stprintf(buf, _T("Accepted connection to %s server from
%s:%d\n"),
- Name, inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
- LogEvent(buf, 0, FALSE);
- _stprintf(buf, _T("Creating new thread for %s\n"), Name);
- LogEvent(buf, 0, FALSE);
+ _stprintf(logBuf,
+ _T("Accepted connection to %s server from
%s:%d"),
+ lpName,
+ inet_ntoa(client.sin_addr),
+ ntohs(client.sin_port));
+ LogEvent(logBuf, 0, 0, LOG_FILE);
- hThread = CreateThread(0, 0, Service, (void*)Sock, 0,
&ThreadID);
+ _stprintf(logBuf, _T("Creating worker thread for %s"),
lpName);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
- /* Check the return value for success. */
- if (hThread == NULL)
+ if (!bShutdown)
{
- _stprintf(buf, _T("Failed to start worker thread for "
- "the %s server....\n"), Name);
- LogEvent(buf, 0, TRUE);
- }
- else
- {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
+ hThread = CreateThread(0, 0, lpService, (void*)sock, 0, NULL);
+ if (hThread != NULL)
+ {
+ CloseHandle(hThread);
+ }
+ else
+ {
+ _stprintf(logBuf, _T("Failed to start worker thread for
the %s server"),
+ lpName);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
+ }
}
}
else
{
- LogEvent(_T("accept failed\n"), 0, TRUE);
- return;
+ LogEvent(_T("accept failed"), WSAGetLastError(), 0,
LOG_ERROR);
}
}
+ }
+ else if (selRet == SOCKET_ERROR)
+ {
+ LogEvent(_T("select failed"), WSAGetLastError(), 0, LOG_ERROR);
}
}
}
BOOL
-ShutdownConnection(SOCKET Sock,
+ShutdownConnection(SOCKET sock,
BOOL bRec)
{
- TCHAR buf[256];
+ TCHAR logBuf[256];
/* 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)
+ if (shutdown(sock, SD_SEND) == SOCKET_ERROR)
{
- LogEvent(_T("Error in shutdown()\n"), 0, TRUE);
+ LogEvent(_T("Error in shutdown()"), WSAGetLastError(), 0, LOG_ERROR);
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. */
+ /* Receive any extra data still sitting on the socket
+ before we close it */
if (bRec)
{
- char ReadBuffer[BUF];
- int NewBytes = recv(Sock, ReadBuffer, BUF, 0);
- if (NewBytes == SOCKET_ERROR)
- return FALSE;
- else if (NewBytes != 0)
+ CHAR readBuffer[BUF];
+ INT ret;
+
+ do
{
- _stprintf(buf, _T("FYI, received %d unexpected bytes during
shutdown\n"), NewBytes);
- LogEvent(buf, 0, FALSE);
- }
+ ret = recv(sock, readBuffer, BUF, 0);
+ if (ret >= 0)
+ {
+ _stprintf(logBuf, _T("FYI, received %d unexpected bytes during
shutdown"), ret);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
+ }
+ } while (ret > 0);
}
- /* Close the socket. */
- if (closesocket(Sock) == SOCKET_ERROR)
- return FALSE;
+ closesocket(sock);
return TRUE;
}
@@ -153,31 +163,37 @@
DWORD WINAPI
StartServer(LPVOID lpParam)
{
- SOCKET ListeningSocket;
+ SOCKET listeningSocket;
PSERVICES pServices;
- TCHAR buf[256];
+ TCHAR logBuf[256];
pServices = (PSERVICES)lpParam;
- ListeningSocket = SetUpListener(htons(pServices->Port));
- if (ListeningSocket == INVALID_SOCKET)
+ _stprintf(logBuf, _T("Starting %s server"), pServices->Name);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
+
+ if (!bShutdown)
{
- LogEvent(_T("Socket error when setting up listener"), 0, TRUE);
- return 3;
+ listeningSocket = SetUpListener(htons(pServices->Port));
+ if (!bShutdown && listeningSocket != INVALID_SOCKET)
+ {
+ _stprintf(logBuf,
+ _T("%s is waiting for connections on port %d"),
+ pServices->Name,
+ pServices->Port);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
+
+ AcceptConnections(listeningSocket, pServices->Service,
pServices->Name);
+ }
+ else
+ {
+ LogEvent(_T("Socket error when setting up listener"), 0, 0,
LOG_FILE);
+ }
}
- _stprintf(buf,
- _T("%s is waiting for connections on port %d"),
- pServices->Name,
- pServices->Port);
- LogEvent(buf, 0, FALSE);
-
- if (!bShutDown)
- AcceptConnections(ListeningSocket, pServices->Service, pServices->Name);
-
- _stprintf(buf,
+ _stprintf(logBuf,
_T("Exiting %s thread"),
pServices->Name);
- LogEvent(buf, 0, FALSE);
+ LogEvent(logBuf, 0, 0, LOG_FILE);
ExitThread(0);
}
Modified: trunk/reactos/base/services/tcpsvcs/tcpsvcs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/tcps…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/tcpsvcs.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/tcpsvcs.c [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -3,22 +3,22 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: /base/services/tcpsvcs/tcpsvcs.c
* PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
- * COPYRIGHT: Copyright 2005 - 2007 Ged Murphy <gedmurphy(a)reactos.org>
+ * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy(a)reactos.org>
*
*/
#include "tcpsvcs.h"
-#define DEBUG
-
-volatile BOOL bShutDown = FALSE;
+static LPTSTR ServiceName = _T("tcpsvcs");
+
+volatile BOOL bShutdown = FALSE;
volatile BOOL bPause = FALSE;
-static SERVICE_STATUS hServStatus;
-static SERVICE_STATUS_HANDLE hSStat;
-
-LPCTSTR LogFileName = _T("C:\\tcpsvcs_log.log");
-LPTSTR ServiceName = _T("tcpsvcs");
+typedef struct _ServiceInfo
+{
+ SERVICE_STATUS servStatus;
+ SERVICE_STATUS_HANDLE hStatus;
+} SERVICEINFO, *PSERVICEINFO;
static SERVICES
Services[NUM_SERVICES] =
@@ -30,164 +30,36 @@
{CHARGEN_PORT, _T("Chargen"), ChargenHandler}
};
-VOID
-LogEvent(LPCTSTR UserMessage,
- DWORD ExitCode,
- BOOL PrintErrorMsg)
-{
-#ifdef DEBUG
- DWORD eMsgLen;
- DWORD ErrNum;
- LPTSTR lpvSysMsg;
- TCHAR MessageBuffer[512];
- FILE *hLogFile = NULL;
-
- hLogFile = _tfopen(LogFileName, _T("a"));
- if (hLogFile == NULL) return;
-
- if (PrintErrorMsg)
- {
- ErrNum = GetLastError();
- eMsgLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- ErrNum,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)&lpvSysMsg,
- 0,
- NULL);
-
- _stprintf(MessageBuffer,
- _T("\n%s %s ErrNum = %lu ExitCode = %lu"),
- UserMessage,
- lpvSysMsg,
- ErrNum,
- ExitCode);
-
- HeapFree(GetProcessHeap(),
- 0,
- lpvSysMsg);
-
- }
+
+static VOID
+UpdateStatus(PSERVICEINFO pServInfo,
+ DWORD NewStatus,
+ DWORD Check)
+{
+ TCHAR szSet[50];
+
+ if (Check > 0)
+ pServInfo->servStatus.dwCheckPoint += Check;
else
- {
- _stprintf(MessageBuffer,
- _T("\n%s"),
- UserMessage);
- }
-
- _fputts(MessageBuffer, hLogFile);
-
- fclose(hLogFile);
-#endif
- if (ExitCode > 0)
- ExitProcess(ExitCode);
- else
- return;
-}
-
-
-VOID
-UpdateStatus(DWORD NewStatus,
- DWORD Check)
-{
- TCHAR szSet[50];
-
- if (Check > 0)
- hServStatus.dwCheckPoint += Check;
- else
- hServStatus.dwCheckPoint = Check;
+ pServInfo->servStatus.dwCheckPoint = Check;
if (NewStatus > 0)
- hServStatus.dwCurrentState = NewStatus;
-
- _sntprintf(szSet, 49, _T("setting service to 0x%lu, CheckPoint %lu"),
NewStatus, hServStatus.dwCheckPoint);
- LogEvent(szSet, 0, FALSE);
-
- if (!SetServiceStatus(hSStat, &hServStatus))
- LogEvent(_T("Cannot set service status"), 101, TRUE);
-
- return;
-}
-
-
-
-VOID WINAPI
-ServiceMain(DWORD argc, LPTSTR argv[])
-{
- LogEvent(_T("Starting service. First log entry."), 0, FALSE);
- LogEvent (_T("Entering ServiceMain."), 0, FALSE);
-
- hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- hServStatus.dwCurrentState = SERVICE_STOPPED;
- hServStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN |
SERVICE_ACCEPT_PAUSE_CONTINUE;
- hServStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
- hServStatus.dwServiceSpecificExitCode = 0;
- hServStatus.dwCheckPoint = 0;
- hServStatus.dwWaitHint = 2 * CS_TIMEOUT;
-
- hSStat = RegisterServiceCtrlHandler(ServiceName, ServerCtrlHandler);
- if (hSStat == 0)
- LogEvent(_T("Failed to register service\n"), 100, TRUE);
-
- LogEvent(_T("Control handler registered successfully"), 0, FALSE);
- UpdateStatus(SERVICE_START_PENDING, 1);
- LogEvent(_T("Service status set to SERVICE_START_PENDING"), 0, FALSE);
-
- if (CreateServers() != 0)
- {
- hServStatus.dwServiceSpecificExitCode = 1;
- UpdateStatus(SERVICE_STOPPED, 0);
- return;
- }
-
- LogEvent(_T("Service threads shut down. Set SERVICE_STOPPED status"), 0,
FALSE);
- UpdateStatus(SERVICE_STOPPED, 0);
- LogEvent(_T("Service status set to SERVICE_STOPPED\n"), 0, FALSE);
- LogEvent(_T("Leaving ServiceMain\n"), 0, FALSE);
-
- return;
-}
-
-VOID WINAPI
-ServerCtrlHandler(DWORD Control)
-{
- switch (Control)
- {
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP:
- LogEvent(_T("\nSetting the service to SERVICE_STOP_PENDING"), 0,
FALSE);
- InterlockedExchange((LONG *)&bShutDown, TRUE);
- hServStatus.dwWin32ExitCode = 0;
- hServStatus.dwWaitHint = 0;
- UpdateStatus(SERVICE_STOP_PENDING, 1);
- break;
-
- case SERVICE_CONTROL_PAUSE: /* not yet implemented */
- LogEvent(_T("Setting the service to SERVICE_PAUSED"), 0, FALSE);
- InterlockedExchange((LONG *)&bPause, TRUE);
- UpdateStatus(SERVICE_PAUSED, 0);
- break;
-
- case SERVICE_CONTROL_CONTINUE:
- LogEvent(_T("Setting the service to SERVICE_RUNNING"), 0, FALSE);
- InterlockedExchange((LONG *)&bPause, FALSE);
- UpdateStatus(SERVICE_RUNNING, 0);
- break;
-
- case SERVICE_CONTROL_INTERROGATE:
- break;
-
- default:
- if (Control > 127 && Control < 256) /* user defined */
- break;
- }
-
- return;
-}
-
-
-INT
-CreateServers()
+ pServInfo->servStatus.dwCurrentState = NewStatus;
+
+ _sntprintf(szSet,
+ 49,
+ _T("Service state 0x%lu, CheckPoint %lu"),
+ pServInfo->servStatus.dwCurrentState,
+ pServInfo->servStatus.dwCheckPoint);
+ LogEvent(szSet, 0, 0, LOG_FILE);
+
+ if (!SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus))
+ LogEvent(_T("Cannot set service status"), GetLastError(), 0, LOG_ALL);
+}
+
+
+static BOOL
+CreateServers(PSERVICEINFO pServInfo)
{
DWORD dwThreadId[NUM_SERVICES];
HANDLE hThread[NUM_SERVICES];
@@ -199,41 +71,38 @@
if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{
_stprintf(buf, _T("WSAStartup() failed : %lu\n"), RetVal);
- LogEvent(buf, RetVal, TRUE);
- return -1;
- }
-
- UpdateStatus(0, 1); /* increment checkpoint */
-
- LogEvent(_T("\nCreating server Threads"), 0, FALSE);
+ LogEvent(buf, 0, 100, LOG_ALL);
+ return FALSE;
+ }
+
+ UpdateStatus(pServInfo, 0, 1);
+
+ LogEvent(_T("\nCreating server Threads"), 0, 0, LOG_FILE);
/* Create worker threads. */
for(i = 0; i < NUM_SERVICES; i++)
{
- _stprintf(buf, _T("Starting %s server"), Services[i].Name);
- LogEvent(buf, 0, FALSE);
-
- hThread[i] = CreateThread(NULL, // default security attributes
- 0, // use default stack size
- StartServer, // thread function
- &Services[i], // argument to thread function
- 0, // use default creation flags
- &dwThreadId[i]); // returns the thread identifier
+ _stprintf(buf, _T("Creating thread for %s server"), Services[i].Name);
+ LogEvent(buf, 0, 0, LOG_FILE);
+
+ hThread[i] = CreateThread(NULL,
+ 0,
+ StartServer,
+ &Services[i],
+ 0,
+ &dwThreadId[i]);
if (hThread[i] == NULL)
{
_stprintf(buf, _T("\nFailed to start %s server\n"),
Services[i].Name);
- /* don't exit process via LogEvent. We want to exit via the server
- * which failed to start, which could mean i=0 */
- LogEvent(buf, 0, TRUE);
+ LogEvent(buf, GetLastError(), 0, LOG_ALL);
}
- UpdateStatus(0, 1); /* increment checkpoint */
- }
-
- LogEvent(_T("setting service status to running"), 0, FALSE);
-
- UpdateStatus(SERVICE_RUNNING, 0);
+ UpdateStatus(pServInfo, 0, 1);
+ }
+
+ LogEvent(_T("Setting service status to running"), 0, 0, LOG_FILE);
+ UpdateStatus(pServInfo, SERVICE_RUNNING, 0);
/* Wait until all threads have terminated. */
WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE);
@@ -244,11 +113,92 @@
CloseHandle(hThread[i]);
}
- LogEvent(_T("Detaching Winsock2"), 0, FALSE);
+ LogEvent(_T("Detaching Winsock2"), 0, 0, LOG_FILE);
WSACleanup();
return 0;
}
+
+VOID WINAPI
+ServerCtrlHandler(DWORD dwControl,
+ DWORD dwEventType,
+ LPVOID lpEventData,
+ LPVOID lpContext)
+{
+ PSERVICEINFO pServInfo = (PSERVICEINFO)lpContext;
+
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_SHUTDOWN:
+ case SERVICE_CONTROL_STOP:
+ LogEvent(_T("\nSetting the service to SERVICE_STOP_PENDING"), 0, 0,
LOG_FILE);
+ InterlockedExchange((LONG *)&bShutdown, TRUE);
+ pServInfo->servStatus.dwWin32ExitCode = 0;
+ pServInfo->servStatus.dwWaitHint = 0;
+ UpdateStatus(pServInfo, SERVICE_STOP_PENDING, 1);
+ break;
+
+ case SERVICE_CONTROL_PAUSE: /* not yet implemented */
+ LogEvent(_T("Setting the service to SERVICE_PAUSED"), 0, 0,
LOG_FILE);
+ InterlockedExchange((LONG *)&bPause, TRUE);
+ UpdateStatus(pServInfo, SERVICE_PAUSED, 0);
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ LogEvent(_T("Setting the service to SERVICE_RUNNING"), 0, 0,
LOG_FILE);
+ InterlockedExchange((LONG *)&bPause, FALSE);
+ UpdateStatus(pServInfo, SERVICE_RUNNING, 0);
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+
+ default:
+ if (dwControl > 127 && dwControl < 256) /* user defined */
+ LogEvent(_T("User defined control code"), 0, 0, LOG_FILE);
+ else
+ LogEvent(_T("ERROR: Bad control code"), 0, 0, LOG_FILE);
+ break;
+ }
+}
+
+VOID WINAPI
+ServiceMain(DWORD argc, LPTSTR argv[])
+{
+ SERVICEINFO servInfo;
+
+ LogEvent (_T("Entering ServiceMain."), 0, 0, LOG_FILE);
+
+ servInfo.servStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ servInfo.servStatus.dwCurrentState = SERVICE_STOPPED;
+ servInfo.servStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
+ servInfo.servStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+ servInfo.servStatus.dwServiceSpecificExitCode = 0;
+ servInfo.servStatus.dwCheckPoint = 0;
+ servInfo.servStatus.dwWaitHint = 2 * CS_TIMEOUT;
+
+ LogEvent(_T("Registering service control handler"), 0, 0, LOG_FILE);
+ servInfo.hStatus = RegisterServiceCtrlHandlerEx(ServiceName,
+
(LPHANDLER_FUNCTION_EX)ServerCtrlHandler,
+ &servInfo);
+ if (!servInfo.hStatus)
+ LogEvent(_T("Failed to register service\n"), GetLastError(), 100,
LOG_ALL);
+
+ UpdateStatus(&servInfo, SERVICE_START_PENDING, 1);
+
+ if (!CreateServers(&servInfo))
+ {
+ servInfo.servStatus.dwServiceSpecificExitCode = 1;
+ UpdateStatus(&servInfo, SERVICE_STOPPED, 0);
+ return;
+ }
+
+ LogEvent(_T("Service threads shut down. Set SERVICE_STOPPED status"), 0, 0,
LOG_FILE);
+ UpdateStatus(&servInfo, SERVICE_STOPPED, 0);
+
+ LogEvent(_T("Leaving ServiceMain\n"), 0, 0, LOG_FILE);
+}
+
int _tmain (int argc, LPTSTR argv [])
{
@@ -258,10 +208,12 @@
{NULL, NULL }
};
- remove(LogFileName);
+ InitLogging();
if (!StartServiceCtrlDispatcher(ServiceTable))
- LogEvent(_T("failed to start the service control dispatcher\n"), 100,
TRUE);
+ LogEvent(_T("failed to start the service control dispatcher"),
GetLastError(), 101, LOG_ALL);
+
+ UninitLogging();
return 0;
}
Modified: trunk/reactos/base/services/tcpsvcs/tcpsvcs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/tcps…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/tcpsvcs.h [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/tcpsvcs.h [iso-8859-1] Wed Apr 2 11:54:55 2008
@@ -1,10 +1,12 @@
-#ifdef _MSC_VER
-#define _CRT_SECURE_NO_DEPRECATE 1
-#endif
#include <stdio.h>
#include <winsock2.h>
#include <tchar.h>
#include <time.h>
+
+#define LOG_FILE 1
+#define LOG_EVENTLOG 2
+#define LOG_ERROR 4
+#define LOG_ALL (LOG_FILE | LOG_EVENTLOG | LOG_ERROR)
/* default port numbers */
#define ECHO_PORT 7
@@ -14,19 +16,8 @@
#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 ASCII_START 32
-#define ASCII_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 {
@@ -35,19 +26,21 @@
LPTHREAD_START_ROUTINE Service;
} SERVICES, *PSERVICES;
-/* tcpsvcs functions */
-VOID WINAPI ServerCtrlHandler(DWORD control);
-INT CreateServers(VOID);
-VOID LogEvent(LPCTSTR UserMessage, DWORD ExitCode, BOOL PrintErrorMsg);
-void UpdateStatus(DWORD NewStatus, DWORD Check);
+extern volatile BOOL bShutdown;
+extern volatile BOOL bPause;
+
+/* logging functions */
+VOID InitLogging();
+VOID UninitLogging();
+VOID LogEvent(LPCTSTR lpMsg, DWORD errNum, DWORD exitCode, UINT flags);
/* skelserver functions */
DWORD WINAPI StartServer(LPVOID lpParam);
BOOL ShutdownConnection(SOCKET Sock, BOOL bRec);
/* server thread handlers */
-DWORD WINAPI ChargenHandler(VOID* Sock_);
-DWORD WINAPI DaytimeHandler(VOID* Sock_);
-DWORD WINAPI EchoHandler(VOID* Sock_);
-DWORD WINAPI DiscardHandler(VOID* Sock_);
-DWORD WINAPI QotdHandler(VOID* Sock_);
+DWORD WINAPI ChargenHandler(VOID* sock_);
+DWORD WINAPI DaytimeHandler(VOID* sock_);
+DWORD WINAPI EchoHandler(VOID* sock_);
+DWORD WINAPI DiscardHandler(VOID* sock_);
+DWORD WINAPI QotdHandler(VOID* sock_);
Modified: trunk/reactos/base/services/tcpsvcs/tcpsvcs.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/tcpsvcs/tcps…
==============================================================================
--- trunk/reactos/base/services/tcpsvcs/tcpsvcs.rbuild [iso-8859-1] (original)
+++ trunk/reactos/base/services/tcpsvcs/tcpsvcs.rbuild [iso-8859-1] Wed Apr 2 11:54:55
2008
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="tcpsvcs" type="win32cui"
installbase="system32" installname="tcpsvcs.exe">
+<module name="tcpsvcs" type="win32cui"
installbase="system32" installname="tcpsvcs.exe"
unicode="yes">
<include base="arp">.</include>
<library>kernel32</library>
<library>iphlpapi</library>
@@ -16,5 +16,6 @@
<file>qotd.c</file>
<file>chargen.c</file>
<file>tcpsvcs.rc</file>
+ <file>log.c</file>
<pch>tcpsvcs.h</pch>
</module>