| // Simple application that creates a server socket, listening for connections |
| // of the unattended install test. Once it gets a client connected, the |
| // app will send back an ACK string, indicating the install process is done. |
| // |
| // You must link this code with Ws2_32.lib, Mswsock.lib, and Advapi32.lib |
| // |
| // Author: Lucas Meneghel Rodrigues <lmr@redhat.com> |
| // Code was adapted from an MSDN sample. |
| |
| // Usage: finish.exe |
| |
| #ifdef __MINGW32__ |
| #undef _WIN32_WINNT |
| #define _WIN32_WINNT 0x500 |
| #endif |
| |
| #include <windows.h> |
| #include <winsock2.h> |
| #include <ws2tcpip.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| int DEFAULT_PORT = 12323; |
| |
| void ExitOnError(const char *message, BOOL winsock = FALSE) |
| { |
| LPVOID system_message; |
| char buffer[512]; |
| int error_code; |
| |
| if (winsock) |
| error_code = WSAGetLastError(); |
| else |
| error_code = GetLastError(); |
| WSACleanup(); |
| |
| FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| FORMAT_MESSAGE_FROM_SYSTEM, |
| NULL, |
| error_code, |
| MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| (LPTSTR)&system_message, |
| 0, |
| NULL); |
| |
| sprintf(buffer, |
| "%s!\n" |
| "Error code = %d\n" |
| "Error message = %s", |
| message, error_code, (char *)system_message); |
| |
| MessageBox(NULL, buffer, "Error", MB_OK | MB_ICONERROR); |
| |
| LocalFree(system_message); |
| ExitProcess(1); |
| } |
| |
| SOCKET PrepareListenSocket(int port) |
| { |
| sockaddr_in addr; |
| linger l; |
| int result; |
| |
| // Create socket |
| SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
| if (ListenSocket == INVALID_SOCKET) |
| ExitOnError("Socket creation failed", TRUE); |
| |
| // Enable lingering |
| l.l_linger = 10; |
| l.l_onoff = 1; |
| setsockopt(ListenSocket, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)); |
| |
| // Bind the socket |
| addr.sin_family = AF_INET; |
| addr.sin_addr.s_addr = htonl(INADDR_ANY); |
| addr.sin_port = htons(port); |
| |
| result = bind(ListenSocket, (sockaddr *)&addr, sizeof(addr)); |
| if (result == SOCKET_ERROR) |
| ExitOnError("Bind failed", TRUE); |
| |
| // Start listening for incoming connections |
| result = listen(ListenSocket, SOMAXCONN); |
| if (result == SOCKET_ERROR) |
| ExitOnError("Listen failed", TRUE); |
| |
| return ListenSocket; |
| } |
| |
| int main(int argc, char **argv) |
| { |
| WSADATA wsaData; |
| SOCKET ListenSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET; |
| struct addrinfo *result = NULL, hints; |
| char *sendbuf = "done"; |
| int iResult, iSendResult; |
| |
| // Validate the parameters |
| if (argc != 1) { |
| ExitOnError("Finish.exe takes no parameters", FALSE); |
| } |
| |
| // Initialize Winsock |
| iResult = WSAStartup(MAKEWORD(2,2), &wsaData); |
| if (iResult != 0) { |
| ExitOnError("WSAStartup failed", FALSE); |
| } |
| |
| // Resolve the server address and port |
| ListenSocket = PrepareListenSocket(DEFAULT_PORT); |
| |
| // Accept a client socket |
| ClientSocket = accept(ListenSocket, NULL, NULL); |
| if (ClientSocket == INVALID_SOCKET) { |
| closesocket(ListenSocket); |
| ExitOnError("Accept failed", TRUE); |
| } |
| |
| // No longer need the server socket |
| closesocket(ListenSocket); |
| |
| // Send the ack string to the client |
| iSendResult = send(ClientSocket, sendbuf, sizeof(sendbuf), 0); |
| if (iSendResult == SOCKET_ERROR) { |
| closesocket(ClientSocket); |
| ExitOnError("Send failed", TRUE); |
| } |
| // Report the number of bytes sent |
| printf("Bytes sent: %d\n", iSendResult); |
| |
| // Shutdown the connection since we're done |
| iResult = shutdown(ClientSocket, SD_SEND); |
| if (iResult == SOCKET_ERROR) { |
| closesocket(ClientSocket); |
| ExitOnError("Shutdown failed", TRUE); |
| } |
| |
| // Cleanup |
| closesocket(ClientSocket); |
| WSACleanup(); |
| |
| return 0; |
| } |