Commit | Line | Data |
---|---|---|
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 | |
306ab31b CE |
62 | { "debug", no_argument, 0, 'D' }, |
63 | { 0, 0, 0, 0 } | |
0316e2c1 | 64 | }; |
65 | ||
66 | void sig_hup(int) { | |
67 | if (b) { | |
68 | b->userList->read(); | |
69 | b->userList->addUserFirst("bidon", "bidon", 0, 0, false, 0, ""); | |
70 | b->reconnect(); | |
71 | } | |
cb21075d | 72 | } |
cb21075d | 73 | |
0316e2c1 | 74 | void print_version () |
75 | { | |
76 | std::cerr << VERSION_STRING << std::endl | |
77 | << COPYRIGHT_STRING << std::endl | |
78 | << PACKAGE" comes with ABSOLUTELY NO WARRANTY\n" | |
79 | << "This is free software, and you are welcome to redistribute it\n" | |
80 | << "under certain conditions; See the COPYING file for details.\n"; | |
81 | } | |
82 | void print_short_help (const char *name) | |
83 | { | |
84 | std::cerr << "Usage: " | |
85 | << name | |
86 | << " [--help] [--version] [--no-background]\n\t" | |
87 | << "[--config-file file] [--config-dir dir] [--debug]\n\t" | |
88 | << "[--config dir-under-configpath]\n\t" | |
89 | << "[--sys-config dir-in-sysconfdir]\n\t" | |
90 | << "[--user-config dir-userdir] [--debug]\n" | |
91 | << "\n--help shows long help.\n"; | |
92 | } | |
ad529fde | 93 | |
0316e2c1 | 94 | void print_long_help (const char *name) |
95 | { | |
96 | std::cerr << "Long Help for " << PACKAGE << std::endl; | |
97 | std::cerr << | |
98 | "The manual (info bobot++) will contain the best information on general\n" | |
99 | "usage of Bobot++. Here is a detailed summary of the command line\n" | |
100 | "arguments: (in long arg short arg format). All args are optional.\n"; | |
101 | print_short_help (name); | |
102 | std::cerr << | |
103 | "[--help][-h] Shows this help and exits\n" | |
104 | "[--version][-v] Shows version information and exits\n" | |
105 | "[--no-background][-b] Run bobot++ in the foreground\n" | |
106 | "[--config-file file][-f] Use file instead of bot.conf\n" | |
107 | "[--config-dir dir][-d] Use dir as dir to load config file from\n" | |
108 | "[--config dir][-c] Search your config path (defaults to\n" | |
109 | " " | |
110 | << getenv ("HOME") | |
9f3a011c | 111 | << "/.bobotpp/default/ and then\n" |
0316e2c1 | 112 | << |
113 | " /etc/bobotpp/) for dir and\n" | |
114 | " then loads your config data using dir\n" | |
115 | "[--sys-config dir][-s] Looks for config in /etc/bobotpp/dir. Note\n" | |
116 | " that the user dir is still searched first\n" | |
117 | "[--user-config dir][-u] Looks for config in\n" | |
118 | " " | |
119 | << getenv("HOME") | |
120 | << "/.bobotpp/config/dir/.\n" | |
121 | << | |
122 | " Note that\n" | |
123 | " the system dir is still searched after this if\n" | |
124 | " dir is not found.\n" | |
125 | "[--debug][-D] Makes Bobot++ print debugging info and run in\n" | |
126 | " the foreground" | |
4da877a5 | 127 | #ifdef USESCRIPTS |
128 | "\n[--debug-scripts][-S] Turns on Guile debugging evaluator" | |
129 | #endif | |
0316e2c1 | 130 | << std::endl |
131 | << std::endl | |
132 | << "The default configuration is read from\n" | |
133 | << getenv("HOME") | |
134 | << "/.bobotpp/config/default/ and then\n" | |
135 | "/etc/bobotpp/default/ if the user config is not found.\n"; | |
136 | } | |
cb21075d | 137 | |
0316e2c1 | 138 | static void real_main(void* DONOTUSE, int argc, char **argv) |
139 | { | |
140 | // FIXME: User directory | |
141 | int opt; | |
142 | bool background = true; | |
143 | std::string configFile = "bot.conf"; | |
144 | std::string cmd_directory = ""; | |
145 | std::string sys_directory = "/etc/bobotpp/"; | |
146 | std::string sys_subdir = "default"; | |
147 | std::string user_directory = | |
148 | std::string (getenv ("HOME")) + "/.bobotpp/config/"; | |
149 | String user_subdir = "default"; | |
150 | bool debug = false; | |
4da877a5 | 151 | bool script_debug = false; |
cb21075d | 152 | |
0316e2c1 | 153 | std::signal(SIGPIPE, SIG_IGN); |
154 | std::signal(SIGALRM, SIG_IGN); | |
155 | std::signal(SIGHUP, sig_hup); | |
439869bf | 156 | |
0316e2c1 | 157 | // We parse the command line options |
4da877a5 | 158 | while ((opt = getopt_long (argc,argv,"vhbf:d:c:DS", bot_options, 0)) |
0316e2c1 | 159 | != -1) |
160 | { | |
161 | switch (opt) | |
31433d27 | 162 | { |
0316e2c1 | 163 | case 'h': |
164 | print_long_help (argv[0]); | |
165 | exit(0); | |
166 | break; | |
167 | case 'v': | |
168 | print_version (); | |
169 | exit (0); | |
170 | break; | |
171 | case 'b': | |
172 | background = false; | |
173 | break; | |
174 | case 'f': | |
175 | configFile = optarg; | |
176 | break; | |
177 | case 'd': | |
178 | cmd_directory = optarg; | |
179 | break; | |
180 | case 'c': | |
181 | sys_subdir = optarg; | |
182 | user_subdir = optarg; | |
183 | break; | |
184 | case 'u': | |
185 | user_subdir = optarg; | |
186 | break; | |
187 | case 's': | |
188 | sys_subdir = optarg; | |
189 | break; | |
190 | case 'D': | |
191 | debug = true; | |
192 | break; | |
4da877a5 | 193 | case 'S': |
194 | script_debug = true; | |
195 | break; | |
0316e2c1 | 196 | default: |
197 | print_short_help (argv[0]); | |
198 | std::exit(1); | |
31433d27 | 199 | } |
0316e2c1 | 200 | } |
201 | ||
202 | DIR * temp; | |
203 | ||
815a1816 | 204 | if (! (temp = opendir ((String(getenv ("HOME")) + "/.bobotpp/logs").c_str ()))) |
31433d27 | 205 | { |
815a1816 | 206 | mkdir ((String(getenv ("HOME")) + "/.bobotpp/logs").c_str (), |
0316e2c1 | 207 | S_IRWXU); |
208 | } | |
209 | else | |
210 | { | |
211 | closedir (temp); | |
31433d27 | 212 | } |
cb21075d | 213 | |
0316e2c1 | 214 | if (!cmd_directory.length ()) |
215 | { | |
216 | if (chdir((user_directory + user_subdir).c_str ()) < 0) | |
217 | { | |
218 | if (chdir ((sys_directory + sys_subdir).c_str ()) < 0) | |
219 | { | |
220 | std::cerr << "Dirs don't exist! Exiting\n"; | |
221 | std::exit (2); // no execution | |
222 | } | |
223 | } | |
cb21075d | 224 | } |
0316e2c1 | 225 | else |
226 | { | |
227 | if (chdir (cmd_directory.c_str ()) < 0) | |
228 | { | |
229 | std::perror("Error: "); | |
230 | std::cerr << "Exiting...\n"; | |
231 | std::exit (2); | |
232 | } | |
233 | } | |
234 | ||
235 | print_version (); | |
236 | ||
237 | // initialize the Parser | |
238 | Parser::init (); | |
239 | ||
606a8eec | 240 | if (!debug) |
241 | { | |
242 | if (background) | |
243 | switch (fork()) | |
244 | { | |
245 | case -1: | |
246 | std::cout << "Could not run in the background. Exiting...\n"; | |
247 | perror("fork"); | |
248 | exit(1); | |
249 | case 0: | |
0316e2c1 | 250 | break; |
606a8eec | 251 | default: |
252 | std::cout << "Running in the background...\n"; | |
253 | exit(0); | |
254 | } | |
255 | } | |
cb21075d | 256 | |
257 | #ifdef USESCRIPTS | |
0316e2c1 | 258 | Interp::Startup(); |
4da877a5 | 259 | if (debug || script_debug) |
606a8eec | 260 | { |
55a3d3ed | 261 | scm_c_eval_string("(debug-enable 'backtrace)" |
55f2215d | 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 | } |