#include "BaseServ.h" #include #include #include class TLerchServer : public TBaseServerApp { protected: virtual const wxChar* GetAppName() const; virtual void ProcessCommand(wxString cmd, wxSocketBase& outs); public: void GenerateFile(wxString& strFilename); bool IsMagicName(wxString& strFilename) const; bool IsCgiName(wxString strFilename) const; void CreateServersList(wxArrayString& arr) const; void ProcessHttpGet(wxString cmd, wxSocketBase& outs); void ProcessFormStart(const THashTable& args, wxSocketBase& sock); void ProcessFormKill(const THashTable& args, wxSocketBase& sock); void CallCgi(wxString& strFileName, wxSocketBase& sock); }; const wxChar* TLerchServer::GetAppName() const { return "Lerch"; } void TLerchServer::CreateServersList(wxArrayString& arr) const { wxFileInputStream ini(GetConfigName()); const size_t size = ini.GetSize(); wxChar* buff = new wxChar[size]; ini.Read(buff, size); const char* aperta = strchr(buff, '['); while (aperta != NULL) { char* chiusa = strchr(aperta+1, ']'); if (chiusa != NULL) { *chiusa = '\0'; wxString str = aperta+1; if (str != GetAppName()) arr.Add(str); aperta = strchr(chiusa+1, '['); } else break; } delete buff; } void TLerchServer::GenerateFile(wxString& strFilename) { TXmlItem html; TXmlItem& body = CreatePageBody(html); if (strFilename == "index") { TXmlItem& table = body.AddChild("table"); table.SetAttr("border", "1"); table.SetAttr("width", "100%"); strFilename = GetTempFilename(); wxArrayString arr; CreateServersList(arr); for (size_t i = 0; i < arr.GetCount(); i++) { wxIniConfig ini("", "", GetConfigName()); wxString str; str << '/' << arr[i]; ini.SetPath(str); wxString strHost; ini.Read("Host", &strHost, wxGetHostName()); int nPort; ini.Read("Port", &nPort, 3883); wxString strIcon; ini.Read("Icon", &strIcon, "euro.gif"); int nRunning; ini.Read("Running", &nRunning, 0); TXmlItem& tr = table.AddChild("tr"); TXmlItem& td0 = tr.AddChild("td"); td0.SetAttr("width", "15%"); td0.SetAttr("align", "center"); TXmlItem& a = td0.AddChild("a"); a.SetAttr("href", wxString::Format("http://%s:%d/index.htm", strHost, nPort)); TXmlItem& img = a.AddChild("img"); img.SetAttr("src", strIcon); img.SetAttr("border", 0); img.SetAttr("alt", arr[i]); TXmlItem& td1 = tr.AddChild("td"); td1.SetAttr("width", "15%"); TXmlItem& form = td1.AddChild("center").AddChild("form"); form.SetAttr("action", nRunning ? "kill.cgi" : "start.cgi"); TXmlItem& name = form.AddChild("input"); name.SetAttr("type", "hidden"); name.SetAttr("name", "App"); name.SetAttr("value", arr[i]); TXmlItem& submit = form.AddChild("input"); submit.SetAttr("type", "submit"); submit.SetAttr("value", nRunning ? "Stop" : "Start"); tr.AddChild("td") << arr[i] << " Server"; } html.Save(strFilename); } } bool TLerchServer::IsMagicName(wxString& strFilename) const { wxString strName; wxSplitPath(strFilename, NULL, &strName, NULL); strName.MakeLower(); if (strName == "index") { strFilename = strName; return true; } if (strName == "log") { strFilename = GetLogFileName(); } return false; } bool TLerchServer::IsCgiName(wxString strFilename) const { const int q = strFilename.Find('?'); if (q > 0) strFilename.Truncate(q); wxString strExt; wxSplitPath(strFilename, NULL, NULL, &strExt); strExt.MakeLower(); return strExt == "cgi" || strExt == "exe"; } void TLerchServer::ProcessFormStart(const THashTable& args, wxSocketBase& sock) { const wxString strApp = args.Get("App"); const wxString strRun = GetConfigString("Run", "", strApp); if (wxFileExists(strRun)) { wxExecute(strRun); for (int i = 0; i < 3; i++) { wxSleep(3); if (GetConfigInt("Running", 0, strApp) == 1) break; } wxString strFileName = "index"; GenerateFile(strFileName); SendFile(strFileName, sock); } else MessageBox("ERROR", wxString::Format("Can't run %s", strRun), sock); } void TLerchServer::ProcessFormKill(const THashTable& args, wxSocketBase& sock) { const wxString strApp = args.Get("App"); const wxString strHost = GetConfigString("Host", "localhost", strApp); const int nPort = GetConfigInt("Port", 0, strApp); if (nPort > 0) { wxIPV4address addr; addr.Hostname(strHost); addr.Service(nPort); wxSocketClient sock; if (sock.Connect(addr)) { const wxString str = "GET /stop.cgi HTTP/1.1\r\n\r\n"; for (int i = 0; i < 3; i++) { sock.Write(str, str.Length()); wxSleep(1); if (GetConfigInt("Running", 0, strApp) == 0) break; } } SetConfigString("Running", "0", strApp); } wxString strFileName = "index"; GenerateFile(strFileName); SendFile(strFileName, sock); } void TLerchServer::CallCgi(wxString& strFileName, wxSocketBase& sock) { wxString strName, strExt, strArgs; const int q = strFileName.Find('?'); if (q > 0) { strArgs = strFileName.Mid(q+1); strFileName.Truncate(q); } wxSplitPath(strFileName, NULL, &strName, &strExt); THashTable hashArgs(13); ParseArguments(strArgs, hashArgs); if (strExt == "cgi") { if (strName == "start") ProcessFormStart(hashArgs, sock); else if (strName == "kill") ProcessFormKill(hashArgs, sock); } } void TLerchServer::ProcessHttpGet(wxString cmd, wxSocketBase& outs) { const int stop = cmd.Find(" HTTP"); wxString str = cmd.Mid(4, stop-4).Trim(); if (str == "/") str += "index.htm"; wxString strFilename = GetDocumentRoot() + str; if (IsCgiName(strFilename)) CallCgi(strFilename, outs); else { if (IsMagicName(strFilename)) GenerateFile(strFilename); SendFile(strFilename, outs); } } void TLerchServer::ProcessCommand(wxString cmd, wxSocketBase& outs) { if (cmd.StartsWith("GET ")) ProcessHttpGet(cmd, outs); } // Istanziare l'applicazione principale IMPLEMENT_APP(TLerchServer)