/* This file is part of SLD. Copyright (C) 2008 Sebastien LUTTRINGER 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 << " -l file : Write log into file." << 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; if (opt.logfile != "") logfile = opt.logfile; } 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")) { this->verbose = 2; } 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; exit(ERR_NO); } 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]); } else if (!strcmp(argv[i], "-h")) { if (++i >= argc) 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]; } else 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; else 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"; }