#include #include #include #include #include #include #include void usage(const char* programName) { std::cerr << "Usage: " << programName << " -h [ -p ]" << std::endl; std::cerr << " selector: The gopher selector to request (e.g., /phlogs/)" << std::endl; std::cerr << " -h : The hostname of the gopher server (e.g., sdf.org)" << std::endl; std::cerr << " -p : The port number of the gopher server (default: 70)" << std::endl; } int main(int argc, char** argv) { if (argc < 4 || std::string(argv[1]) == "-h") { usage(argv[0]); return 1; } std::string selector = argv[1]; std::string host = argv[3]; std::string port = (argc > 4 && std::string(argv[4]) == "-p") ? argv[5] : "70"; for (int i = 2; i < argc; i++) { std::string arg = argv[i]; if (arg == "-h" && i + 1 < argc) { host = argv[++i]; } else if (arg == "-p" && i + 1 < argc) { port = argv[++i]; } else { std::cerr << "Unknown argument: " << arg << std::endl; usage(argv[0]); return 1; } } if (host.empty()) { std::cerr << "Host is required" << std::endl; usage(argv[0]); return 1; } addrinfo hints{}; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; addrinfo* res = nullptr; int status = getaddrinfo(host.c_str(), port.c_str(), &hints, &res); if (status != 0) { std::cerr << "Failed to resolve hostname: " << gai_strerror(status) << std::endl; return 1; } int clientSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (clientSocket < 0) { std::cerr << "Failed to create socket" << std::endl; freeaddrinfo(res); return 1; } int result = connect(clientSocket, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); if (result < 0) { std::cerr << "Failed to connect to server" << std::endl; return 1; } std::string request = selector + "\r\n"; send(clientSocket, request.c_str(), request.size(), 0); char buffer[4096]; ssize_t bytesRead; while ((bytesRead = recv(clientSocket, buffer, sizeof(buffer) - 1, 0)) > 0) { buffer[bytesRead] = '\0'; std::cout << buffer; } std::cout << std::endl; close(clientSocket); return 0; }