recognize startup parameters

Usage: winix [options]
  -c             : a path to the config file
  --config       : a path to the config file
  -h             : print usage information
  --help         : print usage information
  -?             : print usage information

While here:
- let it be possible to parse multiple configs,
- fix: some error messages were not printed at startup.
This commit is contained in:
Tomasz Sowa 2022-04-16 18:38:30 +02:00
parent e0d9989d74
commit 4f8b5e649a
3 changed files with 120 additions and 48 deletions

View File

@ -45,7 +45,6 @@ namespace Winix
Config::Config()
{
errors_to_stdout = true;
}
@ -61,27 +60,19 @@ void Config::SetLogBuffer(pt::WTextStream * log_buffer)
}
void Config::ShowError()
void Config::ShowError(const std::wstring & config_file)
{
switch( parser.status )
{
case pt::SpaceParser::ok:
log << log2 << "Config: syntax ok" << logend;
break;
case pt::SpaceParser::cant_open_file:
if( errors_to_stdout )
std::wcout << L"Config: I cannot open a config file: " << config_file << std::endl;
log << log1 << "Config: cant open a config file: " << config_file << logend;
log << log1 << "Config: I cannot open a config file: " << config_file << logend;
break;
case pt::SpaceParser::syntax_error:
if( errors_to_stdout )
std::wcout << "Config: syntax error, line: " << parser.get_last_parsed_line() << std::endl;
log << log1 << "Config: syntax error, line: " << parser.get_last_parsed_line() << logend;
log << log1 << "Config: syntax error in file: " << config_file << ", line: " << parser.get_last_parsed_line() << logend;
break;
}
}
@ -91,28 +82,26 @@ void Config::ShowError()
bool Config::ReadConfig(bool errors_to_stdout_, bool stdout_is_closed)
bool Config::ReadConfig(const std::wstring & config_file)
{
errors_to_stdout = errors_to_stdout_;
if( config_file.empty() )
{
log << log2 << "Config: name of the config file is empty" << logend;
return false;
}
log << log2 << "Config: reading a config file" << logend;
pt::SpaceParser::Status status = parser.parse_space_file(config_file, space);
log << log2 << "Config: reading a config file: " << config_file << logend;
pt::SpaceParser::Status status = parser.parse_space_file(config_file, space, false);
if( status == pt::SpaceParser::ok )
{
AssignValues(stdout_is_closed);
AssignValues();
SetAdditionalVariables();
return true;
}
else
{
ShowError();
ShowError(config_file);
return false;
}
}
@ -120,7 +109,7 @@ bool Config::ReadConfig(bool errors_to_stdout_, bool stdout_is_closed)
void Config::AssignValues(bool stdout_is_closed)
void Config::AssignValues()
{
server_mode = Text(L"server_mode");
demonize = Bool(L"demonize", true);

View File

@ -53,10 +53,6 @@ class Config
{
public:
// name of the config file
// this is the parameter passed to winix programm
std::wstring config_file;
// server mode
// you can assign any string to it such as "production" "dev"
// this value is not used by winix itself
@ -857,7 +853,7 @@ public:
Config();
bool ReadConfig(bool errors_to_stdout_, bool stdout_is_closed = true);
bool ReadConfig(const std::wstring & config_file);
/*
*
@ -902,11 +898,10 @@ public:
private:
pt::SpaceParser parser;
bool errors_to_stdout;
Log log;
void ShowError();
void AssignValues(bool stdout_is_closed);
void ShowError(const std::wstring & config_file);
void AssignValues();
void SetAdditionalVariables();
void CheckPasswd();

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2008-2018, Tomasz Sowa
* Copyright (c) 2008-2022, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -43,7 +43,7 @@
#include "core/app.h"
#include "core/version.h"
#include "utf8/utf8.h"
#include "mainoptions/mainoptionsparser.h"
@ -59,11 +59,19 @@ App app;
void print_syntax()
{
std::cout << "Syntax:" << std::endl;
std::cout << " winix config_file" << std::endl;
std::cout << "Winix version " << WINIX_VER_MAJOR << '.' << WINIX_VER_MINOR << '.' << WINIX_VER_REVISION << std::endl;
std::cout << "Copyright (c) 2008-2022, Tomasz Sowa" << std::endl;
std::cout << "Usage: winix [options]" << std::endl;
std::cout << " -c : a path to the config file" << std::endl;
std::cout << " --config : a path to the config file" << std::endl;
std::cout << " -h : print usage information" << std::endl;
std::cout << " --help : print usage information" << std::endl;
std::cout << " -? : print usage information" << std::endl;
std::cout << "At least one -c or --config parameter is required, use -c or --config option" << std::endl;
std::cout << "multiple times to load more than one config." << std::endl;
}
@ -148,34 +156,107 @@ void RemovePidFile()
}
bool ReadConfigs(const pt::Space::TableType & table, size_t & config_read)
{
bool status = true;
for(const pt::Space * config : table)
{
if( config->is_table() && config->table_size() == 1 )
{
std::wstring config_file = config->value.value_table[0]->to_wstr();
config_read += 1;
if( !app.config.ReadConfig(config_file) )
{
status = false;
break;
}
}
}
return status;
}
bool ReadConfigs(const pt::Space & options)
{
size_t config_read = 0;
bool status = true;
const pt::Space::TableType * table = options.get_table(L"c");
app.config.space.clear();
if( table )
{
status = status && ReadConfigs(*table, config_read);
}
table = options.get_table(L"config");
if( table )
{
status = status && ReadConfigs(*table, config_read);
}
if( config_read == 0 )
{
std::cout << "You have to provide a config file with c parameter" << std::endl;
Winix::print_syntax();
return false;
}
return status;
}
} // namespace Winix
int main(int argv, char ** argc)
int main(int argc, const char ** argv)
{
using Winix::app;
std::srand(std::time(0));
if( argv != 2 )
{
Winix::print_syntax();
return 1;
}
app.system.system_start = time(0);
if( !pt::utf8_to_wide(argc[1], app.config.config_file) )
pt::Space options;
pt::Space arguments;
pt::MainOptionsParser options_parser;
arguments.add(L"c", 1);
arguments.add(L"config", 1);
pt::MainOptionsParser::Status status = options_parser.parse(argc, argv, options, arguments);
if( status != pt::MainOptionsParser::status_ok )
{
std::wcout << "An incorrect UTF-8 path of the config file" << std::endl;
Winix::print_syntax();
return 6;
}
if( !app.config.ReadConfig(true, false) ) /* errors to stdout, stdout in not closed */
return 2;
if( options.has_key(L"h") || options.has_key(L"help") || options.has_key(L"?") )
{
Winix::print_syntax();
return 0;
}
Winix::Log & log = app.GetMainLog();
Winix::LogInfo(log, Winix::log3, "UTC booting Winix", true, ""); // date will be printed as UTC because the time zones are not loaded yet
if( !Winix::ReadConfigs(options) )
{
// we need to print the buffer by hand because the logger
// is not fully initialized yet
pt::WTextStream * buffer = log.get_log_buffer();
if( buffer && !buffer->empty() )
{
pt::wide_stream_to_utf8(*buffer, std::cout);
}
return 2;
}
app.InitLoggers();
if( app.stdout_is_closed || app.config.demonize )
@ -185,15 +266,22 @@ using Winix::app;
Winix::CloseDescriptors();
if( app.config.demonize && !app.Demonize() )
{
log << Winix::logsave;
return 4;
Winix::LogInfo(log, Winix::log3, "booting Winix", true, "");
}
if( !app.InitFCGI() )
{
log << Winix::logsave;
return 5;
}
if( !app.DropPrivileges() )
{
log << Winix::logsave;
return 3;
}
app.LogUserGroups();
Winix::SavePidFile(log);