--- HostUpdate/HostUpdate.cpp 2003/11/06 02:29:00 2 +++ HostUpdate/HostUpdate.cpp 2004/03/02 03:41:20 91 @@ -1,29 +1,245 @@ -// Host Update -// -// Douglas Thrift -// -// $Id$ - -#include "HostUpdate.hpp" - -int main(int argc, char* argv[]) -{ - HostUpdate update; - - return 0; -} - -HostUpdate::HostUpdate() -{ - CgiEnvironment env = cgi.getEnvironment(); - - cout << "Location: " << (env.usingHTTPS() ? "https" : "http") << "://" - << env.getServerName() << ":" << env.getServerPort() << "/\n\n"; - - form_iterator itor = cgi["host"]; - FormEntry host = *itor; -} - -HostUpdate::~HostUpdate() -{ -} +// 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); + mode(); + + if (agent.find("Host Update/") == 0 && method == "POST" && agent.find(" (") + != string::npos && agent.find(") libwww-perl/") != string::npos) + { + update(agent); + } + else if (agent.find("Host Update Sharp/") == 0 && method == "POST" && + agent.find(" (") != string::npos && agent.find(')') != 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::mode() +{ + host = false, name = false, address = false, platform = false, since = + false; + + for (multimap::iterator itor = cgi.find("mode"); itor != + cgi.upper_bound("mode") && itor != cgi.end(); itor++) + { + string mode = itor->second; + + for (string::iterator itor = mode.begin(); itor != mode.end(); itor++) + { + char mode = *itor; + + switch (mode) + { + case 'h': + if (!host) host = true; + break; + case 'n': + if (!name) name = true; + break; + case 'a': + if (!address) address = true; + break; + case 'p': + if (!platform) platform = true; + break; + case 's': + if (!since) since = true; + break; + default: + break; + } + } + } + + if (!host && !name && !address && !platform && !since) host = true, name = + true, address = true, platform = true, since = true; +} + +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.rfind(')'); + + if (begin >= end) return; + + string platform = agent.substr(begin, end - begin); + + Host client(host, name, address, platform), saved(host); + + if (client != ++saved) client--; + + display(client); +} + +void HostUpdate::display() +{ + cout << "Content-Type: text/plain\n\n"; + + { + bool request = false; + + for (multimap::iterator itor = cgi.find("host"); itor != + cgi.upper_bound("host") && itor != cgi.end(); itor++) + { + if (itor->second != "") + { + Host host(itor->second); + + display(++host); + + if (!request) request = true; + } + } + + if (request) return; + } + + 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) +{ + if (this->host) cout << "host=" << host.getHost() << '\n'; + if (name) cout << "name=" << host.getName() << '\n'; + if (address) cout << "address=" << host.getAddress() << '\n'; + if (platform) cout << "platform=" << host.getPlatform() << '\n'; + + string name = string("hosts") + slash + host.getHost(); + struct stat file; + + if (since && 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"; + } + else if (since) + { + char since[20]; + time_t* now = new time_t; + + time(now); + strftime(since, 20, "%m/%d/%Y %H:%M:%S", gmtime(now)); + + delete now; + + cout << "since=" << since << " GMT\n"; + } +}