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