Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 2.1 598 git-svn-id: svn://10.65.10.50/trunk@13909 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			692 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			692 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        BaseServ.cpp
 | 
						|
// Purpose:     Simple base Server
 | 
						|
// Author:      Guy
 | 
						|
// Modified by:
 | 
						|
// Created:     21/08/2002
 | 
						|
// Copyright:   (c) 2002 Guy
 | 
						|
// Licence:     wxWindows licence
 | 
						|
/////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// ==========================================================================
 | 
						|
// declarations
 | 
						|
// ==========================================================================
 | 
						|
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
// headers
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
 | 
						|
#include "baseserv.h"
 | 
						|
 | 
						|
#include <wx/config.h>
 | 
						|
#include <wx/filename.h>
 | 
						|
#include <wx/image.h>
 | 
						|
#include <wx/mimetype.h>
 | 
						|
#include <wx/sckstrm.h>
 | 
						|
#ifdef WIN32
 | 
						|
#include <wx/fileconf.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <wx/app.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TBaseServerApp& GetServerApp()
 | 
						|
{
 | 
						|
	return (TBaseServerApp&)*wxTheApp;
 | 
						|
}
 | 
						|
 | 
						|
wxString Date2String(const wxDateTime& date)
 | 
						|
{
 | 
						|
	return date.Format("%d-%m-%Y");
 | 
						|
}
 | 
						|
 | 
						|
wxDateTime String2Date(const wxString& str)
 | 
						|
{
 | 
						|
	int d, m, y;
 | 
						|
	sscanf(str, "%d-%d-%d", &d, &m, &y);
 | 
						|
	wxDateTime date(d, wxDateTime::Month(m-1), y);
 | 
						|
	return date;
 | 
						|
}
 | 
						|
 | 
						|
wxSocketBase& operator<<(wxSocketBase& outf, const wxChar* str)
 | 
						|
{
 | 
						|
	if (str && *str)
 | 
						|
    outf.Write(str, wxStrlen(str));
 | 
						|
	return outf;
 | 
						|
}
 | 
						|
 | 
						|
wxSocketBase& operator<<(wxSocketBase& outf, wxString str)
 | 
						|
{
 | 
						|
	if (!str.IsEmpty())
 | 
						|
    outf.Write(str, str.Length());
 | 
						|
	return outf;
 | 
						|
}
 | 
						|
 | 
						|
wxSocketBase& operator<<(wxSocketBase& outf, size_t num)
 | 
						|
{
 | 
						|
	return outf << wxString::Format("%u", num);
 | 
						|
}
 | 
						|
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
// classes
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// THashTable
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void THashTable::Put(const wxString& key, const wxString& value)
 | 
						|
{
 | 
						|
	THashString* entry = new THashString(value);
 | 
						|
	m_Hash.Put(key, entry);
 | 
						|
}
 | 
						|
 | 
						|
wxString THashTable::Get(const wxChar* key) const
 | 
						|
{
 | 
						|
	wxString strValue;
 | 
						|
	THashString* str = (THashString*)m_Hash.Get(key);
 | 
						|
	if (str != NULL)
 | 
						|
		strValue = str->m_str;
 | 
						|
	return strValue;
 | 
						|
}
 | 
						|
 | 
						|
THashTable::THashTable(size_t size) : m_Hash(wxKEY_STRING, size) 
 | 
						|
{ 
 | 
						|
	m_Hash.DeleteContents(true); 
 | 
						|
}
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TTaskbarIcon
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(TTaskBarIcon, wxTaskBarIcon)
 | 
						|
  EVT_TASKBAR_LEFT_DOWN(TTaskBarIcon::OnTaskBarClick)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
void TTaskBarIcon::OnTaskBarClick(wxTaskBarIconEvent& e)
 | 
						|
{
 | 
						|
  wxString url;
 | 
						|
  url << "http://127.0.0.1:" << GetServerApp().GetDefaultPort();
 | 
						|
  ::ShellExecute(0, "open", url, NULL, NULL, SW_SHOWNORMAL);
 | 
						|
}
 | 
						|
 | 
						|
void TTaskBarIcon::Init()
 | 
						|
{
 | 
						|
  const TBaseServerApp& a = GetServerApp();
 | 
						|
  wxIcon icon;
 | 
						|
 | 
						|
  const wxString strIcon = a.GetConfigString("Icon");
 | 
						|
  if (wxFileExists(strIcon))
 | 
						|
  {
 | 
						|
    wxInitAllImageHandlers();
 | 
						|
    wxImage img(strIcon);
 | 
						|
    img.Rescale(32,32);
 | 
						|
		wxBitmap bmp(img);
 | 
						|
    icon.CopyFromBitmap(bmp);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    icon.LoadFile("mondrian", wxBITMAP_TYPE_ICO_RESOURCE);
 | 
						|
 | 
						|
  SetIcon(icon, a.GetAppName());
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TBaseServerApp
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
enum 
 | 
						|
{
 | 
						|
  SERVER_ID = 1001,
 | 
						|
  SOCKET_ID = 1002
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(TBaseServerApp, wxApp)
 | 
						|
  EVT_SOCKET(SERVER_ID, TBaseServerApp::OnServerEvent)
 | 
						|
  EVT_SOCKET(SOCKET_ID, TBaseServerApp::OnSocketEvent)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
void TBaseServerApp::WriteLog(const wxChar* str) const
 | 
						|
{
 | 
						|
	if (m_log != NULL)
 | 
						|
	  *m_log << str << endl;
 | 
						|
}
 | 
						|
 | 
						|
wxString TBaseServerApp::GetTempFilename()
 | 
						|
{
 | 
						|
	wxString strTmp;
 | 
						|
	if (m_strTempDir.IsEmpty())
 | 
						|
	{
 | 
						|
    const wxString strPrefix = "Srv";
 | 
						|
    ::wxGetTempFileName(strPrefix, strTmp);
 | 
						|
		::wxRemoveFile(strTmp);
 | 
						|
		(wxString&)m_strTempDir << ::wxPathOnly(strTmp) << "/";
 | 
						|
	}
 | 
						|
	strTmp = m_strTempDir;
 | 
						|
  strTmp += wxString::Format("%s_%d.htm", GetAppName(), m_nTmpCounter);
 | 
						|
  m_nTmpCounter++;
 | 
						|
	if (m_nTmpCounter >= 4)
 | 
						|
		m_nTmpCounter = 0;
 | 
						|
 | 
						|
	return strTmp;
 | 
						|
}
 | 
						|
 | 
						|
TXmlItem& TBaseServerApp::AddLogo(TXmlItem& tr) const 
 | 
						|
{
 | 
						|
	TXmlItem& td = tr.AddChild("td");
 | 
						|
	td.SetAttr("width", "15%");
 | 
						|
	td.SetAttr("align", "center");
 | 
						|
	
 | 
						|
	TXmlItem& a = td.AddChild("a");
 | 
						|
	a.SetAttr("href", "/index.htm");
 | 
						|
  
 | 
						|
	const wxString gif = GetConfigString("Icon", "euro.gif");
 | 
						|
	TXmlItem& img = a.AddChild("img");
 | 
						|
	img.SetAttr("src", gif);
 | 
						|
	img.SetAttr("border", "0");
 | 
						|
	img.SetAttr("alt", "Return to Home Page");
 | 
						|
	
 | 
						|
	return td;
 | 
						|
}
 | 
						|
 | 
						|
TXmlItem& TBaseServerApp::CreatePageBody(TXmlItem& html, wxString header) const
 | 
						|
{
 | 
						|
  if (header.IsEmpty())
 | 
						|
		header << GetAppName() << " Server";
 | 
						|
 | 
						|
	html.SetTag("html");
 | 
						|
	
 | 
						|
	TXmlItem& head = html.AddChild("head");
 | 
						|
  TXmlItem& meta1 = head.AddChild("meta");
 | 
						|
	meta1.SetAttr("name", "GENERATOR"); 
 | 
						|
	meta1.SetAttr("content", GetAppName());
 | 
						|
  TXmlItem& meta2 = head.AddChild("meta");
 | 
						|
	meta2.SetAttr("HTTP-EQUIV", "Content-Type"); 
 | 
						|
	meta2.SetAttr("content", "text/html; charset=iso-8859-1");
 | 
						|
  head.AddChild("title") << header;
 | 
						|
 | 
						|
	TXmlItem& body = html.AddChild("body");
 | 
						|
	body.SetAttr("bgcolor", "#EFCEAD");
 | 
						|
	if (m_bRunning)
 | 
						|
  	body.SetAttr("background", "back.gif");
 | 
						|
 | 
						|
	TXmlItem& title = body.AddChild("table");
 | 
						|
	title.SetAttr("border", "5"); title.SetAttr("width", "100%");
 | 
						|
	TXmlItem& title_tr = title.AddChild("tr");
 | 
						|
 | 
						|
	if (m_bRunning)
 | 
						|
    AddLogo(title_tr);
 | 
						|
  
 | 
						|
	TXmlItem& td1 = title_tr.AddChild("td");
 | 
						|
	td1.AddChild("h1").AddChild("center") << header;
 | 
						|
	
 | 
						|
	if (m_bRunning)
 | 
						|
    AddLogo(title_tr);
 | 
						|
  
 | 
						|
	body.AddChild("br");
 | 
						|
	return body;
 | 
						|
}
 | 
						|
 | 
						|
TXmlItem& TBaseServerApp::AddLinkButton(TXmlItem& body, const wxChar* strCaption, const wxChar* strHref) const
 | 
						|
{
 | 
						|
  TXmlItem& table = body.AddChild("table");
 | 
						|
	table.SetAttr("border", "2"); table.SetAttr("bgcolor", "#C0C0C0");
 | 
						|
 | 
						|
	TXmlItem& td = table.AddChild("tr").AddChild("td");
 | 
						|
	td.SetAttr("align", "center");
 | 
						|
	td.AddChild("a").SetAttr("href", strHref) << strCaption;
 | 
						|
	
 | 
						|
	return table;
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::MessageBox(const wxChar* caption, const wxChar* msg, wxSocketBase& outs)
 | 
						|
{
 | 
						|
  TXmlItem html; 
 | 
						|
	TXmlItem& body = CreatePageBody(html); 
 | 
						|
 | 
						|
	TXmlItem& table = body.AddChild("center").AddChild("table");
 | 
						|
	table.SetAttr("width", "70%"); table.SetAttr("border", "2");
 | 
						|
	table.AddChild("caption").AddChild("h2") << caption;
 | 
						|
 | 
						|
	TXmlItem& td0 = table.AddChild("tr").AddChild("td");
 | 
						|
	td0.SetAttr("align", "justify");
 | 
						|
	td0.AddChild("h3") << msg;
 | 
						|
 | 
						|
	TXmlItem& td1 = table.AddChild("tr").AddChild("td");
 | 
						|
	td1.SetAttr("align", "center");
 | 
						|
	AddLinkButton(td1, "Return to main page", "index.htm");
 | 
						|
 | 
						|
	const wxString strTmp = GetTempFilename();
 | 
						|
	html.Save(strTmp);
 | 
						|
	SendFile(strTmp, outs);
 | 
						|
}
 | 
						|
 | 
						|
bool TBaseServerApp::CanProcessCommand(wxString& cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
	if (cmd.Find("stop.cgi") > 0)
 | 
						|
	{
 | 
						|
	  m_bRunning = false; // Disable gif on title
 | 
						|
    MessageBox("Warning!", "Server Stopped", outs);
 | 
						|
    ExitMainLoop();
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::SendContent(wxFileInputStream& inf, wxSocketBase& sock)
 | 
						|
{
 | 
						|
	const size_t nSize = inf.GetSize();
 | 
						|
	WriteLog(wxString::Format("Sending %u bytes", nSize));
 | 
						|
 | 
						|
	const size_t BUF_TEMP_SIZE = nSize;  // was 1024*16
 | 
						|
  char* buf = new char[BUF_TEMP_SIZE];
 | 
						|
  size_t bytes = BUF_TEMP_SIZE;
 | 
						|
	size_t nTotalWritten = 0;
 | 
						|
  while (bytes == BUF_TEMP_SIZE)
 | 
						|
  {
 | 
						|
    bytes = inf.Read(buf, bytes).LastRead();
 | 
						|
    size_t nWritten = sock.Write(buf, bytes).LastCount();
 | 
						|
		nTotalWritten += nWritten;
 | 
						|
  }
 | 
						|
	delete buf;
 | 
						|
 | 
						|
	if (nTotalWritten < nSize)
 | 
						|
		WriteLog(wxString::Format("I sent %u on %u bytes only.", nTotalWritten, nSize));
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::SendFile(wxString strFilename, wxSocketBase& sock)
 | 
						|
{
 | 
						|
  const bool bFound = wxFileExists(strFilename);
 | 
						|
	if (!bFound)
 | 
						|
	{
 | 
						|
		const wxString strTmp = GetTempFilename();
 | 
						|
		if (!strTmp.IsEmpty())
 | 
						|
		{
 | 
						|
			TXmlItem html; 
 | 
						|
			TXmlItem& body = CreatePageBody(html); 
 | 
						|
			body.AddChild("h1") << "Sorry: File not found!";
 | 
						|
			body.AddChild("br");
 | 
						|
			body.AddChild("h2") << strFilename;
 | 
						|
			html.Save(strTmp);
 | 
						|
		}
 | 
						|
 		strFilename = strTmp;
 | 
						|
	}
 | 
						|
 | 
						|
	wxString strType;
 | 
						|
	wxSplitPath(strFilename, NULL, NULL, &strType);
 | 
						|
	wxFileType* type = wxTheMimeTypesManager->GetFileTypeFromExtension(strType);
 | 
						|
	if (type != NULL)
 | 
						|
		type->GetMimeType(&strType);
 | 
						|
	else
 | 
						|
		strType = "text/plain";
 | 
						|
	const wxDateTime date = ::wxFileModificationTime(strFilename);
 | 
						|
 | 
						|
	wxFileInputStream inf(strFilename);
 | 
						|
	const size_t nSize = inf.GetSize();
 | 
						|
 | 
						|
	if (bFound)
 | 
						|
	  sock << "HTTP/1.1 200 OK\n";
 | 
						|
	else
 | 
						|
    sock << "HTTP/1.1 401 Not found\n";
 | 
						|
	sock << "Server: " << GetAppName() << "\n";
 | 
						|
	sock << "Host: " << wxGetFullHostName() << "\n";
 | 
						|
	if (bFound && m_bRunning)
 | 
						|
	  sock << "Connection: keep-alive\n";
 | 
						|
	else
 | 
						|
		sock << "Connection: close\n";
 | 
						|
	sock << "Content-Type: " << strType << "\n";
 | 
						|
 	sock << "Content-Length: " << nSize << "\n";
 | 
						|
	sock << "Date: " << date.Format("%#c") << "\n";
 | 
						|
 | 
						|
  wxDateTime dtFraUnPo = wxDateTime::Now();
 | 
						|
	const wxTimeSpan minuto(0, 1, 0);  // Zero ore, Un minuto, Zero secondi
 | 
						|
	dtFraUnPo += minuto;
 | 
						|
  sock << "Expires: " << dtFraUnPo.Format("%#c") << "\n";
 | 
						|
 | 
						|
  sock << "\n";
 | 
						|
 | 
						|
  SendContent(inf, sock);  
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::SendNotModifiedFile(wxSocketBase& sock)
 | 
						|
{
 | 
						|
	sock << "HTTP/1.1 304 Not Modified\n";
 | 
						|
	sock << "Date: " << wxDateTime::Now().Format("%#c") << "\n";
 | 
						|
  sock << "Server: " << GetAppName() << "\n";
 | 
						|
  sock << "Connection: close\n";
 | 
						|
}
 | 
						|
 | 
						|
const wxChar* TBaseServerApp::GetAppName() const
 | 
						|
{
 | 
						|
	// Pure virtual function
 | 
						|
	return "Server";
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::ProcessCommand(wxString cmd, wxSocketBase& outs)
 | 
						|
{
 | 
						|
	// Pure virtual function
 | 
						|
	WriteLog("Processing...");
 | 
						|
	SendFile("index.htm", outs);
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::OnServerEvent(wxSocketEvent& event)
 | 
						|
{
 | 
						|
  wxString s = "--- OnServerEvent: ";
 | 
						|
 | 
						|
  switch(event.GetSocketEvent())
 | 
						|
  {
 | 
						|
    case wxSOCKET_CONNECTION : s.Append("wxSOCKET_CONNECTION"); break;
 | 
						|
    default                  : s.Append("Unexpected event!"); break;
 | 
						|
  }
 | 
						|
 | 
						|
  WriteLog(s);
 | 
						|
 | 
						|
  // Accept new connection if there is one in the pending
 | 
						|
  // connections queue, else exit. We use Accept(FALSE) for
 | 
						|
  // non-blocking accept (although if we got here, there
 | 
						|
  // should ALWAYS be a pending connection).
 | 
						|
 | 
						|
  wxSocketBase* sock = m_server->Accept(FALSE);
 | 
						|
  if (sock)
 | 
						|
  {
 | 
						|
    WriteLog("--- New client connection accepted");
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    WriteLog("### Error: couldn't accept a new connection");
 | 
						|
    sock->Destroy();
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  sock->SetEventHandler(*this, SOCKET_ID);
 | 
						|
  sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
 | 
						|
  sock->Notify(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::OnSocketEvent(wxSocketEvent& event)
 | 
						|
{
 | 
						|
  wxSocketBase& sock = *event.GetSocket();
 | 
						|
  switch(event.GetSocketEvent())
 | 
						|
  {
 | 
						|
    case wxSOCKET_INPUT:
 | 
						|
    {
 | 
						|
      // We disable input events, so that the test doesn't trigger
 | 
						|
      // wxSocketEvent again.
 | 
						|
      sock.SetNotify(wxSOCKET_LOST_FLAG);
 | 
						|
 | 
						|
			// Read the data
 | 
						|
			const size_t BUFSIZE = 2048;
 | 
						|
			wxString str;
 | 
						|
			wxChar* bufStart = str.GetWriteBuf(BUFSIZE);
 | 
						|
			memset(bufStart, 0, BUFSIZE);
 | 
						|
			wxChar* buf = bufStart;
 | 
						|
 | 
						|
			const size_t len = sock.Read(buf, BUFSIZE).LastCount();
 | 
						|
			buf += len;
 | 
						|
			// Attendi la fine del comando HTTP!
 | 
						|
      if (strncmp(bufStart, "GET ", 4) == 0 || strncmp(bufStart, "POST ", 5) == 0)
 | 
						|
			{
 | 
						|
				while (strstr(bufStart, "\r\n\r\n") == NULL)
 | 
						|
				{
 | 
						|
   				const size_t len = sock.Read(buf, BUFSIZE).LastCount();
 | 
						|
					buf += len;
 | 
						|
				}
 | 
						|
			}
 | 
						|
      str.UngetWriteBuf();
 | 
						|
			
 | 
						|
      WriteLog(str);
 | 
						|
 | 
						|
			if (CanProcessCommand(str, sock))
 | 
						|
			{
 | 
						|
				const wxSocketFlags flags = sock.GetFlags();
 | 
						|
				sock.SetFlags(wxSOCKET_WAITALL);
 | 
						|
			  ProcessCommand(str, sock);
 | 
						|
				sock.SetFlags(flags);
 | 
						|
			}
 | 
						|
 | 
						|
      // Enable input events again.
 | 
						|
      sock.SetNotify(wxSOCKET_LOST_FLAG | wxSOCKET_INPUT_FLAG);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    case wxSOCKET_LOST:
 | 
						|
    {
 | 
						|
      WriteLog("--- Deleting socket.");
 | 
						|
      sock.Destroy();
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    default: ;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const wxString& TBaseServerApp::GetConfigName() const
 | 
						|
{
 | 
						|
  if (m_strIni.IsEmpty())
 | 
						|
  {
 | 
						|
    wxFileName name(argv[0]);
 | 
						|
    name.SetName("servers");
 | 
						|
    name.SetExt("ini");
 | 
						|
    (wxString&)m_strIni = name.GetFullPath();
 | 
						|
  }
 | 
						|
	return m_strIni;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::SetConfigString(const wxChar* key, const wxChar* val, const wxChar* app) const
 | 
						|
{
 | 
						|
  wxFileConfig ini("", "", GetConfigName(), "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
 | 
						|
	wxString str;
 | 
						|
	if (app == NULL || *app == '\0')
 | 
						|
		app = GetAppName();
 | 
						|
	str << '/' << app;
 | 
						|
	ini.SetPath(str);
 | 
						|
	ini.Write(key, val);
 | 
						|
}
 | 
						|
 | 
						|
void TBaseServerApp::SetConfigInt(const wxChar* key, int val, const wxChar* app) const
 | 
						|
{
 | 
						|
	wxString str = wxString::Format("%d", val);
 | 
						|
  SetConfigString(key, str, 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')
 | 
						|
		app = GetAppName();
 | 
						|
	str << '/' << app;
 | 
						|
	ini.SetPath(str);
 | 
						|
	ini.Read(key, &str, def);
 | 
						|
	return str;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseServerApp::GetConfigInt(const wxChar* key, int def, const wxChar* app) const
 | 
						|
{
 | 
						|
  const wxString str = GetConfigString(key, "*", app);
 | 
						|
  return str != "*" ? atoi(str) : def;
 | 
						|
}
 | 
						|
 | 
						|
bool TBaseServerApp::GetConfigBool(const wxChar* key, bool def, const wxChar* app) const
 | 
						|
{
 | 
						|
	bool val = def;
 | 
						|
	const wxString str = GetConfigString(key, "*", app);
 | 
						|
	if (str != "*")
 | 
						|
	 val = (str[0u] == '1') || (str[0u] == 'X') || (str[0u] == 'Y') || (str.CmpNoCase("On")==0);
 | 
						|
 | 
						|
	return val;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseServerApp::GetDefaultPort() const
 | 
						|
{
 | 
						|
	return GetConfigInt("Port", 3883);
 | 
						|
}
 | 
						|
 | 
						|
wxString TBaseServerApp::GetLogFileName() const
 | 
						|
{
 | 
						|
  return GetConfigString("LogFile");
 | 
						|
}
 | 
						|
 | 
						|
wxString TBaseServerApp::GetDocumentRoot() const
 | 
						|
{
 | 
						|
  return GetConfigString("DocumentRoot", ".");
 | 
						|
}
 | 
						|
 | 
						|
bool TBaseServerApp::OnInit()
 | 
						|
{
 | 
						|
  m_server = NULL;
 | 
						|
	m_log = NULL;
 | 
						|
 | 
						|
	m_SingleInstance = new wxSingleInstanceChecker(GetAppName());
 | 
						|
  if (m_SingleInstance->IsAnotherRunning())
 | 
						|
	{
 | 
						|
		delete m_SingleInstance;
 | 
						|
		m_SingleInstance = NULL;
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
#ifdef LINUX
 | 
						|
	wxString path;
 | 
						|
	
 | 
						|
	wxFileName::SplitPath(argv[0], &path, NULL, NULL);
 | 
						|
	
 | 
						|
	if (!path.IsEmpty())
 | 
						|
		wxSetWorkingDirectory(path);
 | 
						|
#endif
 | 
						|
 | 
						|
  // Create the address - defaults to localhost:0 initially
 | 
						|
  wxIPV4address addr;
 | 
						|
  addr.Service(GetDefaultPort());
 | 
						|
  // Create the socket
 | 
						|
  m_server = new wxSocketServer(addr);
 | 
						|
 | 
						|
  // Create the Log file
 | 
						|
	wxString str;
 | 
						|
	
 | 
						|
	str = GetLogFileName();
 | 
						|
  if (!str.IsEmpty())
 | 
						|
  	m_log = new wxFileOutputStream(str);
 | 
						|
	else
 | 
						|
		m_log = NULL;
 | 
						|
 | 
						|
	m_nTmpCounter = 0;
 | 
						|
	
 | 
						|
	// We use Ok() here to see if the server is really listening
 | 
						|
  str.Empty();
 | 
						|
  if (m_server->Ok())
 | 
						|
  {
 | 
						|
		// Setup the event handler and subscribe to connection events
 | 
						|
		m_server->SetEventHandler(*this, SERVER_ID);
 | 
						|
		m_server->SetNotify(wxSOCKET_CONNECTION_FLAG);
 | 
						|
		m_server->Notify(TRUE);
 | 
						|
 | 
						|
		str << GetAppName() << " listening on port " << addr.Service();
 | 
						|
		m_bRunning = true;
 | 
						|
	}
 | 
						|
  else
 | 
						|
  {
 | 
						|
		str << GetAppName() << " could not listen to port " << addr.Service();
 | 
						|
  }
 | 
						|
	WriteLog(str);
 | 
						|
 | 
						|
	bool ok = m_server->Ok();
 | 
						|
	if (ok)
 | 
						|
    ok = Initialization();
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
  m_Tray = NULL;
 | 
						|
  if (ok) 
 | 
						|
  {
 | 
						|
    m_Tray = new TTaskBarIcon;
 | 
						|
    m_Tray->Init();
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
	return ok;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseServerApp::OnExit()
 | 
						|
{
 | 
						|
	if (m_server != NULL)
 | 
						|
	{
 | 
						|
    Deinitialization();
 | 
						|
		delete m_SingleInstance;
 | 
						|
  	delete m_server;
 | 
						|
	}
 | 
						|
	if (m_log != NULL)
 | 
						|
	{
 | 
						|
		wxString str;
 | 
						|
		str << GetAppName() << " shutting down.";
 | 
						|
		WriteLog(str);
 | 
						|
	  delete m_log;
 | 
						|
	}
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
  if (m_Tray != NULL) 
 | 
						|
  {
 | 
						|
    delete m_Tray;
 | 
						|
    m_Tray = NULL;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
	return wxApp::OnExit();
 | 
						|
}
 | 
						|
 | 
						|
wxString TBaseServerApp::UnformatString(const wxString& strFormString) const
 | 
						|
{
 | 
						|
	wxString strResult;
 | 
						|
	for (int i = 0; strFormString[i]; i++)
 | 
						|
	{
 | 
						|
		switch(strFormString[i])
 | 
						|
		{
 | 
						|
		case '+': 
 | 
						|
			strResult += ' '; break;
 | 
						|
		case '%':
 | 
						|
			{
 | 
						|
				const wxChar c = hex2int(strFormString.Mid(i+1, 2));
 | 
						|
				strResult += c;
 | 
						|
				i += 2;
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		default: 
 | 
						|
			strResult += strFormString[i]; break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return strResult;
 | 
						|
}
 | 
						|
 | 
						|
int TBaseServerApp::ParseArguments(wxString args, THashTable& hashArgs) const
 | 
						|
{
 | 
						|
  int uguale = args.Find('=');
 | 
						|
	while (uguale > 0)
 | 
						|
	{
 | 
						|
		wxString name = args.Left(uguale); 
 | 
						|
		name.Trim(false); name.Trim(true);
 | 
						|
		
 | 
						|
		wxString value;
 | 
						|
		const int acapo = args.Find('&');
 | 
						|
		if (acapo > uguale)
 | 
						|
	    value = args.Mid(uguale+1, acapo-uguale-1); 
 | 
						|
		else
 | 
						|
			value = args.Mid(uguale+1); 
 | 
						|
		value.Trim(false); value.Trim(true);
 | 
						|
		hashArgs.Put(name, UnformatString(value));
 | 
						|
 | 
						|
		if (acapo > 0)
 | 
						|
		{
 | 
						|
      args = args.Mid(acapo+1);
 | 
						|
			uguale = args.Find('=');
 | 
						|
		}
 | 
						|
		else
 | 
						|
			uguale = -1;
 | 
						|
	}
 | 
						|
	return hashArgs.GetCount();
 | 
						|
}	
 |