2 # +------------------------------------+
3 # | Inspire Internet Relay Chat Daemon |
4 # +------------------------------------+
6 # (C) 2002-2008 InspIRCd Development Team
7 # http://www.inspircd.org/wiki/index.php/Credits
9 # Written by Craig Edwards, Craig McLure, and others.
10 # This program is free but copyrighted software; see
11 # the file COPYING for details.
13 # ---------------------------------------------------
16 my $basepath = "@BASE_DIR@";
17 my $confpath = "@CONFIG_DIR@/";
18 my $binpath = "@BINARY_DIR@";
19 my $libpath = "@LIBRARY_DIR@";
20 my $executable = "@EXECUTABLE@";
21 my $version = "@VERSION@";
25 # Lets see what they want to do.. Set the variable (Cause i'm a lazy coder)
27 getpidfile($confpath."inspircd.conf");
29 if ($arg eq "start") { start(); exit(); }
30 if ($arg eq "debug") { debug(); exit(); }
31 if ($arg eq "screendebug") { screendebug(); exit() }
32 if ($arg eq "valdebug") { valdebug(); exit(); }
33 if ($arg eq "screenvaldebug") { screenvaldebug(); exit(); }
34 if ($arg eq "stop") { stop(); exit(); }
35 if ($arg eq "status") {
36 if (getstatus() == 1) {
37 my $pid = getprocessid();
38 print "InspIRCd is running (PID: $pid)\n";
41 print "InspIRCd is not running. (Or PID File not found)\n";
45 if ($arg eq "rehash") {
46 if (getstatus() == 1) {
47 my $pid = getprocessid();
48 system("kill -HUP $pid >/dev/null 2>&1");
49 print "InspIRCd rehashed (pid: $pid).\n";
52 print "InspIRCd is not running. (Or PID File not found)\n";
58 if (getstatus() == 0) { start(); }
62 if ($arg eq "version") {
63 print "InspIRCd version: $version\n";
67 if ($arg eq "restart") {
69 unlink($pidfile) if (-e $pidfile);
75 if ($arg eq "checkconf") {
80 if ($arg eq "Cheese-Sandwich") {
81 print "Creating Cheese Sandwich..\n";
87 # If we get here.. bad / no parameters.
89 print "Invalid Argument: $arg\n";
90 print "Usage: inspircd (start|stop|restart|rehash|status|cron|checkconf|version)\n";
91 print "Developer arguments: (debug|screendebug|valdebug|screenvaldebug)\n";
95 # Generic Helper Functions.
99 # Check to see its not 'running' already.
100 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
101 # If we are still alive here.. Try starting the IRCd..
102 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
103 print "$binpath/$executable is not executable\n" and return 0 unless(-f "$binpath/$executable" && -x "$binpath/$executable");
105 system("$binpath/$executable");
110 # Check to see its not 'running' already.
111 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
113 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
114 print "$binpath/$executable is not executable\n" and return 0 unless(-f "$binpath/$executable" && -x "$binpath/$executable");
119 # If we are still alive here.. Try starting the IRCd..
120 system("gdb --command=$basepath/.gdbargs --args $binpath/$executable -nofork -debug");
125 # Check to see its not 'running' already.
126 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
128 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
134 # If we are still alive here.. Try starting the IRCd..
135 print "Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the gdb output and get a backtrace.\n";
136 print "Once you're inside the screen session press ^C + d to re-detach from the session\n";
137 system("screen -m -d gdb --command=$basepath/.gdbargs --args $binpath/$executable -nofork -debug -nolog");
142 # Check to see its not 'running' already.
143 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
145 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
146 print "$binpath/$executable is not executable\n" and return 0 unless(-f "$binpath/$executable" && -x "$binpath/$executable");
148 # Check we have valgrind and gdb
152 # If we are still alive here.. Try starting the IRCd..
153 # May want to do something with these args at some point: --suppressions=.inspircd.sup --gen-suppressions=yes
154 # Could be useful when we want to stop it complaining about things we're sure aren't issues.
155 system("valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=10 $binpath/$executable -nofork -debug -nolog");
160 # Check to see its not 'running' already.
161 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
163 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
164 print "$binpath/$executable is not executable\n" and return 0 unless(-f "$binpath/$executable" && -x "$binpath/$executable");
171 # If we are still alive here.. Try starting the IRCd..
172 print "Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the valgrind and gdb output and get a backtrace.\n";
173 print "Once you're inside the screen session press ^C + d to re-detach from the session\n";
174 system("screen -m -d valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=10 $binpath/$executable -nofork -debug -nolog");
178 if (getstatus() == 0) { print "InspIRCd is not running. (Or PID File not found)\n"; return 0; }
179 # Get to here, we have something to kill.
180 my $pid = getprocessid();
181 print "Stopping InspIRCd (pid: $pid)...\n";
182 system("kill -TERM $pid >/dev/null 2>&1");
183 # Give it a second to exit
185 if (getstatus() == 1)
187 print "InspIRCd not dying quietly -- forcing kill\n";
188 system("kill -9 $pid >/dev/null 2>&1");
190 print "InspIRCd Stopped.\n";
193 # GetPidfile Version 2 - Now With Include Support..
194 # I beg for months for include support in insp, then..
195 # when it is added, it comes around and BITES ME IN THE ASS,
196 # because i then have to code support into this script.. Evil.
198 # Craig got bitten in the ass again --
199 # in 1.1 beta the include file is manditory, therefore
200 # if we cant find it, default to %conf%/inspircd.pid.
201 # Note, this also contains a fix for when the pid file is
202 # defined, but defined in a comment (line starts with #)
207 # Before we start, do we have a PID already? (Should never occur)
211 # Are We using a relative path?
212 if ($file !~ /^\//) {
213 # Convert it to a full path..
214 $file = $confpath . $file;
217 # Have we checked this file before?
218 for (my $i = 0; $i < $filesparsed; $i++) {
219 if ($filesparsed[$i] eq $file) {
220 # Already Parsed, Possible recursive loop..
225 # If we get here, Mark as 'Read'
226 $filesparsed[$filesparsed] = $file;
229 open INFILE, "< $file" or die "Unable to open file $file\n";
230 # Grab entire file contents..
231 my(@lines) = <INFILE>;
235 # remove trailing spaces
237 foreach $i (@lines) {
239 $i =~ s/[^=]+=\s(.*)/\1/;
240 # Does this file have a pid?
241 if (($i =~ /<pid file=\"(\S+)\">/i) && ($i !~ /^#/))
243 # Set the PID file and return.
249 # If we get here, NO PID FILE! -- Check for includes
250 foreach $i (@lines) {
251 $i =~ s/[^=]+=\s(.*)/\1/;
252 if (($i =~ s/\<include file=\"(.+?)\"\>//i) && ($i !~ /^#/))
254 # Decend into that file, and check for PIDs.. (that sounds like an STD ;/)
257 if ($pidfile ne "") {
264 # End of includes / No includes found. Using default.
265 $pidfile = $confpath . "inspircd.pid";
269 my $pid = getprocessid();
270 if ($pid == 0) { return 0; }
271 $status = system("kill -0 $pid >/dev/null 2>&1") / 256;
272 if ($status == 0) { return 1; }
279 open PIDFILE, "< $pidfile" or return 0;
280 while($i = <PIDFILE>)
290 unless(`valgrind --version`)
292 print "Couldn't start valgrind: $!\n";
299 unless(`gdb --version`)
301 print "Couldn't start gdb: $!\n";
308 unless(`screen --version`)
310 print "Couldn't start screen: $!\n";
317 open(FH, "xmllint|") or die "Couldn't start xmllint: $!\n";
323 validateconf($confpath."inspircd.conf");
324 print "Config check complete\n";
331 # Are We using a relative path?
332 if ($file !~ /^\//) {
333 # Convert it to a full path..
334 $file = $confpath . $file;
337 # Have we checked this file before?
338 for (my $i = 0; $i < $filechecked; $i++) {
339 if ($filechecked[$i] eq $file) {
340 # Already Parsed, Possible recursive loop..
345 # If we get here, Mark as 'Read'
346 $filechecked[$filechecked] = $file;
349 open INFILE, "< $file" or die "Unable to open file $file\n";
350 # Grab entire file contents..
351 my(@lines) = <INFILE>;
355 # remove trailing spaces
362 push @newlines, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
363 # push @newlines, "<!DOCTYPE config SYSTEM \"".$confpath."inspircd.dtd\">";
364 push @newlines, "<config>";
368 # remove trailing newlines
371 # convert tabs to spaces
374 # remove leading spaces
383 # remove trailing comments
386 for (my $j = 0; $j < length($i); $j++)
388 if (substr($i,$j, 1) eq '"') { $quote = ($quote) ? 0 : 1; } elsif (substr($i,$j, 1) eq "#" && !$quote) { last; }
389 $line .= substr($i,$j, 1);
393 # remove trailing spaces
396 # setup incf for include check and clean it up, since this breaks parsing use local var
398 $incf =~ s/[^=]+=\s(.*)/\1/;
401 if (($incf =~ s/\<include file=\"(.+?)\"\>//i) && ($incf !~ /^#/))
407 if ($i =~ /^<.*/ && $conline =~ /^<.*/)
409 push @newlines, $conline;
410 push @newlines, @blanks;
416 $i =~ s/(.*)>$/\1 \/>/;
422 $conline =~ s/(.*)>$/\1 \/>/;
424 push @newlines, $conline;
425 push @newlines, @blanks;
433 elsif ($conline =~ /^<.*/ && $i)
452 push @newlines, $conline;
453 push @newlines, @blanks;
456 push @newlines, "</config>";
462 } until sysopen(TF, $tmpfile, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0700);
464 foreach $n (@newlines)
470 my @result = `xmllint -noout $tmpfile 2>&1`;
481 $n =~ s/$tmpfile\:\d*\: *//g;
482 if ($n =~ /.*config>.*/)
490 if ($n =~ /line \d*/)
493 $lineno =~ s/.*line (\d*).*/\1/;
495 $n =~ s/line (\d*)/line $lineno/;
497 print "$file : $n\n";