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