// Feeping Creaturism // // Douglas Thrift // // $Id$ #include "Environment.hpp" #include "Matcher.hpp" #include "Jargon.hpp" extern "C" { #include #include #include } int main(int argc, char* argv[]) { FeepingCreaturism::program = argv[0]; FeepingCreaturism creaturism; return 0; } FeepingCreaturism::FeepingCreaturism() { initialize(); std::string path(env.get("PATH_INFO")); Matcher matcher; if (path == "/daily/") daily(); else if (path == "/random/") { random(); } else if (path == matcher("^/(" + this->matcher + ")$")) { select(matcher[1], true); } else { cout << "Status: 301\r\n"; } } std::string FeepingCreaturism::program; void FeepingCreaturism::initialize() { ext::Handle document(xml::Parse("jargon.xml")); ext::Handle node(*document/"feepingcreaturism"); this->path = *node/"jargon"; this->matcher = *node/"matcher"; char* path[] = { new char[this->path.size()] }; std::strcpy(path[0], this->path.c_str()); ::FTS* traversal(::fts_open(path, FTS_LOGICAL, NULL)); Matcher matcher('^' + this->path + "/(" + this->matcher + ")$"); if (traversal == NULL) { cerr << program << ": Horrible Failure!\n"; std::exit(1); } for (::FTSENT* entity(::fts_read(traversal)); entity != NULL; entity = ::fts_read(traversal)) { if (entity->fts_info == FTS_F && entity->fts_path == matcher) { jargon.insert(matcher[1]); } } ::fts_close(traversal); delete [] path[0]; } void FeepingCreaturism::daily() { std::time_t when(std::time(NULL)); std::tm* now(std::localtime(&when)); now->tm_sec = 0; now->tm_min = 0; now->tm_hour = 0; std::time_t difference(mktime(now) / 86400); std::vector jargon(this->jargon.begin(), this->jargon.end()); std::string entry(jargon.size() ? jargon[difference % jargon.size()] : ""); select(entry); } void FeepingCreaturism::random() { ::srandomdev(); std::vector jargon(this->jargon.begin(), this->jargon.end()); std::string entry(jargon.size() ? jargon[::random() % jargon.size()] : ""); select(entry); } void FeepingCreaturism::select(const std::string& selection, bool validate) { if (!validate || jargon.find(selection) != jargon.end()) { cout << "Content-Type: text/html; charset=UTF-8\r\n\r\n"; Jargon jargon(path + '/' + selection); cout << jargon; } else { cout << "Status: 404\r\nContent-Type: text/html; charset=ISO-8859-1\r\n" << "\r\n\n" << "\n404 Not Found\n\n" << "

Not Found

\n

The requested URL " << env.get("PATH_INFO") << " was not found on this server.

\n" << "
\n" << env.get("SERVER_SIGNATURE") << "\n"; } }