Newer
Older
/*
This file is part of SLD.
Copyright (C) 2008 Sebastien LUTTRINGER <contact@seblu.net>
SLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
SLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SLD; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "sld.hh"
Options::Options() {
port = -1;
verbose = -1;
retrydelay = -1;
daemon = -1;
}
void Options::usage(const char *argv0) const {
std::cerr
<< "usage: "
<< argv0
<< " [-f conffile] [-d scriptdir] [-h] [-v] [-l login]"
<< " [-p pass] [-H host] [-P port] [-r] [-V]"
<< std::endl
<< " -f file : read and load conf file (def: /etc/sldrc)." << std::endl
<< " -d dir : Scripts directory." << std::endl
<< " -h : Print this usage." << std::endl
<< " -v : Verbose mode." << std::endl
<< " -q : Quiet mode." << std::endl
<< " -d : Daemon mode." << std::endl
<< " -h host : Set login to host (def: check hostname)." << std::endl
<< " -p secret : Set pass to secret." << std::endl
<< " -H name : Set server host to name." << std::endl
<< " -P number : Set server port to number (def: 18136)." << std::endl
<< " -r number : Set retry delay to val in seconds (def: 60)." << std::endl
<< " -F file : Set file where pid is written." << std::endl
<< " -V : Print version and exit." << std::endl;
}
void Options::merge(const Options &opt) {
if (opt.server != "") server = opt.server;
if (opt.port >= 0) port = opt.port;
if (opt.login != "") login = opt.login;
if (opt.pass != "") pass = opt.pass;
if (opt.verbose >= 0) verbose = opt.verbose;
if (opt.conffile != "") conffile = opt.conffile;
if (opt.scriptdir != "") scriptdir = opt.scriptdir;
if (opt.retrydelay >= 0) retrydelay = opt.retrydelay;
if (opt.daemon >= 0) daemon = opt.daemon;
if (opt.pidfile != "") pidfile = opt.pidfile;
}
Options &Options::getoptions(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-h")) {
usage(*argv);
throw Error(ERR_USAGE);
}
else if (!strcmp(argv[i], "-v")) {
}
else if (!strcmp(argv[i], "-q")) {
this->verbose = 0;
}
else if (!strcmp(argv[i], "-d")) {
this->daemon = 1;
}
else if (!strcmp(argv[i], "-V")) {
std::cout << "sl daemon version : " << VERSION << std::endl;
}
else if (!strcmp(argv[i], "-H")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -h");
this->server = string(argv[i]);
}
else if (!strcmp(argv[i], "-P")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -p");
char *endptr;
this->port = strtol(argv[i], &endptr, 10);
if (!(*argv[i] != '\0' && *endptr == '\0'))
throw Error(ERR_USAGE, "Unable to convert port to a number");
}
else if (!strcmp(argv[i], "-f")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -f");
this->conffile = string(argv[i]);
}
else if (!strcmp(argv[i], "-d")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -d");
this->scriptdir = string(argv[i]);
}
throw Error(ERR_USAGE, "No enough argument for option -h");
this->login = string(argv[i]);
}
else if (!strcmp(argv[i], "-p")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -p");
this->pass = string(argv[i]);
}
else if (!strcmp(argv[i], "-r")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -r");
this->retrydelay = atoi(argv[i]);
}
else if (!strcmp(argv[i], "-F")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -F");
this->pidfile = argv[i];
}
else if (!strcmp(argv[i], "-l")) {
if (++i >= argc)
throw Error(ERR_USAGE, "No enough argument for option -l");
this->pidfile = argv[i];
}
throw Error(ERR_USAGE, (string) "Invalid option : " + argv[i]);
}
return *this;
}
Options Options::getoptions(const string file) {
ifstream fs;
char line[MAX_CONF_LINE_SIZE];
int i=0;
char name[11], value[MAX_CONF_LINE_SIZE - 10 + 1];
fs.open(file.c_str(), ifstream::in);
if (fs.fail())
throw Error(ERR_FILE, "Unable to open configuration file");
while (!fs.eof()) {
fs.getline(line, MAX_CONF_LINE_SIZE);
if (fs.eof())
break;
++i;
// jump empty line
if (*line == '#' || *line == 0)
continue;
sscanf(line, "%10[^=]=%2039s\n", name, value); //TODO: fix magic number
if (!strcasecmp(name, "host"))
this->login = value;
else if (!strcasecmp(name, "pass"))
this->pass = value;
else if (!strcasecmp(name, "server"))
this->server = value;
else if (!strcasecmp(name, "port"))
this->port = atoi(value);
else if (!strcasecmp(name, "scriptdir"))
this->scriptdir = value;
else if (!strcasecmp(name, "verbose"))
this->verbose = atoi(value);
else if (!strcasecmp(name, "retrydelay"))
this->retrydelay = atoi(value);
else if (!strcasecmp(name, "daemon"))
this->daemon = atoi(value);
else if (!strcasecmp(name, "pidfile"))
this->pidfile = value;
else if (!strcasecmp(name, "logfile"))
this->logfile = value;
logerr << "Invalid line " << i << ": " << line << "\n";
}
fs.close();
return *this;
}
Logger &operator<< (Logger &s, const Options &o) {
return s << "server: " << o.server << "\n"
<< "port: " << o.port << "\n"
<< "host login: " << o.login << "\n"
<< "host pass: " << o.pass << "\n"
<< "script directory: " << o.scriptdir << "\n"
<< "configuration file: " << o.conffile << "\n"
<< "retry delay: " << o.retrydelay << "\n"
<< "daemon mode: " << o.daemon << "\n"
<< "log file: " << o.logfile << "\n"
<< "pid file: " << o.pidfile << "\n"
<< "verbose level: " << o.verbose << "\n";