/* * PROJECT: ReactOS simple TCP/IP services * LICENSE: GPL - See COPYING in the top level directory * FILE: base/services/tcpsvcs/chargen.c * PURPOSE: Sends continuous lines of chars to the client * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy * */ #include "tcpsvcs.h" /* printable ASCII's characters for chargen */ #define ASCII_START 32 #define ASCII_END 126 #define NUM_CHARS ASCII_END - ASCII_START + 1 /* number of chars to put on a line */ #define LINESIZE 74 // 72 + CR + NL static BOOL SendLine(SOCKET sock, LPSTR lpLine) { BOOL bRet = FALSE; /*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) { bRet = TRUE; } else { LogEvent(L"Chargen: Not sent enough bytes", 0, 0, LOG_FILE); } } else if (retVal == SOCKET_ERROR) { LogEvent(L"Chargen: Socket error\n", WSAGetLastError(), 0, LOG_ERROR); } else { LogEvent(L"Chargen: unknown error\n", WSAGetLastError(), 0, LOG_ERROR); } return bRet; } static BOOL GenerateChars(SOCKET sock) { CHAR chars[NUM_CHARS]; CHAR line[LINESIZE]; INT charIndex; INT loopIndex; INT i; /* fill the array with printable characters */ for (charIndex = 0, i = ASCII_START; i <= ASCII_END; charIndex++, i++) chars[charIndex] = (CHAR)i; loopIndex = 0; while (!bShutdown) { /* reset the loop when we hit the last char */ if (loopIndex == NUM_CHARS) loopIndex = 0; /* fill a line array to send */ charIndex = loopIndex; for (i=0; i < LINESIZE - 2; i++) { line[i] = chars[charIndex]; /* if we hit the end char, reset it */ if (chars[charIndex] == chars[NUM_CHARS - 1]) charIndex = 0; else charIndex++; } line[LINESIZE - 2] = '\r'; line[LINESIZE - 1] = '\n'; if (!SendLine(sock, line)) break; /* start printing from next char in the array */ loopIndex++; } return TRUE; } DWORD WINAPI ChargenHandler(VOID* sock_) { INT retVal = 0; SOCKET sock = (SOCKET)sock_; if (!GenerateChars(sock)) { LogEvent(L"Chargen: Char generation failed", 0, 0, LOG_FILE); retVal = 1; } LogEvent(L"Chargen: Shutting connection down...", 0, 0, LOG_FILE); if (ShutdownConnection(sock, FALSE)) { LogEvent(L"Chargen: Connection is down", 0, 0, LOG_FILE); } else { LogEvent(L"Chargen: Connection shutdown failed", 0, 0, LOG_FILE); retVal = 1; } LogEvent(L"Chargen: Terminating thread", 0, 0, LOG_FILE); ExitThread(retVal); }