bb51b5412565dcc80bbdf8581e14841e64e3af8f
[clinton/bobotpp.git] / source / Main.C
1 // Main.C -*- C++ -*-
2 // Copyright (c) 1997, 1998 Etienne BERNARD
3 // Copyright (C) 2002 Clinton Ebadi
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // any later version.
9
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <unistd.h>
24 #include <iostream>
25 #include <cstdio>
26 #include <csignal>
27 #include <cstdlib>
28 #include <getopt.h>
29 #include <dirent.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32
33 #ifdef USESCRIPTS
34 #include "Interp.H"
35 #endif
36
37 #include "Bot.H"
38
39 namespace
40 {
41 Bot *b;
42
43 option bot_options[] =
44 {
45 { "help", no_argument, 0, 'h' },
46 { "version", no_argument, 0, 'v' },
47 { "no-background", no_argument, 0, 'b'},
48 { "config-file", required_argument, 0, 'f'},
49 { "config-dir", required_argument, 0, 'd'},
50 { "config", required_argument, 0, 'c'},
51 { "sys-config", required_argument, 0, 's'},
52 { "user-config", required_argument, 0, 'u'},
53 { "debug", no_argument, 0, 'D' }
54 };
55
56 void sig_hup(int) {
57 if (b) {
58 b->userList->read();
59 b->userList->addUserFirst("bidon", "bidon", 0, 0, false, 0, "");
60 b->reconnect();
61 }
62 }
63
64 void print_version ()
65 {
66 std::cerr << VERSION_STRING << std::endl
67 << COPYRIGHT_STRING << std::endl
68 << PACKAGE" comes with ABSOLUTELY NO WARRANTY\n"
69 << "This is free software, and you are welcome to redistribute it\n"
70 << "under certain conditions; See the COPYING file for details.\n";
71 }
72 void print_short_help (const char *name)
73 {
74 std::cerr << "Usage: "
75 << name
76 << " [--help] [--version] [--no-background]\n\t"
77 << "[--config-file file] [--config-dir dir] [--debug]\n\t"
78 << "[--config dir-under-configpath]\n\t"
79 << "[--sys-config dir-in-sysconfdir]\n\t"
80 << "[--user-config dir-userdir] [--debug]\n"
81 << "\n--help shows long help.\n";
82 }
83
84 void print_long_help (const char *name)
85 {
86 std::cerr << "Long Help for " << PACKAGE << std::endl;
87 std::cerr <<
88 "The manual (info bobot++) will contain the best information on general\n"
89 "usage of Bobot++. Here is a detailed summary of the command line\n"
90 "arguments: (in long arg short arg format). All args are optional.\n";
91 print_short_help (name);
92 std::cerr <<
93 "[--help][-h] Shows this help and exits\n"
94 "[--version][-v] Shows version information and exits\n"
95 "[--no-background][-b] Run bobot++ in the foreground\n"
96 "[--config-file file][-f] Use file instead of bot.conf\n"
97 "[--config-dir dir][-d] Use dir as dir to load config file from\n"
98 "[--config dir][-c] Search your config path (defaults to\n"
99 " "
100 << getenv ("HOME")
101 << "/.bobotpp/config/ and then\n"
102 <<
103 " /etc/bobotpp/) for dir and\n"
104 " then loads your config data using dir\n"
105 "[--sys-config dir][-s] Looks for config in /etc/bobotpp/dir. Note\n"
106 " that the user dir is still searched first\n"
107 "[--user-config dir][-u] Looks for config in\n"
108 " "
109 << getenv("HOME")
110 << "/.bobotpp/config/dir/.\n"
111 <<
112 " Note that\n"
113 " the system dir is still searched after this if\n"
114 " dir is not found.\n"
115 "[--debug][-D] Makes Bobot++ print debugging info and run in\n"
116 " the foreground"
117 << std::endl
118 << std::endl
119 << "The default configuration is read from\n"
120 << getenv("HOME")
121 << "/.bobotpp/config/default/ and then\n"
122 "/etc/bobotpp/default/ if the user config is not found.\n";
123 }
124
125 static void real_main(void* DONOTUSE, int argc, char **argv)
126 {
127 // FIXME: User directory
128 int opt;
129 bool background = true;
130 String configFile = "bot.conf";
131 String cmd_directory = "";
132 String sys_directory = "/etc/bobotpp/";
133 String sys_subdir = "default";
134 String user_directory = String(getenv ("HOME")) + "/.bobotpp/config/";
135 String user_subdir = "default";
136 bool debug = false;
137
138 std::signal(SIGPIPE, SIG_IGN);
139 std::signal(SIGALRM, SIG_IGN);
140 std::signal(SIGHUP, sig_hup);
141
142 // We parse the command line options
143 while ((opt = getopt_long (argc,argv,"vhbf:d:c:D", bot_options, 0))
144 != -1)
145 switch (opt) {
146 case 'h':
147 print_long_help (argv[0]);
148 exit(0);
149 break;
150 case 'v':
151 print_version ();
152 exit (0);
153 break;
154 case 'b':
155 background = false;
156 break;
157 case 'f':
158 configFile = optarg;
159 break;
160 case 'd':
161 cmd_directory = optarg;
162 break;
163 case 'c':
164 sys_subdir = optarg;
165 user_subdir = optarg;
166 break;
167 case 'u':
168 user_subdir = optarg;
169 break;
170 case 's':
171 sys_subdir = optarg;
172 break;
173 case 'D':
174 debug = true;
175 break;
176 default:
177 print_short_help (argv[0]);
178 exit(1);
179 }
180
181 DIR * temp;
182 if (! (temp = opendir (String(getenv ("HOME")) + "/.bobotpp/logs")))
183 mkdir (String(getenv ("HOME")) + "/.bobotpp/logs",
184 S_IRWXU);
185 else
186 closedir (temp);
187
188 if (!cmd_directory.length ())
189 {
190 if (chdir(user_directory + user_subdir) < 0)
191 if (chdir(sys_directory + sys_subdir) < 0)
192 {
193 std::cerr << "Dirs don't exist! Exiting\n";
194 std::exit (2); // no execution
195 }
196 }
197 else
198 if (chdir(cmd_directory) < 0)
199 {
200 std::perror("Error: ");
201 std::cerr << "Exiting...\n";
202 std::exit (2);
203 }
204
205 // std::cout << COPYRIGHT_STRING <<
206 // "\n"PACKAGE" comes with ABSOLUTELY NO WARRANTY\n"
207 // "This is free software, and you are welcome to redistribute it\n"
208 // "under certain conditions; See the COPYING file for details.\n";
209 print_version ();
210
211 // initialize the Parser
212 Parser::init ();
213
214 if (!debug) {
215 if (background)
216 switch (fork()) {
217 case -1:
218 std::cout << "Could not run in the background. Exiting...\n";
219 perror("fork");
220 exit(1);
221 case 0:
222 break;
223 default:
224 std::cout << "Running in the background...\n";
225 exit(0);
226 }
227 }
228
229 #ifdef USESCRIPTS
230 Interp::Startup();
231 #endif
232
233 b = new Bot(configFile, debug);
234 b->run();
235 delete b;
236
237 #ifdef USESCRIPTS
238 Interp::Shutdown();
239 #endif
240 }
241
242 } // static functions and data
243
244 int main(int argc, char **argv) {
245 #ifdef USESCRIPTS
246 scm_boot_guile (argc, argv, real_main, 0);
247 #else
248 real_main(0, argc, argv);
249 #endif
250
251 return 0;
252 }