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 | |
cb21075d |
24 | #include <cstdio> |
25 | #include <csignal> |
31433d27 |
26 | #include <cstdlib> |
ad529fde |
27 | #include <getopt.h> |
439869bf |
28 | #include <dirent.h> |
0316e2c1 |
29 | #include <unistd.h> |
439869bf |
30 | #include <sys/stat.h> |
31 | #include <sys/types.h> |
cb21075d |
32 | |
0316e2c1 |
33 | #include <iostream> |
34 | #include <string> |
35 | |
cb21075d |
36 | #ifdef USESCRIPTS |
37 | #include "Interp.H" |
38 | #endif |
39 | |
40 | #include "Bot.H" |
41 | |
ad529fde |
42 | namespace |
43 | { |
0316e2c1 |
44 | Bot *b; |
cb21075d |
45 | |
0316e2c1 |
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'}, |
4da877a5 |
56 | #ifdef USESCRIPTS |
57 | { "debug-scripts", no_argument, 0, 'S' }, |
58 | #endif |
0316e2c1 |
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 | } |
cb21075d |
68 | } |
cb21075d |
69 | |
0316e2c1 |
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 | } |
ad529fde |
89 | |
0316e2c1 |
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" |
4da877a5 |
123 | #ifdef USESCRIPTS |
124 | "\n[--debug-scripts][-S] Turns on Guile debugging evaluator" |
125 | #endif |
0316e2c1 |
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 | } |
cb21075d |
133 | |
0316e2c1 |
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; |
4da877a5 |
147 | bool script_debug = false; |
cb21075d |
148 | |
0316e2c1 |
149 | std::signal(SIGPIPE, SIG_IGN); |
150 | std::signal(SIGALRM, SIG_IGN); |
151 | std::signal(SIGHUP, sig_hup); |
439869bf |
152 | |
0316e2c1 |
153 | // We parse the command line options |
4da877a5 |
154 | while ((opt = getopt_long (argc,argv,"vhbf:d:c:DS", bot_options, 0)) |
0316e2c1 |
155 | != -1) |
156 | { |
157 | switch (opt) |
31433d27 |
158 | { |
0316e2c1 |
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; |
4da877a5 |
189 | case 'S': |
190 | script_debug = true; |
191 | break; |
0316e2c1 |
192 | default: |
193 | print_short_help (argv[0]); |
194 | std::exit(1); |
31433d27 |
195 | } |
0316e2c1 |
196 | } |
197 | |
198 | DIR * temp; |
199 | |
200 | if (! (temp = opendir (String(getenv ("HOME")) + "/.bobotpp/logs"))) |
31433d27 |
201 | { |
0316e2c1 |
202 | mkdir (String(getenv ("HOME")) + "/.bobotpp/logs", |
203 | S_IRWXU); |
204 | } |
205 | else |
206 | { |
207 | closedir (temp); |
31433d27 |
208 | } |
cb21075d |
209 | |
0316e2c1 |
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 | } |
cb21075d |
220 | } |
0316e2c1 |
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 | |
606a8eec |
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: |
0316e2c1 |
246 | break; |
606a8eec |
247 | default: |
248 | std::cout << "Running in the background...\n"; |
249 | exit(0); |
250 | } |
251 | } |
cb21075d |
252 | |
186fb426 |
253 | b = new Bot(configFile, debug); |
cb21075d |
254 | #ifdef USESCRIPTS |
0316e2c1 |
255 | Interp::Startup(); |
4da877a5 |
256 | if (debug || script_debug) |
606a8eec |
257 | { |
258 | SCM_DEVAL_P = 1; |
259 | SCM_RECORD_POSITIONS_P = 1; |
d56bdd22 |
260 | SCM_BACKTRACE_P = 1; |
606a8eec |
261 | SCM_RESET_DEBUG_MODE; |
262 | } |
cb21075d |
263 | #endif |
0316e2c1 |
264 | b->run(); |
265 | delete b; |
cb21075d |
266 | |
267 | #ifdef USESCRIPTS |
0316e2c1 |
268 | Interp::Shutdown(); |
cb21075d |
269 | #endif |
0316e2c1 |
270 | } |
cb21075d |
271 | |
ad529fde |
272 | } // static functions and data |
273 | |
c7d9fb19 |
274 | int main(int argc, char **argv) |
275 | { |
cb21075d |
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 | } |