Sync with trunk head
[reactos.git] / base / services / tcpsvcs / qotd.c
1 /*
2 * PROJECT: ReactOS simple TCP/IP services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: /base/services/tcpsvcs/qotd.c
5 * PURPOSE: Sends a random quote to the client
6 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "tcpsvcs.h"
11
12 static WCHAR szFilePath[] = L"\\drivers\\etc\\quotes";
13
14 static BOOL
15 SendQuote(SOCKET sock, char* Quote)
16 {
17 INT strSize = strlen(Quote);
18 if (send(sock, Quote, strSize, 0) == SOCKET_ERROR)
19 return FALSE;
20
21 return TRUE;
22 }
23
24 static BOOL
25 RetrieveQuote(SOCKET sock)
26 {
27 HANDLE hFile;
28 WCHAR szFullPath[MAX_PATH + 20];
29 DWORD dwBytesRead;
30 LPSTR lpQuotes;
31 LPSTR lpStr;
32 INT quoteNum;
33 INT NumQuotes = 0;
34 INT i;
35
36 if(!GetSystemDirectoryW(szFullPath, MAX_PATH))
37 {
38 LogEvent(L"QOTD: Getting system path failed", GetLastError(), 0, LOG_FILE);
39 return FALSE;
40 }
41 wcscat(szFullPath, szFilePath);
42
43
44 LogEvent(L"QOTD: Opening quotes file", 0, 0, LOG_FILE);
45 hFile = CreateFileW(szFullPath,
46 GENERIC_READ,
47 0,
48 NULL,
49 OPEN_EXISTING,
50 FILE_ATTRIBUTE_NORMAL,
51 NULL);
52 if (hFile == INVALID_HANDLE_VALUE)
53 {
54 LogEvent(L"QOTD: Error opening quotes file", GetLastError(), 0, LOG_FILE);
55 }
56 else
57 {
58 DWORD dwSize = GetFileSize(hFile, NULL);
59 lpQuotes = (LPSTR)HeapAlloc(GetProcessHeap(), 0, dwSize);
60 if (!lpQuotes)
61 {
62 CloseHandle(hFile);
63 return FALSE;
64 }
65
66 ReadFile(hFile,
67 lpQuotes,
68 dwSize,
69 &dwBytesRead,
70 NULL);
71 CloseHandle(hFile);
72
73 lpQuotes[dwSize] = 0;
74
75 if (dwBytesRead != dwSize)
76 return FALSE;
77
78 lpStr = lpQuotes;
79 while (*lpStr)
80 {
81 if (*lpStr == '%')
82 NumQuotes++;
83 lpStr++;
84 }
85
86 /* pick a random quote */
87 srand((unsigned int) GetTickCount());
88 quoteNum = rand() % NumQuotes;
89
90 /* retrieve the full quote */
91 lpStr = lpQuotes;
92 for (i = 1; i <= quoteNum; i++)
93 {
94 /* move past proceding quote */
95 lpStr++;
96
97 if (i == quoteNum)
98 {
99 LPSTR lpStart = lpStr;
100
101 while (*lpStr != '%' && *lpStr != '\0')
102 lpStr++;
103
104 *lpStr = 0;
105
106 /* send the quote */
107 if (!SendQuote(sock, lpStart))
108 LogEvent(L"QOTD: Error sending data", 0, 0, LOG_FILE);
109 break;
110 }
111 else
112 {
113 while (*lpStr != '%' && *lpStr != '\0')
114 lpStr++;
115
116 /* move past % and RN */
117 lpStr += 2;
118 }
119 }
120
121 return TRUE;
122 }
123
124 return FALSE;
125 }
126
127
128 DWORD WINAPI
129 QotdHandler(VOID* sock_)
130 {
131 SOCKET sock = (SOCKET)sock_;
132 DWORD retVal = 0;
133
134 if (!RetrieveQuote(sock))
135 {
136 LogEvent(L"QOTD: Error retrieving quote", 0, 0, LOG_FILE);
137 retVal = 1;
138 }
139
140 LogEvent(L"QOTD: Shutting connection down", 0, 0, LOG_FILE);
141 if (ShutdownConnection(sock, FALSE))
142 {
143 LogEvent(L"QOTD: Connection is down", 0, 0, LOG_FILE);
144 }
145 else
146 {
147 LogEvent(L"QOTD: Connection shutdown failed", 0, 0, LOG_FILE);
148 LogEvent(L"QOTD: Terminating thread", 0, 0, LOG_FILE);
149 retVal = 1;
150 }
151
152 LogEvent(L"QOTD: Terminating thread", 0, 0, LOG_FILE);
153 ExitThread(retVal);
154 }