use GetSystemDirectory
[reactos.git] / reactos / services / tcpsvcs / skelserver.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/skelserver.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 StartServer(LPVOID lpParam)
21 {
22 SOCKET ListeningSocket;
23 const TCHAR* HostIP = "127.0.0.1";
24 PSERVICES pServices;
25
26 pServices = (PSERVICES)lpParam;
27
28 ListeningSocket = SetUpListener(HostIP, htons(pServices->Port));
29 if (ListeningSocket == INVALID_SOCKET)
30 {
31 _tprintf(_T("error setting up socket\n"));
32 return 3;
33 }
34
35 _tprintf(_T("%s is waiting for connections on port %d...\n"),
36 pServices->Name, pServices->Port);
37 while (1)
38 {
39 AcceptConnections(ListeningSocket, pServices->Service, pServices->Name);
40 printf("Acceptor restarting...\n");
41 }
42
43 /* won't see this yet as we kill the service with ctrl+c */
44 _tprintf(_T("Detaching Winsock2...\n"));
45 WSACleanup();
46 return 0;
47 }
48
49
50 SOCKET SetUpListener(const char* ServAddr, int Port)
51 {
52 SOCKET Sock;
53 SOCKADDR_IN Server;
54
55 Sock = socket(AF_INET, SOCK_STREAM, 0);
56 if (Sock != INVALID_SOCKET)
57 {
58 Server.sin_family = AF_INET;
59 Server.sin_addr.s_addr = htonl(INADDR_ANY);
60 Server.sin_port = Port;
61 if (bind(Sock, (SOCKADDR*)&Server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
62 {
63 listen(Sock, SOMAXCONN);
64 return Sock;
65 }
66 else
67 printf("bind() failed\n");
68
69 }
70 return INVALID_SOCKET;
71 }
72
73
74
75
76 VOID AcceptConnections(SOCKET ListeningSocket,
77 LPTHREAD_START_ROUTINE Service, TCHAR *Name)
78 {
79 SOCKADDR_IN Client;
80 SOCKET Sock;
81 INT nAddrSize = sizeof(Client);
82 DWORD ThreadID;
83
84 while (1)
85 {
86 Sock = accept(ListeningSocket, (SOCKADDR*)&Client, &nAddrSize);
87 if (Sock != INVALID_SOCKET)
88 {
89 _tprintf(_T("Accepted connection to %s server from %s:%d\n"),
90 Name, inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
91 _tprintf(_T("Creating new thread for %s\n"), Name);
92 CreateThread(0, 0, Service, (void*)Sock, 0, &ThreadID);
93 }
94 else
95 {
96 _tprintf(_T("accept() failed\n"));
97 return;
98 }
99 }
100 }
101
102 BOOL ShutdownConnection(SOCKET Sock, BOOL bRec)
103 {
104 /* Disallow any further data sends. This will tell the other side
105 that we want to go away now. If we skip this step, we don't
106 shut the connection down nicely. */
107 if (shutdown(Sock, SD_SEND) == SOCKET_ERROR)
108 {
109 _tprintf(_T("Error in shutdown"));
110 return FALSE;
111 }
112
113 /* Receive any extra data still sitting on the socket. After all
114 data is received, this call will block until the remote host
115 acknowledges the TCP control packet sent by the shutdown above.
116 Then we'll get a 0 back from recv, signalling that the remote
117 host has closed its side of the connection. */
118 if (bRec)
119 {
120 char ReadBuffer[BUF];
121 int NewBytes = recv(Sock, ReadBuffer, BUF, 0);
122 if (NewBytes == SOCKET_ERROR)
123 return FALSE;
124 else if (NewBytes != 0)
125 _tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes);
126 }
127
128 /* Close the socket. */
129 if (closesocket(Sock) == SOCKET_ERROR)
130 return FALSE;
131
132 return TRUE;
133 }