144 lines
3.8 KiB
C++
144 lines
3.8 KiB
C++
// 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;
|
|
}
|