campo-sirio/server/lerch.cpp
alex 981678913a Patch level : 2.0.369
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la versione P@rtners  2.0 patch 349


git-svn-id: svn://10.65.10.50/trunk@10709 c028cbd2-c16b-5b4b-a496-9718f37d4682
2002-12-20 17:08:30 +00:00

429 lines
11 KiB
C++
Executable File

#include "BaseServ.h"
#include <wx/config.h>
#include <wx/msw/iniconf.h>
#include <ctype.h>
class TLerchServer : public TBaseServerApp
{
protected:
virtual const wxChar* GetAppName() const;
virtual void ProcessCommand(wxString cmd, wxSocketBase& outs);
virtual bool Initialization();
void AddMiniForm(TXmlItem& tr, const wxChar* action, const wxChar* app, const wxChar* prompt) const;
void EnumerateVariables(const wxString& strApp, wxArrayString& arr) const;
void CreateServersList(wxArrayString& arr) const;
void KillProcess(const wxString& strApp);
public:
void GenerateFile(wxString& strFilename);
bool IsMagicName(wxString& strFilename) const;
bool IsCgiName(wxString strFilename) const;
void ProcessHttpGet(wxString cmd, wxSocketBase& outs);
void ProcessHttpPost(wxString cmd, wxSocketBase& outs);
void ProcessFormStart(const THashTable& args, wxSocketBase& sock);
void ProcessFormKill(const THashTable& args, wxSocketBase& sock);
void ProcessFormConfig(const THashTable& args, wxSocketBase& sock);
void ProcessFormUpdate(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;
arr.Add(str);
aperta = strchr(chiusa+1, '[');
}
else
break;
}
delete buff;
}
void TLerchServer::AddMiniForm(TXmlItem& tr, const wxChar* action, const wxChar* app, const wxChar* prompt) const
{
TXmlItem& td = tr.AddChild("td").SetAttr("width", "15%");
TXmlItem& form = td.AddChild("center").AddChild("form");
form.SetAttr("action", action);
TXmlItem& name = form.AddChild("input");
name.SetAttr("type", "hidden"); name.SetAttr("name", "App");
name.SetAttr("value", app);
TXmlItem& submit = form.AddChild("input");
submit.SetAttr("type", "submit");
submit.SetAttr("value", prompt);
}
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, wxGetFullHostName());
int nPort;
ini.Read("Port", &nPort, 3883);
wxString strIcon;
ini.Read("Icon", &strIcon, "euro.gif");
const wxSingleInstanceChecker sic(arr[i]);
const bool bRunning = sic.IsAnotherRunning();
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]);
AddMiniForm(tr, bRunning ? "kill.cgi" : "start.cgi", arr[i], bRunning ? "Stop" : "Start");
AddMiniForm(tr, "config.cgi", arr[i], "Configure");
TXmlItem& a3 = tr.AddChild("td").AddChild("a");
a3.SetAttr("href", wxString::Format("http://%s:%d/index.htm", strHost, nPort));
a3 << 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)
{
bool ok = false;
const wxString strApp = args.Get("App");
if (!strApp.IsEmpty()) // Dummy test
{
const wxSingleInstanceChecker sic(strApp);
ok = !sic.IsAnotherRunning();
}
if (ok)
{
const wxString strRun = GetConfigString("Run", "", strApp);
if (wxFileExists(strRun))
{
const long nProc = wxExecute(strRun);
if (nProc == 0 || nProc == -1)
MessageBox("ERROR", wxString::Format("Can't run %s executable (%s)", strApp, strRun), sock);
else
MessageBox("Server Started", strApp, sock);
}
else
MessageBox("ERROR", wxString::Format("Can't find %s executable (%s)", strApp, strRun), sock);
}
else
MessageBox("ERROR", wxString::Format("%s il already running", strApp), sock);
}
void TLerchServer::KillProcess(const wxString& strApp)
{
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";
sock.Write(str, str.Length());
if (strHost == "localhost")
{
const wxSingleInstanceChecker sic(strApp);
for (int i = 0; i < 5 && sic.IsAnotherRunning(); i++)
wxSleep(1);
}
}
}
}
void TLerchServer::ProcessFormKill(const THashTable& args, wxSocketBase& sock)
{
const wxString strApp = args.Get("App");
if (strApp == GetAppName()) // Stop myself!
{
wxArrayString app; CreateServersList(app);
for (size_t i = 0; i < app.GetCount(); i++)
{
if (app[i] != GetAppName()) // Stop Children only!
{
const wxSingleInstanceChecker sic(app[i]);
if (sic.IsAnotherRunning())
KillProcess(app[i]);
}
}
}
KillProcess(strApp);
MessageBox("Server stopped", strApp, sock);
}
void TLerchServer::EnumerateVariables(const wxString& strApp, wxArrayString& arr) const
{
wxFileInputStream inf(GetConfigName());
wxString strParagraph = wxString::Format("[%s]", strApp);
wxString str;
bool bFound = false;
while (inf.Ok())
{
inf >> str;
if (str == strParagraph)
{
bFound = true;
break;
}
}
if (bFound)
{
while (inf.Ok())
{
inf >> str;
if (str.IsEmpty() || str[0] == '[')
break;
const int nEqual = str.Find('=');
if (nEqual > 0)
{
str.Truncate(nEqual);
str.Trim(false);
str.Trim(true);
arr.Add(str);
}
}
arr.Sort();
}
}
void TLerchServer::ProcessFormConfig(const THashTable& args, wxSocketBase& sock)
{
const wxString strApp = args.Get("App");
wxArrayString arr;
EnumerateVariables(strApp, arr);
TXmlItem html;
TXmlItem& body = CreatePageBody(html);
TXmlItem& form = body.AddChild("form");
form.SetAttr("action", "update.cgi").SetAttr("method", "post");
TXmlItem& table = form.AddChild("table").SetAttr("width", "100%").SetAttr("border", "1");
table.AddChild("caption").AddChild("h2") << strApp;
TXmlItem& thead = table.AddChild("thead");
thead.AddChild("th").SetAttr("width", "15%") << "Property";
thead.AddChild("th").SetAttr("width", "85%") << "Value";
for (size_t v = 0; v < arr.GetCount(); v++)
{
TXmlItem& tr = table.AddChild("tr");
tr.AddChild("td") << arr[v];
TXmlItem& input = tr.AddChild("td").AddChild("input");
input.SetAttr("type", "text"); input.SetAttr("name", arr[v]);
input.SetAttr("size", "80"); input.SetAttr("maxlength", "256");
input.SetAttr("value", GetConfigString(arr[v], "", strApp));
}
TXmlItem& app = form.AddChild("input").SetAttr("type", "hidden");
app.SetAttr("name", "App"); app.SetAttr("value", strApp);
TXmlItem& submit = form.AddChild("br").AddChild("center").AddChild("input");
submit.SetAttr("type", "submit"); submit.SetAttr("value", "Update Parameters");
body.AddChild("br");
AddLinkButton(body.AddChild("center"), "Return to main page", "/");
const wxString strFilename = GetTempFilename();
html.Save(strFilename);
SendFile(strFilename, sock);
}
void TLerchServer::ProcessFormUpdate(THashTable& args, wxSocketBase& sock)
{
const wxString strApp = args.Get("App");
args.BeginFind();
for (wxNode* pNode = args.Next(); pNode; pNode = args.Next())
{
const wxString strKey = pNode->GetKeyString();
if (strKey != "App")
{
const wxString strVal = args.Get(strKey);
SetConfigString(strKey, strVal, strApp);
}
}
const wxString msg = wxString::Format("%s parameters updated", strApp);
MessageBox("Success!", msg, 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); else
if (strName == "config")
ProcessFormConfig(hashArgs, sock); else
if (strName == "update")
ProcessFormUpdate(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::ProcessHttpPost(wxString cmd, wxSocketBase& outs)
{
const int stop = cmd.Find(" HTTP");
wxString strFileName = cmd.Mid(5, stop-5).Trim();
wxString strName, args;
wxSplitPath(strFileName, NULL, &strName, NULL);
const int pos = cmd.Find("\r\n\r\n");
if (pos > 0)
args = cmd.Mid(pos+4);
THashTable hashArgs(17);
ParseArguments(args, hashArgs);
if (strName == "update")
ProcessFormUpdate(hashArgs, outs);
}
void TLerchServer::ProcessCommand(wxString cmd, wxSocketBase& outs)
{
if (cmd.StartsWith("GET "))
ProcessHttpGet(cmd, outs); else
if (cmd.StartsWith("POST "))
ProcessHttpPost(cmd, outs);
}
bool TLerchServer::Initialization()
{
wxArrayString arr; CreateServersList(arr);
for (size_t i = 0; i < arr.GetCount(); i++)
{
const wxString& strApp = arr[i];
const bool bAutorun = GetConfigBool("Autorun", false, strApp);
if (bAutorun)
{
const wxSingleInstanceChecker sic(strApp);
if (!sic.IsAnotherRunning())
{
wxString strRun = GetConfigString("Run", "", strApp);
if (wxFileExists(strRun))
wxExecute(strRun);
}
}
}
return true;
}
// Istanziare l'applicazione principale
IMPLEMENT_APP(TLerchServer)