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