1 /* 2 * PROJECT: ReactOS simple TCP/IP services 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/services/tcpsvcs/chargen.c 5 * PURPOSE: Sends continuous lines of chars to the client 6 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@reactos.org> 7 * 8 */ 9 10 #include "tcpsvcs.h" 11 12 /* printable ASCII's characters for chargen */ 13 #define ASCII_START 32 14 #define ASCII_END 126 15 #define NUM_CHARS ASCII_END - ASCII_START + 1 16 17 /* number of chars to put on a line */ 18 #define LINESIZE 74 // 72 + CR + NL 19 20 static BOOL 21 SendLine(SOCKET sock, LPSTR lpLine) 22 { 23 BOOL bRet = FALSE; 24 25 /*FIXME: need to establish if peer closes connection, not just report a socket error */ 26 INT retVal = send(sock, lpLine, LINESIZE, 0); 27 if (retVal > 0) 28 { 29 if (retVal == LINESIZE) 30 { 31 bRet = TRUE; 32 } 33 else 34 { 35 LogEvent(L"Chargen: Not sent enough bytes", 0, 0, LOG_FILE); 36 } 37 } 38 else if (retVal == SOCKET_ERROR) 39 { 40 LogEvent(L"Chargen: Socket error\n", WSAGetLastError(), 0, LOG_ERROR); 41 } 42 else 43 { 44 LogEvent(L"Chargen: unknown error\n", WSAGetLastError(), 0, LOG_ERROR); 45 } 46 47 return bRet; 48 } 49 50 static BOOL 51 GenerateChars(SOCKET sock) 52 { 53 CHAR chars[NUM_CHARS]; 54 CHAR line[LINESIZE]; 55 INT charIndex; 56 INT loopIndex; 57 INT i; 58 59 /* fill the array with printable characters */ 60 for (charIndex = 0, i = ASCII_START; i <= ASCII_END; charIndex++, i++) 61 chars[charIndex] = (CHAR)i; 62 63 loopIndex = 0; 64 while (!bShutdown) 65 { 66 /* reset the loop when we hit the last char */ 67 if (loopIndex == NUM_CHARS) 68 loopIndex = 0; 69 70 /* fill a line array to send */ 71 charIndex = loopIndex; 72 for (i=0; i < LINESIZE - 2; i++) 73 { 74 line[i] = chars[charIndex]; 75 76 /* if we hit the end char, reset it */ 77 if (chars[charIndex] == chars[NUM_CHARS - 1]) 78 charIndex = 0; 79 else 80 charIndex++; 81 } 82 line[LINESIZE - 2] = '\r'; 83 line[LINESIZE - 1] = '\n'; 84 85 if (!SendLine(sock, line)) 86 break; 87 88 /* start printing from next char in the array */ 89 loopIndex++; 90 } 91 92 return TRUE; 93 } 94 95 DWORD WINAPI 96 ChargenHandler(VOID* sock_) 97 { 98 INT retVal = 0; 99 SOCKET sock = (SOCKET)sock_; 100 101 if (!GenerateChars(sock)) 102 { 103 LogEvent(L"Chargen: Char generation failed", 0, 0, LOG_FILE); 104 retVal = 1; 105 } 106 107 LogEvent(L"Chargen: Shutting connection down...", 0, 0, LOG_FILE); 108 if (ShutdownConnection(sock, FALSE)) 109 { 110 LogEvent(L"Chargen: Connection is down", 0, 0, LOG_FILE); 111 } 112 else 113 { 114 LogEvent(L"Chargen: Connection shutdown failed", 0, 0, LOG_FILE); 115 retVal = 1; 116 } 117 118 LogEvent(L"Chargen: Terminating thread", 0, 0, LOG_FILE); 119 ExitThread(retVal); 120 } 121