-Start to convert tcpsvcs to a proper NT service. Supports starting and stopping...
[reactos.git] / reactos / services / tcpsvcs / chargen.c
1 /*
2 * ReactOS Services
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * LICENCE: GPL - See COPYING in the top level directory
6 * PROJECT: ReactOS simple TCP/IP services
7 * FILE: apps/utils/net/tcpsvcs/chargen.c
8 * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
9 * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
10 * REVISIONS:
11 * GM 04/10/05 Created
12 *
13 */
14
15 #include <stdio.h>
16 #include <winsock2.h>
17 #include <tchar.h>
18 #include "tcpsvcs.h"
19
20 DWORD WINAPI ChargenHandler(VOID* Sock_)
21 {
22 DWORD RetVal = 0;
23 SOCKET Sock = (SOCKET)Sock_;
24
25 if (!GenerateChars(Sock))
26 {
27 LogEvent(_T("Chargen: Char generation failed\n"), 0, FALSE);
28 RetVal = -1;
29 }
30
31 LogEvent(_T("Chargen: Shutting connection down...\n"), 0, FALSE);
32 if (ShutdownConnection(Sock, FALSE))
33 LogEvent(_T("Chargen: Connection is down.\n"), 0, FALSE);
34 else
35 {
36 LogEvent(_T("Chargen: Connection shutdown failed\n"), 0, FALSE);
37 RetVal = -1;
38 }
39
40 LogEvent(_T("Chargen: Terminating thread\n"), 0, FALSE);
41 ExitThread(RetVal);
42
43 }
44
45
46 BOOL GenerateChars(SOCKET Sock)
47 {
48 int i;
49 int charIndex; /* internal loop */
50 int loopIndex; /* line loop */
51 char ring[END-START];
52 char *endring;
53 char Line[LINESIZ];
54
55 /* fill ring with printable characters */
56 for (charIndex=0, i=START; i<=END; charIndex++, i++)
57 ring[charIndex] = i;
58 /* save the address of the end character in the ring */
59 endring = &ring[charIndex];
60
61 /* where we will start output from */
62 loopIndex = 0;
63 while (1)
64 {
65 /* if the loop index is equal to the last char,
66 * start the loop again from the beginning */
67 if (loopIndex == END-START)
68 loopIndex = 0;
69
70 /* start printing from char controled by loopIndex */
71 charIndex = loopIndex;
72 for (i=0; i < LINESIZ - 2; i++)
73 {
74 Line[i] = ring[charIndex];
75
76 if (ring[charIndex] == *endring)
77 charIndex = 0;
78 else
79 charIndex++;
80 }
81
82 Line[LINESIZ - 2] = L'\r';
83 Line[LINESIZ - 1] = L'\n';
84
85 if (!SendLine(Sock, Line))
86 break;
87
88 /* increment loop index to start printing from next char in ring */
89 loopIndex++;
90 }
91
92 return TRUE;
93 }
94
95 BOOL SendLine(SOCKET Sock, TCHAR* Line)
96 {
97 INT RetVal;
98 INT SentBytes;
99 INT LineSize;
100
101 LineSize = sizeof(TCHAR) * LINESIZ;
102
103 SentBytes = 0;
104 RetVal = send(Sock, Line, LineSize, 0);
105 /*FIXME: need to establish if peer closes connection,
106 not just report a socket error */
107 if (RetVal > 0)
108 {
109 if (RetVal != LineSize)
110 {
111 LogEvent(_T("Chargen: Not sent enough bytes\n"), 0, FALSE);
112 return FALSE;
113 }
114 SentBytes += RetVal;
115 return TRUE;
116 }
117 else if (RetVal == SOCKET_ERROR)
118 {
119 LogEvent(_T("Chargen: Socket error\n"), 0, FALSE);
120 return FALSE;
121 }
122 else
123 LogEvent(_T("Chargen: unknown error\n"), 0, FALSE);
124 //WSAGetLastError()
125
126 LogEvent(_T("Chargen: Connection closed by peer.\n"), 0, FALSE);
127 return TRUE;
128 }