2 # +------------------------------------+
3 # | Inspire Internet Relay Chat Daemon |
4 # +------------------------------------+
6 # (C) 2002-2007 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");
104 system("$binpath/$executable");
109 # Check to see its not 'running' already.
110 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
112 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
117 # If we are still alive here.. Try starting the IRCd..
118 system("gdb --command=$basepath/.gdbargs --args $binpath/$executable -nofork -debug -nolog");
123 # Check to see its not 'running' already.
124 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
126 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
132 # If we are still alive here.. Try starting the IRCd..
133 print "Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the gdb output and get a backtrace.\n";
134 print "Once you're inside the screen session press ^C + d to re-detach from the session\n";
135 system("screen -m -d gdb --command=$basepath/.gdbargs --args $binpath/$executable -nofork -debug -nolog");
140 # Check to see its not 'running' already.
141 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
143 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
145 # Check we have valgrind and gdb
149 # If we are still alive here.. Try starting the IRCd..
150 # May want to do something with these args at some point: --suppressions=.inspircd.sup --gen-suppressions=yes
151 # Could be useful when we want to stop it complaining about things we're sure aren't issues.
152 system("valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=10 $binpath/$executable -nofork -debug -nolog");
157 # Check to see its not 'running' already.
158 if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
160 print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
167 # If we are still alive here.. Try starting the IRCd..
168 print "Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the valgrind and gdb output and get a backtrace.\n";
169 print "Once you're inside the screen session press ^C + d to re-detach from the session\n";
170 system("screen -m -d valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=10 $binpath/$executable -nofork -debug -nolog");
174 if (getstatus() == 0) { print "InspIRCd is not running. (Or PID File not found)\n"; return 0; }
175 # Get to here, we have something to kill.
176 my $pid = getprocessid();
177 print "Stopping InspIRCd (pid: $pid)...\n";
178 system("kill -TERM $pid >/dev/null 2>&1");
179 # Give it a second to exit
181 if (getstatus() == 1)
183 print "InspIRCd not dying quietly -- forcing kill\n";
184 system("kill -9 $pid >/dev/null 2>&1");
186 print "InspIRCd Stopped.\n";
189 # GetPidfile Version 2 - Now With Include Support..
190 # I beg for months for include support in insp, then..
191 # when it is added, it comes around and BITES ME IN THE ASS,
192 # because i then have to code support into this script.. Evil.
194 # Craig got bitten in the ass again --
195 # in 1.1 beta the include file is manditory, therefore
196 # if we cant find it, default to %conf%/inspircd.pid.
197 # Note, this also contains a fix for when the pid file is
198 # defined, but defined in a comment (line starts with #)
203 # Before we start, do we have a PID already? (Should never occur)
207 # Are We using a relative path?
208 if ($file !~ /^\//) {
209 # Convert it to a full path..
210 $file = $confpath . $file;
213 # Have we checked this file before?
214 for (my $i = 0; $i < $filesparsed; $i++) {
215 if ($filesparsed[$i] eq $file) {
216 # Already Parsed, Possible recursive loop..
221 # If we get here, Mark as 'Read'
222 $filesparsed[$filesparsed] = $file;
225 open INFILE, "< $file" or die "Unable to open file $file\n";
226 # Grab entire file contents..
227 my(@lines) = <INFILE>;
231 # remove trailing spaces
233 foreach $i (@lines) {
235 $i =~ s/[^=]+=\s(.*)/\1/;
236 # Does this file have a pid?
237 if (($i =~ /<pid file=\"(\S+)\">/i) && ($i !~ /^#/))
239 # Set the PID file and return.
245 # If we get here, NO PID FILE! -- Check for includes
246 foreach $i (@lines) {
247 $i =~ s/[^=]+=\s(.*)/\1/;
248 if (($i =~ s/\<include file=\"(.+?)\"\>//i) && ($i !~ /^#/))
250 # Decend into that file, and check for PIDs.. (that sounds like an STD ;/)
253 if ($pidfile ne "") {
260 # End of includes / No includes found. Using default.
261 $pidfile = $confpath . "inspircd.pid";
265 my $pid = getprocessid();
266 if ($pid == 0) { return 0; }
267 $status = system("kill -0 $pid >/dev/null 2>&1") / 256;
268 if ($status == 0) { return 1; }
275 open PIDFILE, "< $pidfile" or return 0;
276 while($i = <PIDFILE>)
286 unless(`valgrind --version`)
288 print "Couldn't start valgrind: $!\n";
295 unless(`gdb --version`)
297 print "Couldn't start gdb: $!\n";
304 unless(`screen --version`)
306 print "Couldn't start screen: $!\n";
313 open(FH, "xmllint|") or die "Couldn't start xmllint: $!\n";
319 validateconf($confpath."inspircd.conf");
320 print "Config check complete\n";
327 # Are We using a relative path?
328 if ($file !~ /^\//) {
329 # Convert it to a full path..
330 $file = $confpath . $file;
333 # Have we checked this file before?
334 for (my $i = 0; $i < $filechecked; $i++) {
335 if ($filechecked[$i] eq $file) {
336 # Already Parsed, Possible recursive loop..
341 # If we get here, Mark as 'Read'
342 $filechecked[$filechecked] = $file;
345 open INFILE, "< $file" or die "Unable to open file $file\n";
346 # Grab entire file contents..
347 my(@lines) = <INFILE>;
351 # remove trailing spaces
358 push @newlines, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
359 # push @newlines, "<!DOCTYPE config SYSTEM \"".$confpath."inspircd.dtd\">";
360 push @newlines, "<config>";
364 # remove trailing newlines
367 # convert tabs to spaces
370 # remove leading spaces
379 # remove trailing comments
382 for (my $j = 0; $j < length($i); $j++)
384 if (substr($i,$j, 1) eq '"') { $quote = ($quote) ? 0 : 1; } elsif (substr($i,$j, 1) eq "#" && !$quote) { last; }
385 $line .= substr($i,$j, 1);
389 # remove trailing spaces
392 # setup incf for include check and clean it up, since this breaks parsing use local var
394 $incf =~ s/[^=]+=\s(.*)/\1/;
397 if (($incf =~ s/\<include file=\"(.+?)\"\>//i) && ($incf !~ /^#/))
403 if ($i =~ /^<.*/ && $conline =~ /^<.*/)
405 push @newlines, $conline;
406 push @newlines, @blanks;
412 $i =~ s/(.*)>$/\1 \/>/;
418 $conline =~ s/(.*)>$/\1 \/>/;
420 push @newlines, $conline;
421 push @newlines, @blanks;
429 elsif ($conline =~ /^<.*/ && $i)
448 push @newlines, $conline;
449 push @newlines, @blanks;
452 push @newlines, "</config>";
458 } until sysopen(TF, $tmpfile, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0700);
460 foreach $n (@newlines)
466 my @result = `xmllint -noout $tmpfile 2>&1`;
477 $n =~ s/$tmpfile\:\d*\: *//g;
478 if ($n =~ /.*config>.*/)
486 if ($n =~ /line \d*/)
489 $lineno =~ s/.*line (\d*).*/\1/;
491 $n =~ s/line (\d*)/line $lineno/;
493 print "$file : $n\n";