Display the driver provider, date and version. Based on a patch by Herve.
[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 extern BOOL bShutDown;
21
22 DWORD WINAPI ChargenHandler(VOID* Sock_)
23 {
24 DWORD RetVal = 0;
25 SOCKET Sock = (SOCKET)Sock_;
26
27 if (!GenerateChars(Sock))
28 {
29 LogEvent(_T("Chargen: Char generation failed\n"), 0, FALSE);
30 RetVal = -1;
31 }
32
33 LogEvent(_T("Chargen: Shutting connection down...\n"), 0, FALSE);
34 if (ShutdownConnection(Sock, FALSE))
35 LogEvent(_T("Chargen: Connection is down.\n"), 0, FALSE);
36 else
37 {
38 LogEvent(_T("Chargen: Connection shutdown failed\n"), 0, FALSE);
39 RetVal = -1;
40 }
41
42 LogEvent(_T("Chargen: Terminating thread\n"), 0, FALSE);
43 ExitThread(RetVal);
44
45 }
46
47
48 BOOL GenerateChars(SOCKET Sock)
49 {
50 int i;
51 int charIndex; /* internal loop */
52 int loopIndex; /* line loop */
53 char ring[END-START];
54 char *endring;
55 char Line[LINESIZ];
56
57 /* fill ring with printable characters */
58 for (charIndex=0, i=START; i<=END; charIndex++, i++)
59 ring[charIndex] = i;
60 /* save the address of the end character in the ring */
61 endring = &ring[charIndex];
62
63 /* where we will start output from */
64 loopIndex = 0;
65 while (! bShutDown)
66 {
67 /* if the loop index is equal to the last char,
68 * start the loop again from the beginning */
69 if (loopIndex == END-START)
70 loopIndex = 0;
71
72 /* start printing from char controled by loopIndex */
73 charIndex = loopIndex;
74 for (i=0; i < LINESIZ - 2; i++)
75 {
76 Line[i] = ring[charIndex];
77
78 if (ring[charIndex] == *endring)
79 charIndex = 0;
80 else
81 charIndex++;
82 }
83
84 Line[LINESIZ - 2] = L'\r';
85 Line[LINESIZ - 1] = L'\n';
86
87 if (! SendLine(Sock, Line))
88 break;
89
90 /* increment loop index to start printing from next char in ring */
91 loopIndex++;
92 }
93
94 if (bShutDown)
95 return FALSE;
96 else
97 return TRUE;
98 }
99
100 BOOL SendLine(SOCKET Sock, TCHAR* Line)
101 {
102 INT RetVal;
103 INT SentBytes;
104 INT LineSize;
105
106 LineSize = sizeof(TCHAR) * LINESIZ;
107
108 SentBytes = 0;
109 RetVal = send(Sock, Line, LineSize, 0);
110 /*FIXME: need to establish if peer closes connection,
111 not just report a socket error */
112 if (RetVal > 0)
113 {
114 if (RetVal != LineSize)
115 {
116 LogEvent(_T("Chargen: Not sent enough bytes\n"), 0, FALSE);
117 return FALSE;
118 }
119 SentBytes += RetVal;
120 return TRUE;
121 }
122 else if (RetVal == SOCKET_ERROR)
123 {
124 LogEvent(_T("Chargen: Socket error\n"), 0, FALSE);
125 return FALSE;
126 }
127 else
128 LogEvent(_T("Chargen: unknown error\n"), 0, FALSE);
129 // return FALSE;
130
131 LogEvent(_T("Chargen: Connection closed by peer.\n"), 0, FALSE);
132 return TRUE;
133 }