//============================================================================= // YHTTPD // yParser //============================================================================= // C #include #include #include #include #include // C++ #include #include #include // system #include #include #include // tuxbox #include #include #include // yhttpd #include #include #include #include #include "mod_yparser.h" #include //============================================================================= // Initialization of static variables //============================================================================= pthread_mutex_t CyParser::yParser_mutex = PTHREAD_MUTEX_INITIALIZER; ; std::string CyParser::HTML_DIRS[HTML_DIR_COUNT]; std::string CyParser::PLUGIN_DIRS[PLUGIN_DIR_COUNT]; std::map CyParser::ycgi_global_vars; struct stat CyParser::yCached_blocks_attrib; std::string CyParser::yCached_blocks_filename; std::string CyParser::yCached_blocks_content; //============================================================================= // Constructor & Destructor //============================================================================= CyParser::CyParser() { yConfig = new CConfigFile(','); yCached_blocks_attrib.st_mtime = 0; } //----------------------------------------------------------------------------- CyParser::~CyParser(void) { if (yConfig != NULL) delete yConfig; } //----------------------------------------------------------------------------- void CyParser::init(CyhookHandler *hh) { if (HTML_DIRS[0].empty()) { CyParser::HTML_DIRS[0] = hh->WebserverConfigList["WebsiteMain.override_directory"]; HTML_DIRS[1] = hh->WebserverConfigList["WebsiteMain.directory"]; PLUGIN_DIRS[0]=PLUGIN_DIRS[1] = HTML_DIRS[0]; PLUGIN_DIRS[1].append("/scripts"); PLUGIN_DIRS[2]=PLUGIN_DIRS[3] = HTML_DIRS[1]; PLUGIN_DIRS[3].append("/scripts"); } } //============================================================================= // Main Dispatcher / Call definitions for /y/ //============================================================================= const CyParser::TyCgiCall CyParser::yCgiCallList[] = { { "cgi", &CyParser::cgi, "text/html; charset=UTF-8" }, #ifdef Y_CONFIG_FEATURE_SHOW_SERVER_CONFIG { "server-config", &CyParser::cgi_server_config, "text/html"}, #endif }; //----------------------------------------------------------------------------- // HOOK: response_hook Handler // This is the main dispatcher for this module //----------------------------------------------------------------------------- THandleStatus CyParser::Hook_SendResponse(CyhookHandler *hh) { hh->status = HANDLED_NONE; log_level_printf(4, "yparser hook start url:%s\n", hh->UrlData["url"].c_str()); init(hh); CyParser *yP = new CyParser(); // create a Session if (hh->UrlData["fileext"] == "yhtm" || hh->UrlData["fileext"] == "yjs" || hh->UrlData["fileext"] == "ysh") // yParser for y*-Files yP->ParseAndSendFile(hh); else if (hh->UrlData["path"] == "/y/") // /y/ commands { yP->Execute(hh); if (hh->status == HANDLED_NOT_IMPLEMENTED) hh->status = HANDLED_NONE; // y-calls can be implemented anywhere } delete yP; // log_level_printf(4,"yparser hook end status:%d\n",(int)hh->status); // log_level_printf(5,"yparser hook result:%s\n",hh->yresult.c_str()); return hh->status; } //----------------------------------------------------------------------------- // URL Function Dispatching //----------------------------------------------------------------------------- void CyParser::Execute(CyhookHandler *hh) { int index = -1; std::string filename = hh->UrlData["filename"]; log_level_printf(4, "yParser.Execute filename%s\n", filename.c_str()); filename = string_tolower(filename); // debugging informations if (CLogging::getInstance()->getDebug()) { dprintf("Execute CGI : %s\n", filename.c_str()); for (CStringList::iterator it = hh->ParamList.begin(); it != hh->ParamList.end(); ++it) dprintf(" Parameter %s : %s\n", it->first.c_str(), it->second.c_str()); } // get function index for (unsigned int i = 0; i < (sizeof(yCgiCallList) / sizeof(yCgiCallList[0])); i++) if (filename == yCgiCallList[i].func_name) { index = i; break; } if (index == -1) // function not found { hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED); return; } // send header if (std::string(yCgiCallList[index].mime_type).empty()) // set by self ; else if (std::string(yCgiCallList[index].mime_type) == "+xml") // Parameter xml? if (!hh->ParamList["xml"].empty()) hh->SetHeader(HTTP_OK, "text/xml"); else hh->SetHeader(HTTP_OK, "text/plain"); else hh->SetHeader(HTTP_OK, yCgiCallList[index].mime_type); // response hh->status = HANDLED_READY; if (hh->Method == M_HEAD) // HEAD or function call return; else { (this->*yCgiCallList[index].pfunc)(hh); return; } } //============================================================================= // URL Functions //============================================================================= //----------------------------------------------------------------------------- // mini cgi Engine (Entry for ycgi) //----------------------------------------------------------------------------- void CyParser::cgi(CyhookHandler *hh) { std::string htmlfilename, yresult, ycmd; if ( !hh->ParamList.empty() ) { if (!hh->ParamList["tmpl"].empty()) // for GET and POST htmlfilename = hh->ParamList["tmpl"]; else htmlfilename = hh->ParamList["1"]; bool ydebug = false; if (!hh->ParamList["debug"].empty()) // switch debug on ydebug = true; if (!hh->ParamList["execute"].empty()) // execute done first! { ycmd = hh->ParamList["execute"]; ycmd = YPARSER_ESCAPE_START + ycmd + YPARSER_ESCAPE_END; yresult = cgi_cmd_parsing(hh, ycmd, ydebug); // parsing engine } // parsing given file if (!htmlfilename.empty()) yresult = cgi_file_parsing(hh, htmlfilename, ydebug); } else printf("[CyParser] Y-cgi:no parameter given\n"); if (yresult.empty()) hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED); else hh->addResult(yresult, HANDLED_READY); } //----------------------------------------------------------------------------- // URL: server-config //----------------------------------------------------------------------------- #ifdef Y_CONFIG_FEATURE_SHOW_SERVER_CONFIG void CyParser::cgi_server_config(CyhookHandler *hh) { std::string yresult; hh->SendHTMLHeader("Webserver Configuration"); yresult += string_printf("Webserver Config
\n"); yresult += string_printf("Webserver \"%s\"
\n",WEBSERVERNAME); yresult += string_printf("
CONFIG (compiled)
\n"); yresult += string_printf("Config File: %s
\n", HTTPD_CONFIGFILE); yresult += string_printf("Upload File: %s
\n", UPLOAD_TMP_FILE); yresult += string_printf("
CONFIG (Config File)
\n"); // Cofig file yresult += string_printf("\n"); CStringList::iterator i = (hh->WebserverConfigList).begin(); for (; i!= (hh->WebserverConfigList).end(); i++ ) { if( ((*i).first) != "mod_auth.username" && ((*i).first) != "mod_auth.password") yresult += string_printf("\n", ((*i).first).c_str(), ((*i).second).c_str()); } yresult += string_printf("
%s%s
\n"); // hook list yresult += string_printf("
Hooks (Compiled)
\n"); yresult += string_printf("\n"); THookList::iterator j = hh->HookList.begin(); for (; j!= hh->HookList.end(); j++ ) { yresult += string_printf("\n", ((*j)->getHookName()).c_str(), ((*j)->getHookVersion()).c_str()); } yresult += string_printf("
%s%s
\n"); hh->addResult(yresult, HANDLED_READY); hh->SendHTMLFooter(); } #endif //============================================================================= // y Parsing and sending .yhtm Files (Main ENTRY) //============================================================================= void CyParser::ParseAndSendFile(CyhookHandler *hh) { bool ydebug = false; std::string yresult, ycmd; log_level_printf(3, "yParser.ParseAndSendFile: File: %s\n", (hh->UrlData["filename"]).c_str()); hh->SetHeader(HTTP_OK, "text/html; charset=UTF-8"); if (hh->Method == M_HEAD) return; if (!hh->ParamList["debug"].empty()) // switch debug on ydebug = true; if (!hh->ParamList["execute"].empty()) // execute done first! { ycmd = hh->ParamList["execute"]; ycmd = YPARSER_ESCAPE_START + ycmd + YPARSER_ESCAPE_END; log_level_printf(3, ": Execute!: %s\n", ycmd.c_str()); yresult = cgi_cmd_parsing(hh, ycmd, ydebug); // parsing engine } // parsing given file yresult += cgi_file_parsing(hh, hh->UrlData["path"]+hh->UrlData["filename"], ydebug); if (yresult.empty()) hh->SetError(HTTP_NOT_IMPLEMENTED, HANDLED_NOT_IMPLEMENTED); else { hh->addResult(yresult, HANDLED_READY); if (!ycgi_vars["cancache"].empty()) { hh->HookVarList["CacheCategory"] = ycgi_vars["cancache"]; hh->HookVarList["CacheMimeType"] = hh->ResponseMimeType; hh->status = HANDLED_CONTINUE; } } } //============================================================================= // y Parsing helpers //============================================================================= //----------------------------------------------------------------------------- // mini cgi Engine (file parsing) //----------------------------------------------------------------------------- std::string CyParser::cgi_file_parsing(CyhookHandler *hh, std::string htmlfilename, bool ydebug) { bool found = false; std::string htmlfullfilename, yresult, html_template; bool isHosted = false; #ifdef Y_CONFIG_USE_HOSTEDWEB // for hosted webs: search in hosted_directory only std::string _hosted=hh->WebserverConfigList["WebsiteMain.hosted_directory"]; if((hh->UrlData["path"]).compare(0,_hosted.length(),hh->WebserverConfigList["WebsiteMain.hosted_directory"]) == 0) // hosted Web ? isHosted = true; #endif //Y_CONFIG_USE_HOSTEDWEB char cwd[255]; getcwd(cwd, 254); for (unsigned int i = 0; i < (isHosted ? 1 : HTML_DIR_COUNT) && !found; i++) { htmlfullfilename = (isHosted ? "" : HTML_DIRS[i]) + "/" + htmlfilename; std::fstream fin(htmlfullfilename.c_str(), std::fstream::in); if (fin.good()) { found = true; chdir(HTML_DIRS[i].c_str()); // set working dir // read whole file into html_template std::string ytmp; while (!fin.eof()) { getline(fin, ytmp); html_template = html_template + ytmp + "\r\n"; } yresult += cgi_cmd_parsing(hh, html_template, ydebug); // parsing engine fin.close(); } } chdir(cwd); if (!found) { printf("[CyParser] Y-cgi:template %s not found %s\n", htmlfilename.c_str(), isHosted ? "" : "in"); if (!isHosted) for (unsigned int i = 0; i < HTML_DIR_COUNT; i++) { printf("%s\n", HTML_DIRS[i].c_str()); } } return yresult; } //----------------------------------------------------------------------------- // main parsing (nested and recursive) //----------------------------------------------------------------------------- std::string CyParser::cgi_cmd_parsing(CyhookHandler *hh, std::string html_template, bool ydebug) { std::string::size_type start, end; unsigned int esc_len = strlen(YPARSER_ESCAPE_START); bool is_cmd; std::string ycmd, yresult; do // replace all {==} nested and recursive { is_cmd = false; if ((end = html_template.find(YPARSER_ESCAPE_END)) != std::string::npos) // 1. find first y-end { if (ydebug) hh->printf("[ycgi debug]: END at:%d following:%s
\n", end, (html_template.substr(end, 10)).c_str()); if ((start = html_template.rfind(YPARSER_ESCAPE_START, end)) != std::string::npos) // 2. find next y-start befor { if (ydebug) hh->printf("[ycgi debug]: START at:%d following:%s
\n", start, (html_template.substr(start + esc_len, 10)).c_str()); ycmd = html_template.substr(start + esc_len, end - (start + esc_len)); //3. get cmd if (ydebug) hh->printf("[ycgi debug]: CMD:[%s]
\n", ycmd.c_str()); yresult = YWeb_cgi_cmd(hh, ycmd); // 4. execute cmd log_level_printf(5, ": ycmd...:%s\n", ycmd.c_str()); log_level_printf(6, ": yresult:%s\n", yresult.c_str()); if (ydebug) hh->printf("[ycgi debug]: RESULT:[%s]
\n", yresult.c_str()); html_template.replace(start, end - start + esc_len, yresult); // 5. replace cmd with output is_cmd = true; // one command found if (ydebug) hh->printf("[ycgi debug]: STEP
\n%s
\n", html_template.c_str()); } } } while (is_cmd); return html_template; } //============================================================================= // ycmd - Dispatching //============================================================================= //----------------------------------------------------------------------------- // ycgi : cmd executing // comment:~ // script: // include: // func: (funcname to be implemented in CyParser::YWeb_cgi_func) // ini-get:;[;][~open|cache] // ini-set:;;[~open|save|cache] // if-empty:~~ // if-equal:~~~ (left_value == right_value?) // if-not-equal:~~~ (left_value == right_value?) // if-file-exists:~~ // find-exec: // include-block:;[;] // var-get: // var-set:= // global-var-get: // global-var-set:= // file-action:;[;] // L: //----------------------------------------------------------------------------- std::string CyParser::YWeb_cgi_cmd(CyhookHandler *hh, std::string ycmd) { std::string ycmd_type, ycmd_name, yresult; if (ySplitString(ycmd, ":", ycmd_type, ycmd_name)) { if (ycmd_type == "L") yresult = CLanguage::getInstance()->getTranslation(ycmd_name); else if (ycmd_type == "comment") { std::string comment_y, comment_html; if (ySplitString(ycmd_name, "~", comment_y, comment_html)) { if (!comment_html.empty()) yresult = ""; } } else if (ycmd_type == "script") yresult = YexecuteScript(hh, ycmd_name); else if (ycmd_type == "if-empty") { std::string if_value, if_then, if_else; if (ySplitString(ycmd_name, "~", if_value, if_then)) { ySplitString(if_then, "~", if_then, if_else); yresult = (if_value.empty()) ? if_then : if_else; } } else if (ycmd_type == "if-equal") { std::string if_left_value, if_right_value, if_then, if_else; if (ySplitString(ycmd_name, "~", if_left_value, if_right_value)) { if (ySplitString(if_right_value, "~", if_right_value, if_then)) { ySplitString(if_then, "~", if_then, if_else); yresult = (if_left_value == if_right_value) ? if_then : if_else; } } } else if (ycmd_type == "if-not-equal") { std::string if_left_value, if_right_value, if_then, if_else; if (ySplitString(ycmd_name, "~", if_left_value, if_right_value)) { if (ySplitString(if_right_value, "~", if_right_value, if_then)) { ySplitString(if_then, "~", if_then, if_else); yresult = (if_left_value != if_right_value) ? if_then : if_else; } } } else if (ycmd_type == "if-file-exists") { std::string if_value, if_then, if_else; if (ySplitString(ycmd_name, "~", if_value, if_then)) { ySplitString(if_then, "~", if_then, if_else); yresult = (access(if_value, R_OK) == 0) ? if_then : if_else; } } else if (ycmd_type == "find-exec") { yresult = find_executable(ycmd_name.c_str()); } else if (ycmd_type == "include") { std::string ytmp; std::fstream fin(ycmd_name.c_str(), std::fstream::in); if (fin.good()) { while (!fin.eof()) { getline(fin, ytmp); yresult += ytmp + "\n"; } fin.close(); } } else if (ycmd_type == "include-block") { std::string filename, blockname, tmp, ydefault; if (ySplitString(ycmd_name, ";", filename, tmp)) { ySplitString(tmp, ";", blockname, ydefault); yresult = YWeb_cgi_include_block(filename, blockname, ydefault); } } else if (ycmd_type == "func") yresult = this->YWeb_cgi_func(hh, ycmd_name); else if (ycmd_type == "define-get") { if (ycmd_name.compare("CONFIGDIR")) yresult = CONFIGDIR; else if (ycmd_name.compare("DATADIR")) yresult = DATADIR; else if (ycmd_name.compare("FONTDIR")) yresult = FONTDIR; else if (ycmd_name.compare("LIBDIR")) yresult = LIBDIR; else if (ycmd_name.compare("GAMESDIR")) yresult = GAMESDIR; else if (ycmd_name.compare("PLUGINDIR")) yresult = PLUGINDIR; else if (ycmd_name.compare("PLUGINDIR_VAR")) yresult = PLUGINDIR_VAR; else if (ycmd_name.compare("LUAPLUGINDIR")) yresult = LUAPLUGINDIR; else if (ycmd_name.compare("LOCALEDIR")) yresult = LOCALEDIR; else if (ycmd_name.compare("LOCALEDIR_VAR")) yresult = LOCALEDIR_VAR; else if (ycmd_name.compare("THEMESDIR")) yresult = THEMESDIR; else if (ycmd_name.compare("THEMESDIR_VAR")) yresult = THEMESDIR_VAR; else if (ycmd_name.compare("ICONSDIR")) yresult = ICONSDIR; else if (ycmd_name.compare("ICONSDIR_VAR")) yresult = ICONSDIR_VAR; else if (ycmd_name.compare("LOGODIR")) yresult = LOGODIR; else if (ycmd_name.compare("LOGODIR_VAR")) yresult = LOGODIR_VAR; else if (ycmd_name.compare("PRIVATE_HTTPDDIR")) yresult = PRIVATE_HTTPDDIR; else if (ycmd_name.compare("PUBLIC_HTTPDDIR")) yresult = PUBLIC_HTTPDDIR; else if (ycmd_name.compare("HOSTED_HTTPDDIR")) yresult = HOSTED_HTTPDDIR; else yresult = ""; } else if (ycmd_type == "ini-get") { std::string filename, varname, tmp, ydefault, yaccess; ySplitString(ycmd_name, "~", filename, yaccess); if (ySplitString(filename, ";", filename, tmp)) { ySplitString(tmp, ";", varname, ydefault); yresult = YWeb_cgi_get_ini(hh, filename, varname, yaccess); if (yresult.empty() && !ydefault.empty()) yresult = ydefault; } else yresult = "ycgi: ini-get: no ; found"; } else if (ycmd_type == "ini-set") { std::string filename, varname, varvalue, tmp, yaccess; ySplitString(ycmd_name, "~", filename, yaccess); if (ySplitString(filename, ";", filename, tmp)) { if (ySplitString(tmp, ";", varname, varvalue)) YWeb_cgi_set_ini(hh, filename, varname, varvalue, yaccess); } else yresult = "ycgi: ini-get: no ; found"; } else if (ycmd_type == "var-get") { yresult = ycgi_vars[ycmd_name]; } else if (ycmd_type == "var-set") { std::string varname, varvalue; if (ySplitString(ycmd_name, "=", varname, varvalue)) ycgi_vars[varname] = varvalue; } else if (ycmd_type == "global-var-get") { pthread_mutex_lock(&yParser_mutex); yresult = ycgi_global_vars[ycmd_name]; pthread_mutex_unlock(&yParser_mutex); } else if (ycmd_type == "global-var-set") { std::string varname, varvalue; if (ySplitString(ycmd_name, "=", varname, varvalue)) { pthread_mutex_lock(&yParser_mutex); ycgi_global_vars[varname] = varvalue; pthread_mutex_unlock(&yParser_mutex); } } else if (ycmd_type == "file-action") { std::string filename, actionname, content, tmp; if (ySplitString(ycmd_name, ";", filename, tmp)) { ySplitString(tmp, ";", actionname, content); replace(content, "\r\n", "\n"); if (actionname == "add") { std::fstream fout(filename.c_str(), std::fstream::out | std::fstream::binary); fout << content; fout.close(); } else if (actionname == "append") { std::fstream fout(filename.c_str(), std::fstream::app | std::fstream::binary); fout << content; fout.close(); } else if (actionname == "delete") { remove(filename.c_str()); } } } else yresult = "ycgi-type unknown"; } else if (!hh->ParamList[ycmd].empty()) { #if 0 if ((hh->ParamList[ycmd]).find("script") == std::string::npos) yresult = hh->ParamList[ycmd]; else yresult = ""; #else yresult = hh->ParamList[ycmd]; #endif } return yresult; } //------------------------------------------------------------------------- // Get Value from ini/conf-file (filename) for var (varname) // yaccess = open | cache //------------------------------------------------------------------------- std::string CyParser::YWeb_cgi_get_ini(CyhookHandler *, std::string filename, std::string varname, std::string yaccess) { std::string result; if ((yaccess == "open") || (yaccess.empty())) { yConfig->clear(); yConfig->loadConfig(filename); } result = yConfig->getString(varname, ""); return result; } //------------------------------------------------------------------------- // set Value from ini/conf-file (filename) for var (varname) // yaccess = open | cache | save //------------------------------------------------------------------------- void CyParser::YWeb_cgi_set_ini(CyhookHandler *, std::string filename, std::string varname, std::string varvalue, std::string yaccess) { if ((yaccess == "open") || (yaccess.empty())) { yConfig->clear(); yConfig->loadConfig(filename); } yConfig->setString(varname, varvalue); if ((yaccess == "save") || (yaccess.empty())) yConfig->saveConfig(filename); } //------------------------------------------------------------------------- // Get text block named from file // The textblock starts with "start-block~" and ends with // "end-block~" //------------------------------------------------------------------------- std::string CyParser::YWeb_cgi_include_block(std::string filename, std::string blockname, std::string ydefault) { std::string ytmp, yfile, yresult; struct stat attrib; yresult = ydefault; stat(filename.c_str(), &attrib); pthread_mutex_lock(&yParser_mutex); if ((attrib.st_mtime == yCached_blocks_attrib.st_mtime) && (filename == yCached_blocks_filename)) { log_level_printf(6, "include-block: (%s) from cache\n", blockname.c_str()); yfile = yCached_blocks_content; } else { bool found = false; for (unsigned int i = 0; i < HTML_DIR_COUNT && !found; i++) { std::string ifilename = HTML_DIRS[i] + "/" + filename; std::fstream fin(ifilename.c_str(), std::fstream::in); if (fin.good()) { found = true; while (!fin.eof()) // read whole file into yfile { getline(fin, ytmp); yfile += ytmp + "\n"; } fin.close(); } } yCached_blocks_content = yfile; yCached_blocks_attrib = attrib; yCached_blocks_filename = filename; log_level_printf(6, "include-block: (%s) from file\n", blockname.c_str()); } pthread_mutex_unlock(&yParser_mutex); if (!yfile.empty()) { std::string t = "start-block~" + blockname; std::string::size_type start, end; if ((start = yfile.find(t)) != std::string::npos) { if ((end = yfile.find("end-block~" + blockname, start + t.length())) != std::string::npos) { yresult = yfile.substr(start + t.length(), end - (start + t.length())); log_level_printf(7, "include-block: (%s) yresult:(%s)\n", blockname.c_str(), yresult.c_str()); } else aprintf( "include-blocks: Block END not found:%s Blockname:%s\n", filename.c_str(), blockname.c_str()); } else aprintf("include-blocks: Block START not found:%s Blockname:%s\n", filename.c_str(), blockname.c_str()); } else aprintf("include-blocks: file not found:%s Blockname:%s\n", filename.c_str(), blockname.c_str()); return yresult; } //------------------------------------------------------------------------- std::string CyParser::YexecuteScript(CyhookHandler *, std::string cmd) { std::string script, para, result; bool found = false; // split script and parameters int pos; if ((pos = cmd.find_first_of(" ")) > 0) { script = cmd.substr(0, pos); para = cmd.substr(pos + 1, cmd.length() - (pos + 1)); // snip } else script = cmd; // get file std::string fullfilename; script += ".sh"; //add script extention char cwd[255]; getcwd(cwd, 254); for (unsigned int i = 0; i < PLUGIN_DIR_COUNT && !found; i++) { fullfilename = PLUGIN_DIRS[i] + "/" + script; FILE *test = fopen(fullfilename.c_str(), "r"); // use fopen: popen does not work if (test != NULL) { fclose(test); chdir(PLUGIN_DIRS[i].c_str()); FILE *f = popen((fullfilename + " " + para).c_str(), "r"); //execute if (f != NULL) { found = true; char output[1024]; while (fgets(output, 1024, f)) // get script output result += output; pclose(f); } } } chdir(cwd); if (!found) { printf(" script %s not found in\n", script.c_str()); for (unsigned int i = 0; i < PLUGIN_DIR_COUNT; i++) { printf("%s\n", PLUGIN_DIRS[i].c_str()); } result = "error"; } return result; } //============================================================================= // y-func : Dispatching // TODO: new functions for // - Compiler-Time Settings like *httpd.conf etc // - Versions of httpd, yParser, Hooks, //============================================================================= const CyParser::TyFuncCall CyParser::yFuncCallList[] = { { "get_request_data", &CyParser::func_get_request_data }, { "get_header_data", &CyParser::func_get_header_data }, { "get_config_data", &CyParser::func_get_config_data }, { "do_reload_httpd_config", &CyParser::func_do_reload_httpd_config }, { "httpd_change", &CyParser::func_change_httpd }, { "get_languages_as_dropdown", &CyParser::func_get_languages_as_dropdown }, { "set_language", &CyParser::func_set_language }, }; //------------------------------------------------------------------------- // y-func : dispatching and executing //------------------------------------------------------------------------- std::string CyParser::YWeb_cgi_func(CyhookHandler *hh, std::string ycmd) { std::string func, para, yresult = "ycgi func not found"; //bool found = false; ySplitString(ycmd, " ", func, para); for (unsigned int i = 0; i < (sizeof(yFuncCallList) / sizeof(yFuncCallList[0])); i++) if (func == yFuncCallList[i].func_name) { yresult = (this->*yFuncCallList[i].pfunc)(hh, para); //found = true; break; } log_level_printf(8, ":%s Result:%s\n", func.c_str(), yresult.c_str()); return yresult; } //------------------------------------------------------------------------- // y-func : get_request_data //------------------------------------------------------------------------- std::string CyParser::func_get_request_data(CyhookHandler *hh, std::string para) { std::string yresult; if (para == "client_addr") yresult = hh->UrlData["clientaddr"]; //compatibility TODO in yhtms else yresult = hh->UrlData[para]; return yresult; } //------------------------------------------------------------------------- // y-func : get_header_data //------------------------------------------------------------------------- std::string CyParser::func_get_header_data(CyhookHandler *hh, std::string para) { return hh->HeaderList[para]; } //------------------------------------------------------------------------- // y-func : get_header_data //------------------------------------------------------------------------- std::string CyParser::func_get_config_data(CyhookHandler *hh, std::string para) { if (para != "mod_auth.username" && para != "mod_auth.password") return hh->WebserverConfigList[para]; else return "empty"; } //------------------------------------------------------------------------- // y-func : Reload the httpd.conf //------------------------------------------------------------------------- extern void yhttpd_reload_config(); std::string CyParser::func_do_reload_httpd_config(CyhookHandler *, std::string) { log_level_printf(1, "func_do_reload_httpd_config: raise USR1 !!!\n"); //raise(SIGUSR1); // Send HUP-Signal to Reload Settings yhttpd_reload_config(); return ""; } //------------------------------------------------------------------------- // y-func : Change httpd (process image) on the fly //------------------------------------------------------------------------- std::string CyParser::func_change_httpd(CyhookHandler *hh, std::string para) { if (!para.empty() && access(para, R_OK) == 0) { hh->status = HANDLED_ABORT; char * argv[2] = { (char *)para.c_str(), NULL }; int err = execvp(argv[0], argv); // no return if successful return "ERROR [change_httpd]: execvp returns error code: " + err; } else return "ERROR [change_httpd]: para has not path to a file"; } //------------------------------------------------------------------------- // y-func : get_header_data //------------------------------------------------------------------------- std::string CyParser::func_get_languages_as_dropdown(CyhookHandler *, std::string para) { std::string yresult, sel; DIR *d; std::string act_language = CLanguage::getInstance()->language; d = opendir((CLanguage::getInstance()->language_dir).c_str()); if (d != NULL) { struct dirent *dir; while ((dir = readdir(d))) { if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) continue; if (dir->d_type != DT_DIR) { sel = (act_language == std::string(dir->d_name)) ? "selected=\"selected\"" : ""; yresult += string_printf("", dir->d_name, sel.c_str(), (encodeString(std::string(dir->d_name))).c_str()); if(para != "nonl") yresult += "\n"; } } closedir(d); } return yresult; } //------------------------------------------------------------------------- // y-func : get_header_data //------------------------------------------------------------------------- std::string CyParser::func_set_language(CyhookHandler *, std::string para) { if (!para.empty()) { CConfigFile *Config = new CConfigFile(','); Config->loadConfig(HTTPD_CONFIGFILE); Config->setString("Language.selected", para); Config->saveConfig(HTTPD_CONFIGFILE); yhttpd_reload_config(); } return ""; }