#include "cli_parser.h" #include "network_utils.h" #include "utils.h" #include #include #include #include std::mutex fileMutex; void scanIp(const std::string &ip, int port, const config &cfg, const std::string &filename) { std::string result = pingMinecraftServer(ip, port, cfg.virtualHostname, cfg.virtualPort, cfg.protocolVersion, cfg.nextState); if (!result.starts_with("ERROR")) { std::lock_guard lock(fileMutex); // Locking here to manage concurrent file access std::ofstream file(filename, std::ios::app | std::ios::out); if (!file.is_open()) { std::cerr << "Failed to open file for writing: " << filename << std::endl; return; } // Write the scan result as a tab-separated line file << ip << '\t' << port << '\t' << cfg.virtualHostname << '\t' << cfg.virtualPort << '\t' << cfg.protocolVersion << '\t' << cfg.nextState << '\t' << result << '\n'; file.close(); } } int main(int argc, char *argv[]) { config cfg; cfg.parseCommandLine(argc, argv); std::vector ips = parseIps(cfg.hostname); // handles both CIDR and single IPs std::string outputFilename = "responsive_" + makePathSafe(cfg.hostname) + ".tsv"; // Create and write headers to the output file std::ofstream outfile(outputFilename, std::ios::out); if (!outfile.is_open()) { std::cerr << "Failed to open file for writing: " << outputFilename << std::endl; return 1; } outfile << "IP Address\tPort\tVirtual Hostname\tVirtual Port\tProtocol Version\tNext State\tStatus\n"; outfile.close(); // Multithreaded scanning std::vector threads; for (const auto &ip: ips) { (void) threads.emplace_back(scanIp, ip, cfg.port, std::ref(cfg), outputFilename); usleep(10000); } for (auto &thread: threads) { thread.join(); } return 0; }