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