11bb93dd2f3297207d24bac45b172b86e61c0c70
[reactos.git] / reactos / apps / utils / net / 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 _tprintf(_T("Char generation failed\n"));
28 RetVal = -1;
29 }
30
31 _tprintf(_T("Shutting connection down...\n"));
32 if (ShutdownConnection(Sock, FALSE))
33 _tprintf(_T("Connection is down.\n"));
34 else
35 {
36 _tprintf(_T("Connection shutdown failed\n"));
37 RetVal = -1;
38 }
39
40 _tprintf(_T("Terminating chargen thread\n"));
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 _tprintf(("Not sent enough\n"));
112 return FALSE;
113 }
114 SentBytes += RetVal;
115 return TRUE;
116 }
117 else if (RetVal == SOCKET_ERROR)
118 {
119 _tprintf(("Socket error\n"));
120 return FALSE;
121 }
122 else
123 _tprintf(("unknown error\n"));
124 //WSAGetLastError()
125
126 _tprintf(("Connection closed by peer.\n"));
127 return TRUE;
128 }