Fix typo in help output
[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 <iostream>
25 #include <string>
26
27 #include <cstdio>
28 #include <csignal>
29 #include <cstdlib>
30
31 #include <dirent.h>
32 #include <getopt.h>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36
37 #ifdef USESCRIPTS
38 #include "Interp.H"
39 #endif
40
41 #include "Bot.H"
42 #include "Parser.H"
43 #include "UserList.H"
44
45 namespace
46 {
47 Bot *b;
48
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'},
59 #ifdef USESCRIPTS
60 { "debug-scripts", no_argument, 0, 'S' },
61 #endif
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 }
71 }
72
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 }
92
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/default/ 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"
126 #ifdef USESCRIPTS
127 "\n[--debug-scripts][-S] Turns on Guile debugging evaluator"
128 #endif
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 }
136
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;
150 bool script_debug = false;
151
152 std::signal(SIGPIPE, SIG_IGN);
153 std::signal(SIGALRM, SIG_IGN);
154 std::signal(SIGHUP, sig_hup);
155
156 // We parse the command line options
157 while ((opt = getopt_long (argc,argv,"vhbf:d:c:DS", bot_options, 0))
158 != -1)
159 {
160 switch (opt)
161 {
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;
192 case 'S':
193 script_debug = true;
194 break;
195 default:
196 print_short_help (argv[0]);
197 std::exit(1);
198 }
199 }
200
201 DIR * temp;
202
203 if (! (temp = opendir ((String(getenv ("HOME")) + "/.bobotpp/logs").c_str ())))
204 {
205 mkdir ((String(getenv ("HOME")) + "/.bobotpp/logs").c_str (),
206 S_IRWXU);
207 }
208 else
209 {
210 closedir (temp);
211 }
212
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 }
223 }
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
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:
249 break;
250 default:
251 std::cout << "Running in the background...\n";
252 exit(0);
253 }
254 }
255
256 #ifdef USESCRIPTS
257 Interp::Startup();
258 if (debug || script_debug)
259 {
260 scm_c_eval_string("(debug-enable 'backtrace)"
261 "(read-enable 'positions)");
262 }
263 #endif
264 b = new Bot(configFile, debug);
265 b->run();
266 delete b;
267
268 #ifdef USESCRIPTS
269 Interp::Shutdown();
270 #endif
271 }
272
273 } // static functions and data
274
275 int main(int argc, char **argv)
276 {
277 #ifdef USESCRIPTS
278 scm_boot_guile (argc, argv, real_main, 0);
279 #else
280 real_main(0, argc, argv);
281 #endif
282
283 return 0;
284 }