/* 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 #include #include #include #include #include #include #include "sld.hh" static Options get_default_options(); static bool register_signals(); /*! ** Program entry point ** ** @param argc arg count ** @param argv arg vector ** ** @return program err code */ int main(int argc, char *argv[]) { SLDaemon &daemon = SLDaemon::Instance(); Options *lineopt = new Options(); try { // Set default options daemon.options.merge(get_default_options()); // Parse and merge line options lineopt->getoptions(argc, argv); daemon.options.merge(*lineopt); // Get and apply options if conffile is specified if (!euidaccess(daemon.options.conffile.c_str(), R_OK)) { daemon.options.getoptions(daemon.options.conffile); //apply arg line options daemon.options.merge(*lineopt); } } catch (const Error &e) { e.print(); return e.code(); } delete lineopt; // Set a log file if necessary if (daemon.options.logfile != "") { logout.file(daemon.options.logfile); logerr.file(daemon.options.logfile); } if (!register_signals()) return ERR_SIGNAL; // Switch in daemon mode if (daemon.options.daemon == 1) ::daemon(0, 0); // if no daemon, can dup on quiet mode else if (daemon.options.verbose == 0) { int dn = open("/dev/null", O_RDWR); if (dn == -1) { logerr << "sld: open(/dev/null, O_RDWR): " << strerror(errno) << ".\n"; return ERR_UNKNOWN; } dup2(dn, STDOUT_FILENO); dup2(dn, STDERR_FILENO); close(dn); } // Write pid in a file if (daemon.options.pidfile != "") { FILE *fs = fopen(daemon.options.pidfile.c_str(), "w"); if (fs) { fprintf(fs, "%d", getpid()); fclose(fs); } else logerr << "sld: fopen: " << strerror(errno) << ".\n"; } // run daemon try { daemon.run(); } catch (const Error &e) { logerr << "sld: error: " << e.message() << ".\n"; return e.code(); } return ERR_UNKNOWN; } /*! ** Register signals ** ** @return success status */ static bool register_signals() { // register sigchild handler if (signal(SIGCHLD, sigchild) == SIG_ERR) { logerr << "sld: error: " << strerror(errno) << ".\n"; return false; } // register sigint handler if (signal(SIGINT, sigint) == SIG_ERR) { logerr << "sld: error: " << strerror(errno) << ".\n"; return false; } // register sigkill handler if (signal(SIGTERM, sigint) == SIG_ERR) { logerr << "sld: error: " << strerror(errno) << ".\n"; return false; } // register sigkill handler if (signal(SIGHUP, sigint) == SIG_ERR) { logerr << "sld: error: " << strerror(errno) << ".\n"; return false; } return true; } /*! ** Set default options ** ** @param opt option struc to set ** */ static Options get_default_options() { char buf[128]; Options options; if (gethostname(buf, 128) == 0) options.login = buf; options.port = 18136; options.conffile = "/etc/sldrc"; options.retrydelay = 60; options.daemon = 0; options.closefd = 1; options.verbose = 1; return options; } /*! ** Retrieve complete path of this executable ** ** @return program path */ string getbinpath() { int pid = getpid(); char buf[PATH_MAX]; char buf2[PATH_MAX] = ""; snprintf(buf, PATH_MAX, "/proc/%d/exe", pid); if (readlink(buf, buf2, PATH_MAX) == 0) { logerr << "sld: getbinpath: readlink: " << strerror(errno) << ".\n"; return (string) ""; } return (string) buf2; } /*! ** copy src to dst ** ** @param src copy file src ** @param dst copy file dst ** ** @return true if all is copied */ bool cp(const char *src, const char *dst) { assert(src); assert(dst); //open source file FILE *fsrc = fopen(src, "r"); if (!fsrc) return false; //open destination file FILE *fdst = fopen(dst, "w"); if (!fdst) { fclose(fsrc); return false; } //do copy char buf[512]; size_t nread; size_t nwrite; while ((nread = fread(buf, 1, 512, fsrc)) > 0) { nwrite = fwrite(buf, 1, nread, fdst); if (nwrite != nread) { fclose(fsrc); fclose(fdst); return false; } } fclose(fsrc); fclose(fdst); return true; }