Patch level : 10.0
Files correlati : lurch.exe Ricompilazione Demo : [ ] Commento : Questo maggiordomo non solo e' in grado di ammazzare la servitu' oziosa... ma anche di risuscitarla quanto questa si suicida! git-svn-id: svn://10.65.10.50/trunk@19979 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
28fb3889c5
commit
46d30d0ca2
@ -15,7 +15,7 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// headers
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <wx/wxprec.h>
|
||||
#include "baseserv.h"
|
||||
|
||||
#include <wx/config.h>
|
||||
@ -25,12 +25,10 @@
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/sckstrm.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef __WXMSW__
|
||||
#include <wx/fileconf.h>
|
||||
#endif
|
||||
|
||||
#include <wx/app.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Utilities
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -589,6 +587,11 @@ const wxString& TBaseServerApp::GetConfigName() const
|
||||
|
||||
void TBaseServerApp::SetConfigString(const wxChar* key, const wxChar* val, const wxChar* app) const
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
if (app == NULL || *app == '\0')
|
||||
app = GetAppName();
|
||||
::WritePrivateProfileString(app, key, val, GetConfigName());
|
||||
#else
|
||||
wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
|
||||
wxString str;
|
||||
if (app == NULL || *app == '\0')
|
||||
@ -596,6 +599,7 @@ void TBaseServerApp::SetConfigString(const wxChar* key, const wxChar* val, const
|
||||
str << '/' << app;
|
||||
ini.SetPath(str);
|
||||
ini.Write(key, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TBaseServerApp::SetConfigInt(const wxChar* key, int val, const wxChar* app) const
|
||||
@ -606,13 +610,19 @@ void TBaseServerApp::SetConfigInt(const wxChar* key, int val, const wxChar* app)
|
||||
|
||||
wxString TBaseServerApp::GetConfigString(const wxChar* key, const wxChar* def, const wxChar* app) const
|
||||
{
|
||||
wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
|
||||
wxString str;
|
||||
if (app == NULL || *app == '\0')
|
||||
if (app == NULL || *app == '\0')
|
||||
app = GetAppName();
|
||||
#ifdef __WXMSW__
|
||||
wxChar value[512]; memset(value, 0, sizeof(value));
|
||||
const int len = ::GetPrivateProfileString(app, key, def, value, sizeof(value)-1, GetConfigName());
|
||||
str = len <= 0 ? def : value;
|
||||
#else
|
||||
wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
|
||||
str << '/' << app;
|
||||
ini.SetPath(str);
|
||||
ini.Read(key, &str, def);
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include <wx/wxprec.h>
|
||||
#ifndef __BASESERV_H__
|
||||
#define __BASESERV_H__
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/hash.h>
|
||||
#include <wx/snglinst.h>
|
||||
#include <wx/socket.h>
|
||||
#include <wx/wfstream.h>
|
||||
#ifdef LINUX
|
||||
#include <wx/app.h>
|
||||
#endif
|
||||
|
||||
#include "xml.h"
|
||||
|
||||
@ -150,3 +151,5 @@ public:
|
||||
};
|
||||
|
||||
TBaseServerApp& GetServerApp();
|
||||
|
||||
#endif
|
||||
|
416
server/lurch.cpp
416
server/lurch.cpp
@ -3,56 +3,36 @@
|
||||
#include <wx/config.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/process.h>
|
||||
#ifdef WIN32
|
||||
#include <wx/fileconf.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TProcess declaration
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TLurchServer; //segnaposto della TLurchServer che serve alla TProcess
|
||||
|
||||
class TProcess : public wxProcess
|
||||
{
|
||||
TLurchServer* m_pLurch;
|
||||
wxString m_strApp;
|
||||
|
||||
protected:
|
||||
virtual void OnTerminate(int pid, int status);
|
||||
|
||||
public:
|
||||
void ForcePid(int pid) { SetPid(pid); }
|
||||
TProcess(TLurchServer* pLurch, const wxString& strApp) : m_pLurch(pLurch), m_strApp(strApp) {}
|
||||
};
|
||||
#include <wx/timer.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TLurchServer declaration
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//classe TProcessHashMap derivata da wxHashMap (è una specie di assocarray!)
|
||||
//classe TProcessHashMap derivata da wxHashMap (è l'equivalente di TAssoc_array)
|
||||
WX_DECLARE_HASH_MAP( wxString, wxProcess*, wxStringHash, wxStringEqual, TProcessHashMap );
|
||||
|
||||
|
||||
class TLurchServer : public TBaseServerApp
|
||||
{
|
||||
TProcessHashMap m_ProcMap;
|
||||
wxTimer m_Timer;
|
||||
int m_nFreq;
|
||||
TProcessHashMap m_hmProcMap;
|
||||
wxSemaphore m_Semaphore;
|
||||
wxTimer m_PingTimer;
|
||||
wxArrayString m_aServers;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
protected:
|
||||
virtual const wxChar* GetAppName() const;
|
||||
virtual bool Initialization();
|
||||
void OnTimer(wxTimerEvent& evt);
|
||||
bool RestartTimer();
|
||||
void OnEndProcess(wxProcessEvent& evt);
|
||||
|
||||
void AddMiniForm(TXmlItem& tr, const wxChar* action, const wxChar* app, const wxChar* prompt) const;
|
||||
TXmlItem& 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;
|
||||
const wxArrayString& GetServersList();
|
||||
const TProcessHashMap& GetRunningServers() { return m_hmProcMap; }
|
||||
|
||||
bool PingProcess(const wxString& strApp);
|
||||
void StopProcess(const wxString& strApp);
|
||||
wxString StartProcess(const wxString& strApp);
|
||||
@ -70,116 +50,150 @@ public:
|
||||
//metodi riguardanti l'interfaccia html
|
||||
void ProcessFormStart(const THashTable& args, wxSocketBase& sock);
|
||||
void ProcessFormStop(const THashTable& args, wxSocketBase& sock);
|
||||
void ProcessFormRestart(const THashTable& args, wxSocketBase& sock);
|
||||
void ProcessFormConfig(const THashTable& args, wxSocketBase& sock);
|
||||
void ProcessFormUpdate(THashTable& args, wxSocketBase& sock);
|
||||
void CallCgi(wxString& strFileName, wxSocketBase& sock);
|
||||
|
||||
TLurchServer();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TProcess implementation
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void TProcess::OnTerminate(int pid, int WXUNUSED(status))
|
||||
{
|
||||
SetPid(pid);
|
||||
m_pLurch->ForgetProcess(m_strApp);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////
|
||||
// TLurchServer implementation
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
BEGIN_EVENT_TABLE(TLurchServer, TBaseServerApp)
|
||||
EVT_TIMER(wxID_ANY, TLurchServer::OnTimer)
|
||||
EVT_TIMER(wxID_ANY, TLurchServer::OnTimer)
|
||||
EVT_END_PROCESS(wxID_ANY, TLurchServer::OnEndProcess)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a)>(b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
bool TLurchServer::PingProcess(const wxString& strApp)
|
||||
{
|
||||
bool bPinged = false;
|
||||
TProcess* pProcess = (TProcess*)m_ProcMap[strApp];
|
||||
if (pProcess != NULL)
|
||||
|
||||
const wxString strPort = GetConfigString("Port", "", strApp);
|
||||
if (!strPort.IsEmpty())
|
||||
{
|
||||
const wxString strPort = GetConfigString("Port", "", strApp);
|
||||
if (!strPort.IsEmpty())
|
||||
const int nInterval = m_PingTimer.GetInterval(); // msec
|
||||
const int nTimeOut = max(nInterval/4, 250); // msec
|
||||
wxIPV4address ipAddress;
|
||||
ipAddress.LocalHost();
|
||||
ipAddress.Service(strPort);
|
||||
wxSocketClient sSock(wxSOCKET_NOWAIT);
|
||||
sSock.Connect(ipAddress, false);
|
||||
if (sSock.WaitOnConnect(0, nTimeOut))
|
||||
{
|
||||
const int nTimeOut = m_nFreq > 3000 ? m_nFreq / 3000 : 1;
|
||||
wxIPV4address ipAddress;
|
||||
ipAddress.LocalHost();
|
||||
ipAddress.Service(strPort);
|
||||
wxSocketClient sSock(wxSOCKET_NOWAIT);
|
||||
sSock.Connect(ipAddress, false);
|
||||
if (sSock.WaitOnConnect(nTimeOut))
|
||||
sSock.Discard(); // Tralascia eventuali dati in arrivo non richiesti
|
||||
const wxString strPing = wxT("PING\n");
|
||||
sSock.Write(strPing, strPing.Len());
|
||||
if (sSock.WaitForWrite(0, nTimeOut))
|
||||
{
|
||||
sSock.Write("PING\n", 5);
|
||||
if (sSock.WaitForWrite(nTimeOut))
|
||||
{
|
||||
char buffer[8]; memset(buffer, 0, sizeof(buffer));
|
||||
sSock.Read(buffer, 4);
|
||||
if (sSock.WaitForRead(nTimeOut))
|
||||
bPinged = wxStrcmp(buffer, "PONG") == 0;
|
||||
}
|
||||
::wxMilliSleep(nTimeOut); // Triste necessita' :-( Aspetto qui ...
|
||||
char buffer[8]; memset(buffer, 0, sizeof(buffer));
|
||||
sSock.Read(buffer, 4);
|
||||
if (sSock.WaitForRead(0, 1)) // ... ma poi non aspetto qua :-)
|
||||
bPinged = wxStrncmp(buffer, "PONG", 4) == 0;
|
||||
sSock.Discard(); // Tralascia ulteriori dati in arrivo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bPinged;
|
||||
}
|
||||
|
||||
void TLurchServer::OnTimer(wxTimerEvent& WXUNUSED(evt))
|
||||
void TLurchServer::OnTimer(wxTimerEvent& evt)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
const wxString strApp = "Authorization";
|
||||
if (!PingProcess(strApp))
|
||||
if (m_Semaphore.TryWait() != wxSEMA_NO_ERROR)
|
||||
{
|
||||
TProcess* pProcess = (TProcess*)m_ProcMap[strApp];
|
||||
wxKillError ke = pProcess->Kill(pProcess->GetPid());
|
||||
if (ke == wxKILL_OK)
|
||||
WriteLog(strApp + " killed!");
|
||||
else
|
||||
{
|
||||
wxString strMsg;
|
||||
strMsg << "Error " << ke << " killing " << strApp;
|
||||
WriteLog(strMsg);
|
||||
}
|
||||
wxSleep(2);
|
||||
StartProcess(strApp);
|
||||
evt.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
const TProcessHashMap& hmServers = GetRunningServers();
|
||||
const int nServers = hmServers.size();
|
||||
if (nServers > 0) // Is anybody out there?
|
||||
{
|
||||
const int nRandomIndex = rand() % nServers;
|
||||
wxString strApp; // Usually "Authorization"
|
||||
TProcessHashMap::const_iterator it;
|
||||
for (it = hmServers.begin(); it != hmServers.end(); ++it)
|
||||
strApp = it->first;
|
||||
|
||||
if (!PingProcess(strApp))
|
||||
{
|
||||
wxProcess* pProcess = m_hmProcMap[strApp];
|
||||
wxKillError ke = pProcess->Kill(pProcess->GetPid());
|
||||
if (ke == wxKILL_OK)
|
||||
WriteLog(strApp + _(" killed!"));
|
||||
else
|
||||
{
|
||||
wxString strMsg;
|
||||
strMsg << _("Error ") << ke << _(" killing ") << strApp;
|
||||
WriteLog(strMsg);
|
||||
}
|
||||
wxSleep(2);
|
||||
StartProcess(strApp);
|
||||
}
|
||||
}
|
||||
|
||||
m_Semaphore.Post();
|
||||
}
|
||||
|
||||
void TLurchServer::OnEndProcess(wxProcessEvent& evt)
|
||||
{
|
||||
TProcessHashMap::const_iterator it;
|
||||
for (it = m_hmProcMap.begin(); it != m_hmProcMap.end(); ++it)
|
||||
{
|
||||
const wxProcess* p = it->second;
|
||||
if (p->GetPid() == evt.GetPid())
|
||||
{
|
||||
ForgetProcess(it->first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
RestartTimer();
|
||||
}
|
||||
|
||||
const wxChar* TLurchServer::GetAppName() const
|
||||
{ return wxT("Lurch"); }
|
||||
|
||||
const wxArrayString& TLurchServer::GetServersList()
|
||||
{
|
||||
return "Lurch";
|
||||
if (m_aServers.IsEmpty())
|
||||
{
|
||||
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 = (char*)strchr(aperta+1, ']');
|
||||
if (chiusa != NULL)
|
||||
{
|
||||
*chiusa = '\0';
|
||||
wxString str = aperta+1;
|
||||
m_aServers.Add(str);
|
||||
aperta = strchr(chiusa+1, '[');
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m_aServers;
|
||||
}
|
||||
|
||||
void TLurchServer::CreateServersList(wxArrayString& arr) const
|
||||
TXmlItem& TLurchServer::AddMiniForm(TXmlItem& tr, const wxChar* action, const wxChar* app, const wxChar* prompt) 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 = (char*)strchr(aperta+1, ']');
|
||||
if (chiusa != NULL)
|
||||
{
|
||||
*chiusa = '\0';
|
||||
wxString str = aperta+1;
|
||||
arr.Add(str);
|
||||
aperta = strchr(chiusa+1, '[');
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
delete buff;
|
||||
}
|
||||
|
||||
void TLurchServer::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");
|
||||
TXmlItem& td = tr.AddChild("td").SetAttr("width", "10%");
|
||||
td.SetAttr("align", "center");
|
||||
td.SetAttr("valign", "center"); // Lo ignora ma insisto
|
||||
|
||||
TXmlItem& form = td.AddChild("form");
|
||||
form.SetAttr("action", action);
|
||||
|
||||
TXmlItem& name = form.AddChild("input");
|
||||
@ -189,6 +203,7 @@ void TLurchServer::AddMiniForm(TXmlItem& tr, const wxChar* action, const wxChar*
|
||||
TXmlItem& submit = form.AddChild("input");
|
||||
submit.SetAttr("type", "submit");
|
||||
submit.SetAttr("value", prompt);
|
||||
return submit;
|
||||
}
|
||||
|
||||
void TLurchServer::GenerateFile(wxString& strFilename)
|
||||
@ -203,30 +218,21 @@ void TLurchServer::GenerateFile(wxString& strFilename)
|
||||
strFilename = GetTempFilename();
|
||||
const wxString strLurchName = GetAppName();
|
||||
|
||||
wxArrayString arr; CreateServersList(arr);
|
||||
const wxArrayString& arr = GetServersList();
|
||||
for (size_t i = 0; i < arr.GetCount(); i++)
|
||||
{
|
||||
const bool bLurch = arr[i] == strLurchName;
|
||||
wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
|
||||
wxString str;
|
||||
str << '/' << arr[i];
|
||||
ini.SetPath(str);
|
||||
const wxString& strApp = arr[i];
|
||||
const bool bLurch = strApp == strLurchName;
|
||||
const wxString strHost = GetConfigString("Host", "127.0.0.1", strApp);
|
||||
const int nPort = GetConfigInt("Port", 3883, strApp);
|
||||
const wxString strIcon = GetConfigString("Icon", "euro.gif", strApp);
|
||||
|
||||
wxString strHost;
|
||||
ini.Read("Host", &strHost, "127.0.0.1");
|
||||
|
||||
int nPort;
|
||||
ini.Read("Port", &nPort, 3883);
|
||||
|
||||
wxString strIcon;
|
||||
ini.Read("Icon", &strIcon, "euro.gif");
|
||||
|
||||
const wxSingleInstanceChecker sic(arr[i]);
|
||||
const wxSingleInstanceChecker sic(strApp);
|
||||
const bool bRunning = sic.IsAnotherRunning();
|
||||
|
||||
TXmlItem& tr = table.AddChild("tr");
|
||||
TXmlItem& td0 = tr.AddChild("td");
|
||||
td0.SetAttr("width", "15%"); td0.SetAttr("align", "center");
|
||||
td0.SetAttr("width", "10%"); td0.SetAttr("align", "center");
|
||||
TXmlItem& a = td0.AddChild("a");
|
||||
if (!bLurch && bRunning)
|
||||
{
|
||||
@ -236,8 +242,17 @@ void TLurchServer::GenerateFile(wxString& strFilename)
|
||||
TXmlItem& img = a.AddChild("img");
|
||||
img.SetAttr("src", strIcon); img.SetAttr("border", 0L); img.SetAttr("alt", arr[i]);
|
||||
|
||||
AddMiniForm(tr, (bRunning || bLurch) ? "kill.cgi" : "start.cgi", arr[i], (bRunning || bLurch) ? "Stop" : "Start");
|
||||
AddMiniForm(tr, "config.cgi", arr[i], "Configure");
|
||||
TXmlItem& buttStart = AddMiniForm(tr, "start.cgi", arr[i], _("Start"));
|
||||
if (bRunning || bLurch)
|
||||
buttStart.SetAttr(wxT("type"), wxT("hidden"));
|
||||
|
||||
TXmlItem& buttStop = AddMiniForm(tr, "kill.cgi", arr[i], _("Stop"));
|
||||
if (!(bRunning || bLurch))
|
||||
buttStop.SetAttr(wxT("type"), wxT("hidden"));
|
||||
|
||||
TXmlItem& buttRestart = AddMiniForm(tr, "restart.cgi", arr[i], _("Restart"));
|
||||
if (!(bRunning && !bLurch))
|
||||
buttRestart.SetAttr(wxT("type"), wxT("hidden"));
|
||||
|
||||
TXmlItem& a3 = tr.AddChild("td").AddChild("a");
|
||||
if (!bLurch && bRunning)
|
||||
@ -264,7 +279,7 @@ void TLurchServer::GenerateFile(wxString& strFilename)
|
||||
|
||||
TXmlItem& tr2 = panel.AddChild("tr");
|
||||
tr2.AddChild("td").AddEnclosedText("Ping Frequency");
|
||||
wxString strFreq; strFreq << m_nFreq/1000;
|
||||
wxString strFreq; strFreq << m_PingTimer.GetInterval()/1000;
|
||||
tr2.AddChild("td").AddEnclosedText(strFreq);
|
||||
|
||||
html.Save(strFilename);
|
||||
@ -301,22 +316,6 @@ bool TLurchServer::IsCgiName(wxString strFilename) const
|
||||
return strExt == "cgi" || strExt == "exe";
|
||||
}
|
||||
|
||||
bool TLurchServer::RestartTimer()
|
||||
{
|
||||
bool ok = true;
|
||||
if (m_nFreq > 0)
|
||||
{
|
||||
ok = m_Timer.Start(m_nFreq) && m_Timer.IsRunning();
|
||||
if (!ok)
|
||||
{
|
||||
wxString strMsg;
|
||||
strMsg << "Error starting timer with " << m_nFreq << " ms frequency";
|
||||
WriteLog(strMsg);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
wxString TLurchServer::StartProcess(const wxString& strApp)
|
||||
{
|
||||
bool ok = false;
|
||||
@ -337,28 +336,26 @@ wxString TLurchServer::StartProcess(const wxString& strApp)
|
||||
fnPath.SetPath(GetServerPath());
|
||||
fnPath.SetFullName(strRun);
|
||||
|
||||
TProcess* pProcess = new TProcess(this, strApp);
|
||||
const long nProc = wxExecute(fnPath.GetFullPath(), wxEXEC_ASYNC, pProcess);
|
||||
if (nProc == 0 || nProc == -1)
|
||||
wxProcess* pProcess = wxProcess::Open(fnPath.GetFullPath());
|
||||
if (pProcess == NULL)
|
||||
{
|
||||
strMessage.Printf("Can't run %s executable (%s)", strApp.c_str(), strRun.c_str());
|
||||
delete pProcess;
|
||||
strMessage.Printf(_("Can't run %s executable (%s)"), strApp.c_str(), strRun.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
pProcess->ForcePid(nProc);
|
||||
m_ProcMap[strApp] = pProcess; //memorizza il numero del processo che ha lanciato per poterlo usare in fase di controllo
|
||||
m_hmProcMap[strApp] = pProcess; // memorizza il numero del processo che ha lanciato per poterlo usare in fase di controllo
|
||||
strMessage = wxEmptyString;
|
||||
::wxSleep(1); // Lascia il tempo di inizializzarsi prima di compinciare a pingarlo!
|
||||
}
|
||||
}
|
||||
else
|
||||
strMessage.Printf("Can't find %s executable (%s)", strApp.c_str(), strRun.c_str());
|
||||
strMessage.Printf(_("Can't find %s executable (%s)"), strApp.c_str(), strRun.c_str());
|
||||
}
|
||||
else
|
||||
strMessage.Printf("%s il already running", strApp.c_str());
|
||||
strMessage.Printf(_("%s il already running"), strApp.c_str());
|
||||
|
||||
if (strMessage.IsEmpty())
|
||||
WriteLog(strApp + " started.");
|
||||
WriteLog(strApp + _(" started."));
|
||||
else
|
||||
WriteLog(strMessage);
|
||||
|
||||
@ -372,16 +369,16 @@ void TLurchServer::ProcessFormStart(const THashTable& args, wxSocketBase& sock)
|
||||
{
|
||||
const wxString strMessage = StartProcess(strApp);
|
||||
if (strMessage.IsEmpty())
|
||||
MessageBox("Server Started", strApp, sock);
|
||||
MessageBox(_("Server Started"), strApp, sock);
|
||||
else
|
||||
MessageBox("ERROR", strMessage, sock);
|
||||
MessageBox(_("ERROR"), strMessage, sock);
|
||||
}
|
||||
}
|
||||
|
||||
bool TLurchServer::ForgetProcess(const wxString& strApp)
|
||||
{
|
||||
WriteLog(strApp + " terminated.");
|
||||
return m_ProcMap.erase(strApp) != 0;
|
||||
WriteLog(strApp + _(" terminated."));
|
||||
return m_hmProcMap.erase(strApp) != 0;
|
||||
}
|
||||
|
||||
void TLurchServer::StopProcess(const wxString& strApp)
|
||||
@ -397,14 +394,25 @@ void TLurchServer::StopProcess(const wxString& strApp)
|
||||
wxSocketClient sock;
|
||||
if (sock.Connect(addr))
|
||||
{
|
||||
// Prima provo con le buone inviando una richiesta di stop
|
||||
const wxString str = "GET /stop.cgi HTTP/1.1\r\n\r\n";
|
||||
sock.Write(str, str.Length());
|
||||
if (strHost == "localhost")
|
||||
if (addr.IsLocalHost())
|
||||
{
|
||||
const wxSingleInstanceChecker sic(strApp);
|
||||
for (int i = 0; i < 5 && sic.IsAnotherRunning(); i++)
|
||||
int i;
|
||||
for (i = 5; i >= 0 && sic.IsAnotherRunning(); i--)
|
||||
wxSleep(1);
|
||||
ForgetProcess(strApp);
|
||||
// Se le buone non hanno funzionato ... passo alle cattive
|
||||
if (i < 0)
|
||||
{
|
||||
wxProcess* p = m_hmProcMap[strApp];
|
||||
if (p != NULL)
|
||||
{
|
||||
p->Kill(p->GetPid());
|
||||
ForgetProcess(strApp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -412,24 +420,46 @@ void TLurchServer::StopProcess(const wxString& strApp)
|
||||
|
||||
void TLurchServer::ProcessFormStop(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())
|
||||
StopProcess(app[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
StopProcess(strApp);
|
||||
MessageBox("Server stopped", strApp, sock);
|
||||
if (m_Semaphore.Wait() == wxSEMA_NO_ERROR)
|
||||
{
|
||||
const wxString strApp = args.Get("App");
|
||||
if (strApp == GetAppName() || strApp.IsEmpty()) // Stop myself!
|
||||
{
|
||||
m_PingTimer.Stop(); // Stop ping process!
|
||||
// Fill a safe array of names before killing the processes stored in the hash map
|
||||
const TProcessHashMap& hmServers = GetRunningServers(); // Hash map of the running processes
|
||||
wxArrayString aRunner; // Array of the names of the runners
|
||||
TProcessHashMap::const_iterator it;
|
||||
for (it = hmServers.begin(); it != hmServers.end(); ++it)
|
||||
aRunner.Add(it->first);
|
||||
for (size_t i = 0; i < aRunner.GetCount(); i++)
|
||||
StopProcess(aRunner[i]);
|
||||
ExitMainLoop();
|
||||
}
|
||||
else
|
||||
StopProcess(strApp);
|
||||
MessageBox("Server stopped", strApp, sock);
|
||||
|
||||
m_Semaphore.Post();
|
||||
}
|
||||
}
|
||||
|
||||
void TLurchServer::ProcessFormRestart(const THashTable& args, wxSocketBase& sock)
|
||||
{
|
||||
const wxString strApp = args.Get("App");
|
||||
if (!strApp.IsEmpty() && strApp != GetAppName())
|
||||
{
|
||||
if (m_Semaphore.Wait() == wxSEMA_NO_ERROR)
|
||||
{
|
||||
StopProcess(strApp);
|
||||
::wxSleep(2);
|
||||
ProcessFormStart(args, sock);
|
||||
m_Semaphore.Post();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TLurchServer::EnumerateVariables(const wxString& strApp, wxArrayString& arr) const
|
||||
{
|
||||
wxFileInputStream inf(GetConfigName());
|
||||
@ -542,10 +572,13 @@ void TLurchServer::CallCgi(wxString& strFileName, wxSocketBase& sock)
|
||||
|
||||
if (strExt == "cgi")
|
||||
{
|
||||
strName.MakeLower();
|
||||
if (strName == "start")
|
||||
ProcessFormStart(hashArgs, sock); else
|
||||
if (strName == "kill")
|
||||
ProcessFormStop(hashArgs, sock); else
|
||||
if (strName == "restart")
|
||||
ProcessFormRestart(hashArgs, sock); else
|
||||
if (strName == "config")
|
||||
ProcessFormConfig(hashArgs, sock); else
|
||||
if (strName == "update")
|
||||
@ -593,23 +626,32 @@ void TLurchServer::ProcessHttpPost(wxString cmd, wxSocketBase& outs)
|
||||
|
||||
bool TLurchServer::Initialization()
|
||||
{
|
||||
m_nFreq = GetConfigInt("PingFreq") * 1000; // sec to msec
|
||||
|
||||
wxArrayString arr; CreateServersList(arr);
|
||||
const wxArrayString& arr = GetServersList();
|
||||
for (size_t i = 0; i < arr.GetCount(); i++)
|
||||
{
|
||||
const wxString& strApp = arr[i];
|
||||
const bool bAutorun = GetConfigBool("Autorun", false, strApp);
|
||||
if (bAutorun)
|
||||
StartProcess(strApp);
|
||||
if (strApp != GetAppName())
|
||||
{
|
||||
const bool bAutorun = GetConfigBool("Autorun", false, strApp);
|
||||
if (bAutorun)
|
||||
StartProcess(strApp);
|
||||
}
|
||||
}
|
||||
|
||||
RestartTimer();
|
||||
|
||||
|
||||
const int nFreq = GetConfigInt("PingFreq");
|
||||
if (nFreq > 0)
|
||||
{
|
||||
m_PingTimer.Start(nFreq * 1000); // sec to msec
|
||||
m_Semaphore.Post(); // GREEN!
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Istanziare l'applicazione principale
|
||||
|
||||
IMPLEMENT_APP(TLurchServer)
|
||||
|
||||
TLurchServer::TLurchServer()
|
||||
: m_Semaphore(0 /* RED! */, 1 /* mutex like behaviour */)
|
||||
{ }
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include "wx/mstream.h"
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user