added: program reads its configuration from a config file

added: confparser directory and confparser.h and confparser.cpp
       class ConfParser used to parse a config file
       this is a generic parser, can be used by another project
added: config.h, config.cpp
       class Config used for assigning values from 
       a config file into the data object
added: function for signals: SIGINT, SIGHUP
       after receiving SIGHUP the program will read
       its config file again


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@463 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2008-12-11 02:46:16 +00:00
parent c53e985a92
commit 8aab988752
15 changed files with 449 additions and 219 deletions

View File

@@ -460,9 +460,9 @@ void Content::Make()
templates.Generate();
// request.PrintGetTable();
//request.PrintGetTable();
//request.PrintEnv();
// request.PrintIn();
//request.PrintIn();
}

View File

@@ -13,34 +13,11 @@
Data::Data()
{
// all these data will be reading from a config file
signal_hup = false;
stdout_is_closed = false;
log_file = "cmslu.log";
fcgi_socket = "/var/cmslu/s1";
fcgi_socket_chmod = 0770;
fcgi_socket_user = "tomek";
fcgi_socket_group = "www";
log_level = 2;
log_stdout = true;
templates = "../httpd/templates"; // templates dir
default_index = "index.html";
http_session_id_name = "slimaczek_sid";
db_database = "tomek";
db_user = "tomek";
db_pass = "monitorekasd";
// !! add a method which will be adding a slash at the end of url-es
base_url = "http://s10.slimaczek.pl/"; // with a slash at the end
one_item_is_showed = true;
dir.root.default_item = 134;
// the rest will be read from a config file
}

View File

@@ -23,11 +23,13 @@
class Data
{
public:
// -----------------------------------------------------------------
// members read from a config file
// name of the config file (full path can be)
std::string config_file;
// log file name
std::string log_file;
@@ -62,21 +64,30 @@ public:
std::string base_url;
std::string http_session_id_name;
Dir dir;
// if there is one item in a directory
// it will be showed
// (instead of showing directory contents)
bool one_item_is_showed;
// end config members
// -----------------------------------------------------------------
// false at the beginning
bool stdout_is_closed;
// true if there was the SIGHUP signal
volatile bool signal_hup;
Dir dir;
Data();
};

View File

@@ -35,6 +35,8 @@ void Db::Init(const std::string & d, const std::string & u, const std::string &
void Db::Connect()
{
Close();
std::ostringstream buf;
buf << "dbname=" << db_database << " user=" << db_user << " password=" << db_pass;

View File

@@ -33,6 +33,7 @@ public:
db_incorrect_login,
db_more_than_one_login,
db_err_currval,
incorrect_dir,

View File

@@ -13,10 +13,8 @@
Log::Log()
{
log_level = 1;
current_level = 2;
log_file = "cmslu.log";
log_stdout = true;
log_level = 3;
current_level = 4; // nothing to log (call Init() first)
}
@@ -27,8 +25,7 @@ void Log::Init(int log_l, const std::string & log_f, bool log_std)
log_stdout = log_std;
}
// zrobic templeta z tych metod
// i dla const char * zrobic specjalizacje
Log & Log::operator<<(const char * s)
{
@@ -64,14 +61,7 @@ Log & Log::operator<<(long s)
return *this;
}
/*
Log & Log::operator<<(void * s)
{
buffer << s;
return *this;
}
*/
Log & Log::operator<<(char s)
@@ -92,28 +82,27 @@ Log & Log::operator<<(size_t s)
Log & Log::operator<<(Manipulators m)
{
switch(m)
{
case logend:
SaveLog();
buffer.str( "" );
break;
switch(m)
{
case logend:
SaveLog();
buffer.str( "" );
break;
case log1:
current_level = 1;
break;
case log2:
current_level = 2;
break;
case log3:
current_level = 3;
break;
}
case log1:
current_level = 1;
break;
case log2:
current_level = 2;
break;
case log3:
current_level = 3;
break;
}
return *this;
return *this;
}
@@ -129,6 +118,9 @@ int attempt = 2;
std::cout << buffer.str() << std::endl;
if( log_file.empty() )
return;
std::ofstream file;
do

View File

@@ -28,27 +28,21 @@ std::string log_file;
bool log_stdout;
public:
Log();
void Init(int log_l, const std::string & log_f, bool log_std);
Log & operator<<(const char * s);
Log & operator<<(const std::string & s);
Log & operator<<(int s);
Log & operator<<(long s);
//Log & operator<<(void * s); // ??
Log & operator<<(char s);
Log & operator<<(size_t s);
Log & operator<<(Manipulators m);
void SaveLog();
};

View File

@@ -16,6 +16,8 @@
#include "log.h"
#include "request.h"
#include "db.h"
#include "config.h"
// singletons
@@ -24,50 +26,92 @@ Data data;
Log log;
Request request;
Db db;
Config config;
void signal_term(int)
{
log << log1 << "system aborted" << logend;
log << log1 << "cmslu stopped" << logend;
exit(0);
}
int main()
void signal_hup(int)
{
std::srand(std::time(0));
log << log3 << "SIGHUP received" << logend;
data.signal_hup = true;
config.ReadConfig(false); /* errors not to stdout */
}
log.Init(data.log_level, data.log_file, data.log_stdout);
void print_syntax()
{
std::cout << "Syntax:" << std::endl;
std::cout << " cmslu.fcgi config_file" << std::endl;
}
int main(int argv, char ** argc)
{
RequestController req_controller;
//data.read_from_file();
std::srand(std::time(0));
db.Init(data.db_database, data.db_user, data.db_pass);
if( !req_controller.Init() )
if( argv != 2 )
{
print_syntax();
return 1;
}
data.config_file = argc[1];
if( !config.ReadConfig(true) ) /* errors to stdout */
return 2;
// closing descriptors only at the beginning
close(2);
if( !data.log_stdout )
{
close(1);
data.stdout_is_closed = true;
}
log << log1 << "system started" << logend;
signal(SIGTERM, signal_term);
signal(SIGINT, signal_term);
signal(SIGHUP, signal_hup);
log << log1 << "checking for table consistency...";
db.CheckAllUrlSubject();
log << log1 << "done" << logend;
while( true )
{
log.Init(data.log_level, data.log_file, data.log_stdout);
db.Init(data.db_database, data.db_user, data.db_pass);
if( !req_controller.Init() )
return 1;
req_controller.Loop();
log << log2 << "checking for table consistency:" << logend;
db.CheckAllUrlSubject();
log << log1 << "cmslu started" << logend;
log << log1 << "system stopped" << logend;
req_controller.Loop();
if( data.signal_hup )
data.signal_hup = false;
}
return 0;
}

View File

@@ -184,6 +184,9 @@ void Request::ReadEnvVariables()
env_request_method = FCGX_GetParam("REQUEST_METHOD", env);
env_request_uri = FCGX_GetParam("REQUEST_URI", env);
env_http_cookie = FCGX_GetParam("HTTP_COOKIE", env);
env_remote_addr = FCGX_GetParam("REMOTE_ADDR", env);
log << log1 << "IP: " << env_remote_addr << logend;
}
@@ -271,104 +274,3 @@ void Request::SendAll()
// ----------------
/*
unsigned char Request::tohex(unsigned char polowa)
{
// polowa z zakresu 0-15
polowa = polowa & 0xf;
if(polowa<10)
polowa += '0';
else
polowa = polowa - 10 + 'A';
return polowa;
}
// cala wartosc zapisywana jest w postaci hex
string Request::ToHex(const string & dane)
{
string wynik;
unsigned int i;
for(i=0 ; i<dane.length() ; ++i)
{
wynik += tohex(dane[i] >> 4);
wynik += tohex(dane[i] & 0xf);
}
return wynik;
}
string Request::HexToString(const string & dane)
{
string wynik;
unsigned int i;
unsigned char znak,znak1,znak2;
if(dane.length()==0)
return wynik;
for(i=0 ; i<dane.length()-1 ; i+=2)
{
znak1 = parsujhex(dane[i]);
znak2 = parsujhex(dane[i+1]);
znak = (znak1 << 4) + znak2;
wynik += znak;
}
return wynik;
}
string Request::ToUrl(const string & dane)
{
string wynik;
unsigned int i;
for(i=0 ; i<dane.length() ; ++i)
{
if( (dane[i]>='a' && dane[i]<='z') ||
(dane[i]>='A' && dane[i]<='Z') ||
(dane[i]>='0' && dane[i]<='9') ||
dane[i]=='_' )
{
wynik += dane[i];
}
else
{
wynik += '%';
wynik += tohex(dane[i] >> 4);
wynik += tohex(dane[i] & 0xf);
}
}
return wynik;
}
*/

View File

@@ -41,9 +41,11 @@ struct Request
PostTable post_table;
CookieTable cookie_table;
// environment variables (can be null)
const char * env_request_method;
const char * env_request_uri;
const char * env_http_cookie;
const char * env_remote_addr;
// current session
// is set after calling session_manager.SetSession()

View File

@@ -16,6 +16,22 @@ RequestController::RequestController()
}
RequestController::~RequestController()
{
Close();
}
void RequestController::Close()
{
// don't call close(0)
// it will be closed next time during dup(s,0)
// if you closed the descriptor here
// then the database would have that descriptor (during connecting)
// and there'll be a problem in the next loop (after SIGHUP)
}
bool RequestController::Init()
@@ -77,12 +93,6 @@ bool RequestController::Init()
dup2(s, 0);
if( !data.log_stdout )
close(1);
close(2);
//
@@ -133,5 +143,13 @@ void RequestController::Loop()
log << log2 << "end request" << logend;
log << log2 << "---------------------------------------------------------------------------------" << logend;
// !! this should be immediately after FCGX_Accept() but signals don't want to break FCGX_Accept
if( data.signal_hup )
{
FCGX_Finish();
return;
}
}
}

View File

@@ -32,11 +32,14 @@ class RequestController
Content content;
SessionManager session_manager;
public:
RequestController();
~RequestController();
bool Init();
void Close();
void Loop();
};