// Main.C -*- C++ -*- // Copyright (c) 1997, 1998 Etienne BERNARD // Copyright (C) 2002,2005 Clinton Ebadi // This program 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; either version 2 of the License, or // any later version. // This program 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 this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #ifdef USESCRIPTS #include "Interp.H" #endif #include "Bot.H" namespace { Bot *b; option bot_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'v' }, { "no-background", no_argument, 0, 'b'}, { "config-file", required_argument, 0, 'f'}, { "config-dir", required_argument, 0, 'd'}, { "config", required_argument, 0, 'c'}, { "sys-config", required_argument, 0, 's'}, { "user-config", required_argument, 0, 'u'}, { "debug", no_argument, 0, 'D' } }; void sig_hup(int) { if (b) { b->userList->read(); b->userList->addUserFirst("bidon", "bidon", 0, 0, false, 0, ""); b->reconnect(); } } void print_version () { std::cerr << VERSION_STRING << std::endl << COPYRIGHT_STRING << std::endl << PACKAGE" comes with ABSOLUTELY NO WARRANTY\n" << "This is free software, and you are welcome to redistribute it\n" << "under certain conditions; See the COPYING file for details.\n"; } void print_short_help (const char *name) { std::cerr << "Usage: " << name << " [--help] [--version] [--no-background]\n\t" << "[--config-file file] [--config-dir dir] [--debug]\n\t" << "[--config dir-under-configpath]\n\t" << "[--sys-config dir-in-sysconfdir]\n\t" << "[--user-config dir-userdir] [--debug]\n" << "\n--help shows long help.\n"; } void print_long_help (const char *name) { std::cerr << "Long Help for " << PACKAGE << std::endl; std::cerr << "The manual (info bobot++) will contain the best information on general\n" "usage of Bobot++. Here is a detailed summary of the command line\n" "arguments: (in long arg short arg format). All args are optional.\n"; print_short_help (name); std::cerr << "[--help][-h] Shows this help and exits\n" "[--version][-v] Shows version information and exits\n" "[--no-background][-b] Run bobot++ in the foreground\n" "[--config-file file][-f] Use file instead of bot.conf\n" "[--config-dir dir][-d] Use dir as dir to load config file from\n" "[--config dir][-c] Search your config path (defaults to\n" " " << getenv ("HOME") << "/.bobotpp/config/ and then\n" << " /etc/bobotpp/) for dir and\n" " then loads your config data using dir\n" "[--sys-config dir][-s] Looks for config in /etc/bobotpp/dir. Note\n" " that the user dir is still searched first\n" "[--user-config dir][-u] Looks for config in\n" " " << getenv("HOME") << "/.bobotpp/config/dir/.\n" << " Note that\n" " the system dir is still searched after this if\n" " dir is not found.\n" "[--debug][-D] Makes Bobot++ print debugging info and run in\n" " the foreground" << std::endl << std::endl << "The default configuration is read from\n" << getenv("HOME") << "/.bobotpp/config/default/ and then\n" "/etc/bobotpp/default/ if the user config is not found.\n"; } static void real_main(void* DONOTUSE, int argc, char **argv) { // FIXME: User directory int opt; bool background = true; std::string configFile = "bot.conf"; std::string cmd_directory = ""; std::string sys_directory = "/etc/bobotpp/"; std::string sys_subdir = "default"; std::string user_directory = std::string (getenv ("HOME")) + "/.bobotpp/config/"; String user_subdir = "default"; bool debug = false; std::signal(SIGPIPE, SIG_IGN); std::signal(SIGALRM, SIG_IGN); std::signal(SIGHUP, sig_hup); // We parse the command line options while ((opt = getopt_long (argc,argv,"vhbf:d:c:D", bot_options, 0)) != -1) { switch (opt) { case 'h': print_long_help (argv[0]); exit(0); break; case 'v': print_version (); exit (0); break; case 'b': background = false; break; case 'f': configFile = optarg; break; case 'd': cmd_directory = optarg; break; case 'c': sys_subdir = optarg; user_subdir = optarg; break; case 'u': user_subdir = optarg; break; case 's': sys_subdir = optarg; break; case 'D': debug = true; break; default: print_short_help (argv[0]); std::exit(1); } } DIR * temp; if (! (temp = opendir (String(getenv ("HOME")) + "/.bobotpp/logs"))) { mkdir (String(getenv ("HOME")) + "/.bobotpp/logs", S_IRWXU); } else { closedir (temp); } if (!cmd_directory.length ()) { if (chdir((user_directory + user_subdir).c_str ()) < 0) { if (chdir ((sys_directory + sys_subdir).c_str ()) < 0) { std::cerr << "Dirs don't exist! Exiting\n"; std::exit (2); // no execution } } } else { if (chdir (cmd_directory.c_str ()) < 0) { std::perror("Error: "); std::cerr << "Exiting...\n"; std::exit (2); } } print_version (); // initialize the Parser Parser::init (); if (!debug) { if (background) switch (fork()) { case -1: std::cout << "Could not run in the background. Exiting...\n"; perror("fork"); exit(1); case 0: break; default: std::cout << "Running in the background...\n"; exit(0); } } #ifdef USESCRIPTS Interp::Startup(); #endif b = new Bot(configFile, debug); b->run(); delete b; #ifdef USESCRIPTS Interp::Shutdown(); #endif } } // static functions and data int main(int argc, char **argv) { #ifdef USESCRIPTS scm_boot_guile (argc, argv, real_main, 0); #else real_main(0, argc, argv); #endif return 0; }