// Host Update // // Douglas Thrift // // $Id$ #include "HostUpdate.hpp" #include "Host.hpp" #ifdef _WIN32 #include #endif int main(int argc, char* argv[]) { HostUpdate update; return 0; } HostUpdate::HostUpdate() { struct stat* hosts = new struct stat; if (stat("hosts", hosts) != 0) { mkdir("hosts"); } delete [] hosts; string agent = sgetenv("HTTP_USER_AGENT"); string method = sgetenv("REQUEST_METHOD"); parse(method); if (agent.find("Host Update/") == 0 && method == "POST" && agent.find(" (") != string::npos && agent.find(") libwww-perl/") != string::npos) { update(agent); } else { display(); } } void HostUpdate::parse(const string& method) { string query; if (method == "POST") { getline(cin, query); } else { query = sgetenv("QUERY_STRING"); } if (query == "") return; istringstream input(query); do { string name, value; getline(input, name, '='); getline(input, value, '&'); cgi.insert(pair(name, value)); } while (input.good()); } void HostUpdate::update(const string& agent) { cout << "Content-Type: text/plain\n\n"; multimap::iterator itor = cgi.find("host"); if (itor == cgi.end()) return; if (itor->second == "") return; string host = itor->second, name = sgetenv("REMOTE_HOST"), address = sgetenv("REMOTE_ADDR"); string::size_type begin = agent.find('(') + 1, end = agent.find(')', begin); string platform = agent.substr(begin, end - begin); Host client(host, name, address, platform), saved(host); cout << "host=" << client.getHost() << '\n' << "name=" << client.getName() << '\n' << "address=" << client.getAddress() << '\n' << "platform=" << client.getPlatform() << '\n'; if (client != ++saved) client--; } void HostUpdate::display() { cout << "Content-Type: text/plain\n\n"; set hosts; #ifndef _WIN32 DIR* dir = opendir("hosts"); struct dirent* ent; while ((ent = readdir(dir)) != NULL) { string file = ent->d_name; if (file == "." || file == "..") continue; Host host(file); hosts.insert(++host); } closedir(dir); #else WIN32_FIND_DATA found; HANDLE find = FindFirstFile("hosts\\*", &found); do { string file = found.cFileName; if (file == "." || file == "..") continue; Host host(file); hosts.insert(++host); } while (FindNextFile(find, &found) != 0); FindClose(find); #endif for (set::iterator itor = hosts.begin(); itor != hosts.end(); itor++) { display(*itor); } } void HostUpdate::display(const Host& host) { cout << "host=" << host.getHost() << '\n' << "name=" << host.getName() << '\n' << "address=" << host.getAddress() << '\n' << "platform=" << host.getPlatform() << '\n'; string name = string("hosts") + slash + host.getHost(); struct stat file; if (stat(name.c_str(), &file) == 0) { char since[20]; strftime(since, 20, "%m/%d/%Y %H:%M:%S", gmtime(&file.st_mtime)); cout << "since=" << since << " GMT\n"; } }