1// Simple application that creates a server socket, listening for connections 2// of the unattended install test. Once it gets a client connected, the 3// app will send back an ACK string, indicating the install process is done. 4// 5// You must link this code with Ws2_32.lib, Mswsock.lib, and Advapi32.lib 6// 7// Author: Lucas Meneghel Rodrigues <lmr@redhat.com> 8// Code was adapted from an MSDN sample. 9 10// Usage: finish.exe 11 12#ifdef __MINGW32__ 13#undef _WIN32_WINNT 14#define _WIN32_WINNT 0x500 15#endif 16 17#include <windows.h> 18#include <winsock2.h> 19#include <ws2tcpip.h> 20#include <stdlib.h> 21#include <stdio.h> 22 23int DEFAULT_PORT = 12323; 24 25void ExitOnError(const char *message, BOOL winsock = FALSE) 26{ 27 LPVOID system_message; 28 char buffer[512]; 29 int error_code; 30 31 if (winsock) 32 error_code = WSAGetLastError(); 33 else 34 error_code = GetLastError(); 35 WSACleanup(); 36 37 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 38 FORMAT_MESSAGE_FROM_SYSTEM, 39 NULL, 40 error_code, 41 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 42 (LPTSTR)&system_message, 43 0, 44 NULL); 45 46 sprintf(buffer, 47 "%s!\n" 48 "Error code = %d\n" 49 "Error message = %s", 50 message, error_code, (char *)system_message); 51 52 MessageBox(NULL, buffer, "Error", MB_OK | MB_ICONERROR); 53 54 LocalFree(system_message); 55 ExitProcess(1); 56} 57 58SOCKET PrepareListenSocket(int port) 59{ 60 sockaddr_in addr; 61 linger l; 62 int result; 63 64 // Create socket 65 SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 66 if (ListenSocket == INVALID_SOCKET) 67 ExitOnError("Socket creation failed", TRUE); 68 69 // Enable lingering 70 l.l_linger = 10; 71 l.l_onoff = 1; 72 setsockopt(ListenSocket, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)); 73 74 // Bind the socket 75 addr.sin_family = AF_INET; 76 addr.sin_addr.s_addr = htonl(INADDR_ANY); 77 addr.sin_port = htons(port); 78 79 result = bind(ListenSocket, (sockaddr *)&addr, sizeof(addr)); 80 if (result == SOCKET_ERROR) 81 ExitOnError("Bind failed", TRUE); 82 83 // Start listening for incoming connections 84 result = listen(ListenSocket, SOMAXCONN); 85 if (result == SOCKET_ERROR) 86 ExitOnError("Listen failed", TRUE); 87 88 return ListenSocket; 89} 90 91int main(int argc, char **argv) 92{ 93 WSADATA wsaData; 94 SOCKET ListenSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET; 95 struct addrinfo *result = NULL, hints; 96 char *sendbuf = "done"; 97 int iResult, iSendResult; 98 99 // Validate the parameters 100 if (argc != 1) { 101 ExitOnError("Finish.exe takes no parameters", FALSE); 102 } 103 104 // Initialize Winsock 105 iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 106 if (iResult != 0) { 107 ExitOnError("WSAStartup failed", FALSE); 108 } 109 110 // Resolve the server address and port 111 ListenSocket = PrepareListenSocket(DEFAULT_PORT); 112 113 // Accept a client socket 114 ClientSocket = accept(ListenSocket, NULL, NULL); 115 if (ClientSocket == INVALID_SOCKET) { 116 closesocket(ListenSocket); 117 ExitOnError("Accept failed", TRUE); 118 } 119 120 // No longer need the server socket 121 closesocket(ListenSocket); 122 123 // Send the ack string to the client 124 iSendResult = send(ClientSocket, sendbuf, sizeof(sendbuf), 0); 125 if (iSendResult == SOCKET_ERROR) { 126 closesocket(ClientSocket); 127 ExitOnError("Send failed", TRUE); 128 } 129 // Report the number of bytes sent 130 printf("Bytes sent: %d\n", iSendResult); 131 132 // Shutdown the connection since we're done 133 iResult = shutdown(ClientSocket, SD_SEND); 134 if (iResult == SOCKET_ERROR) { 135 closesocket(ClientSocket); 136 ExitOnError("Shutdown failed", TRUE); 137 } 138 139 // Cleanup 140 closesocket(ClientSocket); 141 WSACleanup(); 142 143 return 0; 144} 145