2005-04-05 21:17:33 +00:00
#!/usr/bin/perl
# +------------------------------------+
# | Inspire Internet Relay Chat Daemon |
# +------------------------------------+
#
2009-01-02 18:16:05 +00:00
# InspIRCd: (C) 2002-2009 InspIRCd Development Team
2009-03-15 12:42:35 +00:00
# See: http://wiki.inspircd.org/Credits
2005-04-05 21:17:33 +00:00
#
# This program is free but copyrighted software; see
2008-10-31 00:11:48 +00:00
# the file COPYING for details.
2005-04-05 21:17:33 +00:00
#
# ---------------------------------------------------
2008-10-31 00:11:48 +00:00
#
2009-01-25 00:21:54 +00:00
use strict ;
2007-02-04 22:52:06 +00:00
use POSIX ;
2009-01-25 00:21:54 +00:00
use Fcntl ;
2005-04-05 21:17:33 +00:00
2006-12-04 17:03:10 +00:00
my $basepath = " @BASE_DIR@ " ;
my $confpath = " @CONFIG_DIR@/ " ;
my $binpath = " @BINARY_DIR@ " ;
my $libpath = " @LIBRARY_DIR@ " ;
2008-10-27 19:08:31 +00:00
my $valgrindlogpath = " $basepath /valgrindlogs " ;
2006-12-04 17:03:10 +00:00
my $executable = " @EXECUTABLE@ " ;
my $version = " @VERSION@ " ;
2005-04-05 21:17:33 +00:00
2009-01-25 00:21:54 +00:00
our ( $pid , $pidfile );
2005-04-05 21:17:33 +00:00
# Lets see what they want to do.. Set the variable (Cause i'm a lazy coder)
2008-12-15 01:06:51 +00:00
my $arg = shift ( @ ARGV );
my $conf = $confpath . " inspircd.conf " ;
for my $a ( @ ARGV )
{
if ( $a =~ m /^-- config = ( .* ) $ / )
{
$conf = $ 1 ;
last ;
}
}
getpidfile ( $conf );
# System for naming script command subs:
# cmd_<name> - Normal command for use by users.
# dev_<name> - Developer commands.
# hid_<name> - Hidden commands (ie Cheese-Sandwich)
# Ideally command subs shouldn't return.
my $subname = $arg ;
$subname =~ s /-/ _ / g ;
my $sub = main -> can ( " cmd_ $subname " ) || main -> can ( " dev_ $subname " ) || main -> can ( " hid_ $subname " );
if ( ! defined ( $sub ))
{
print STDERR " Invalid command or none given. \n " ;
cmd_help ();
exit 1 ;
}
else
{
$sub -> ( @ ARGV );
exit 0 ;
}
sub cmd_help ()
{
2009-01-25 00:21:54 +00:00
my @ subs = grep { $_ =~ m /^ ( cmd | dev ) _ / && defined ( main -> can ( $_ )) } keys ( %:: );
2008-12-15 01:06:51 +00:00
my @ cmds = grep /^ cmd_ / , @ subs ;
my @ devs = grep /^ dev_ / , @ subs ;
local $_ ;
$_ =~ s /^ ( cmd | dev ) _ // foreach (@cmds, @devs);
$_ =~ s / _ /-/ g foreach ( @ cmds , @ devs );
print STDERR " Usage: ./inspircd ( " . join ( " | " , @ cmds ) . " ) \n " ;
print STDERR " Developer arguments: ( " . join ( " | " , @ devs ) . " ) \n " ;
exit 0 ;
}
sub cmd_status ()
{
2007-02-04 22:52:06 +00:00
if ( getstatus () == 1 ) {
2005-04-05 21:17:33 +00:00
my $pid = getprocessid ();
print " InspIRCd is running (PID: $pid ) \n " ;
exit ();
} else {
print " InspIRCd is not running. (Or PID File not found) \n " ;
exit ();
}
}
2008-12-15 01:06:51 +00:00
sub cmd_rehash ()
{
2005-04-05 21:17:33 +00:00
if ( getstatus () == 1 ) {
my $pid = getprocessid ();
2007-02-04 22:52:06 +00:00
system ( " kill -HUP $pid >/dev/null 2>&1 " );
2006-12-24 13:38:32 +00:00
print " InspIRCd rehashed (pid: $pid ). \n " ;
2005-04-05 21:17:33 +00:00
exit ();
} else {
print " InspIRCd is not running. (Or PID File not found) \n " ;
exit ();
}
}
2008-12-15 01:06:51 +00:00
sub cmd_cron ()
{
if ( getstatus () == 0 ) { goto & cmd_start (); }
2005-04-05 21:24:01 +00:00
exit ();
2005-04-05 21:17:33 +00:00
}
2008-12-15 01:06:51 +00:00
sub cmd_version ()
{
2006-12-04 17:03:10 +00:00
print " InspIRCd version: $version\n " ;
exit ();
}
2008-12-15 01:06:51 +00:00
sub cmd_restart ( @ )
{
cmd_stop ();
2006-06-22 10:26:33 +00:00
unlink ( $pidfile ) if ( - e $pidfile );
2008-12-15 01:06:51 +00:00
goto & cmd_start ;
2005-04-05 21:17:33 +00:00
}
2008-12-15 01:06:51 +00:00
sub hid_cheese_sandwich ()
{
2005-04-05 21:17:33 +00:00
print " Creating Cheese Sandwich.. \n " ;
print " Done. \n " ;
exit ();
}
2008-12-15 01:06:51 +00:00
sub cmd_start ( @ )
{
2007-02-04 22:52:06 +00:00
# Check to see its not 'running' already.
if ( getstatus () == 1 ) { print " InspIRCd is already running. \n " ; return 0 ; }
# If we are still alive here.. Try starting the IRCd..
2006-08-12 13:43:42 +00:00
print " $binpath / $executable doesn't exist \n " and return 0 unless ( - e " $binpath / $executable " );
2008-10-23 14:45:58 +00:00
print " $binpath / $executable is not executable \n " and return 0 unless ( - f " $binpath / $executable " && - x " $binpath / $executable " );
2006-08-12 13:43:42 +00:00
2008-12-15 01:06:51 +00:00
exec { " $binpath / $executable " } " $binpath / $executable " , @ _ ;
die " Failed to start IRCd: $ ! \n " ;
2005-04-05 21:17:33 +00:00
}
2008-12-15 01:06:51 +00:00
sub dev_debug ( @ )
{
2006-05-07 10:10:53 +00:00
# Check to see its not 'running' already.
if ( getstatus () == 1 ) { print " InspIRCd is already running. \n " ; return 0 ; }
2007-02-04 22:52:06 +00:00
2006-08-12 13:43:42 +00:00
print " $binpath / $executable doesn't exist \n " and return 0 unless ( - e " $binpath / $executable " );
2008-10-23 14:45:58 +00:00
print " $binpath / $executable is not executable \n " and return 0 unless ( - f " $binpath / $executable " && - x " $binpath / $executable " );
2007-02-04 22:52:06 +00:00
2006-05-07 10:10:53 +00:00
# Check we have gdb
checkgdb ();
2007-02-04 22:52:06 +00:00
2006-05-07 10:10:53 +00:00
# If we are still alive here.. Try starting the IRCd..
2009-01-25 00:21:54 +00:00
exec 'gdb' , " --command= $basepath /.gdbargs " , '--args' , " $binpath / $executable " , qw ( - nofork - debug ), @ _ ;
2008-12-15 01:06:51 +00:00
die " Failed to start GDB: $ ! \n " ;
2005-04-21 13:22:15 +00:00
}
2008-12-15 01:06:51 +00:00
sub dev_screendebug ( @ )
2006-05-07 10:10:53 +00:00
{
# Check to see its not 'running' already.
if ( getstatus () == 1 ) { print " InspIRCd is already running. \n " ; return 0 ; }
2007-02-04 22:52:06 +00:00
2006-08-12 13:43:42 +00:00
print " $binpath / $executable doesn't exist \n " and return 0 unless ( - e " $binpath / $executable " );
2006-05-07 10:10:53 +00:00
#Check we have gdb
checkgdb ();
checkscreen ();
2007-02-04 22:52:06 +00:00
2006-05-07 10:10:53 +00:00
# If we are still alive here.. Try starting the IRCd..
print " Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the gdb output and get a backtrace. \n " ;
print " Once you're inside the screen session press ^C + d to re-detach from the session \n " ;
2009-01-25 00:21:54 +00:00
exec qw ( screen - m - d gdb ), " --comand= $basepath /.gdbargs " , '-args' , " $binpath / $executable " , qw ( - nofork - debug - nolog ), @ _ ;
2008-12-15 01:06:51 +00:00
die " Failed to start screen: $ ! \n " ;
2006-05-07 10:10:53 +00:00
}
2008-12-15 01:06:51 +00:00
sub dev_valdebug ( @ )
2006-05-07 10:10:53 +00:00
{
# Check to see its not 'running' already.
if ( getstatus () == 1 ) { print " InspIRCd is already running. \n " ; return 0 ; }
2006-08-12 13:43:42 +00:00
print " $binpath / $executable doesn't exist \n " and return 0 unless ( - e " $binpath / $executable " );
2008-10-23 14:45:58 +00:00
print " $binpath / $executable is not executable \n " and return 0 unless ( - f " $binpath / $executable " && - x " $binpath / $executable " );
2006-08-12 13:43:42 +00:00
2006-05-07 10:10:53 +00:00
# Check we have valgrind and gdb
checkvalgrind ();
checkgdb ();
2007-02-04 22:52:06 +00:00
2006-05-07 10:10:53 +00:00
# If we are still alive here.. Try starting the IRCd..
# May want to do something with these args at some point: --suppressions=.inspircd.sup --gen-suppressions=yes
# Could be useful when we want to stop it complaining about things we're sure aren't issues.
2009-01-25 00:21:54 +00:00
exec qw ( valgrind - v -- tool = memcheck -- leak - check = yes -- db - attach = yes -- num - callers = 10 ), " $binpath / $executable " , qw ( - nofork - debug - nolog ), @ _ ;
2008-12-15 01:06:51 +00:00
die " Failed to start valgrind: $ ! \n " ;
2006-05-07 10:10:53 +00:00
}
2008-12-15 01:06:51 +00:00
sub dev_valdebug_unattended ( @ )
2008-10-27 19:08:31 +00:00
{
# NOTE: To make sure valgrind generates coredumps, set soft core limit in /etc/security/limits.conf to unlimited
# Check to see its not 'running' already.
if ( getstatus () == 1 ) { print " InspIRCd is already running. \n " ; return 0 ; }
2008-12-05 14:33:07 +00:00
2008-10-27 19:08:31 +00:00
print " $binpath / $executable doesn't exist \n " and return 0 unless ( - e " $binpath / $executable " );
print " $binpath / $executable is not executable \n " and return 0 unless ( - f " $binpath / $executable " && - x " $binpath / $executable " );
2008-12-05 14:33:07 +00:00
2008-10-27 19:08:31 +00:00
# Check we have valgrind and gdb
checkvalgrind ();
checkgdb ();
2008-12-05 14:33:07 +00:00
2008-10-27 19:08:31 +00:00
# If we are still alive here.. Try starting the IRCd..
#
# NOTE: Saving the debug log (redirected stdout), while useful, is a potential security risk AND one hell of a spacehog. DO NOT SAVE THIS WHERE EVERYONE HAS ACCESS!
# Redirect stdout to /dev/null if you're worried about the security.
#
2008-10-27 20:15:53 +00:00
my $pid = fork ;
if ( $pid == 0 ) {
POSIX :: setsid ();
2008-12-05 21:01:31 +00:00
- d $valgrindlogpath or mkdir $valgrindlogpath or die " Cannot create $valgrindlogpath : $ ! \n " ;
2009-06-14 21:12:16 +00:00
- e " $binpath /valgrind.sup " or do { open my $f , '>' , " $binpath /valgrind.sup " ; };
2008-12-05 21:01:31 +00:00
my $suffix = strftime ( " %Y%m%d-%H%M%S " , localtime ( time )) . " . $ $ " ;
open STDIN , '<' , '/dev/null' or die " Can't redirect STDIN to /dev/null: $ ! \n " ;
sysopen STDOUT , " $valgrindlogpath /out. $suffix " , O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND , 0600 or die " Can't open $valgrindlogpath /out. $suffix : $ ! \n " ;
sysopen STDERR , " $valgrindlogpath /valdebug. $suffix " , O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND , 0666 or die " Can't open $valgrindlogpath /valdebug. $suffix : $ ! \n " ;
2009-06-14 21:12:16 +00:00
# May want to do something with these args at some point: --suppressions=.inspircd.sup --gen-suppressions=yes
# Could be useful when we want to stop it complaining about things we're sure aren't issues.
exec qw ( valgrind - v -- tool = memcheck -- leak - check = full -- show - reachable = yes -- num - callers = 15 -- track - fds = yes ),
" --suppressions= $binpath /valgrind.sup " , qw ( -- gen - suppressions = all ),
qw ( -- leak - resolution = med -- time - stamp = yes -- log - fd = 2 -- ),
" $binpath / $executable " , qw ( - nofork - debug - nolog ), @ _ ;
2008-12-05 21:01:31 +00:00
die " Can't execute valgrind: $ ! \n " ;
2008-10-27 20:15:53 +00:00
}
2008-10-27 19:08:31 +00:00
}
2008-12-15 01:06:51 +00:00
sub dev_screenvaldebug ( @ )
2006-05-07 10:10:53 +00:00
{
# Check to see its not 'running' already.
if ( getstatus () == 1 ) { print " InspIRCd is already running. \n " ; return 0 ; }
2007-02-04 22:52:06 +00:00
2006-08-12 13:43:42 +00:00
print " $binpath / $executable doesn't exist \n " and return 0 unless ( - e " $binpath / $executable " );
2008-10-23 14:45:58 +00:00
print " $binpath / $executable is not executable \n " and return 0 unless ( - f " $binpath / $executable " && - x " $binpath / $executable " );
2006-08-12 13:43:42 +00:00
2006-05-07 10:10:53 +00:00
#Check we have gdb
checkvalgrind ();
checkgdb ();
checkscreen ();
2007-02-04 22:52:06 +00:00
2006-05-07 10:10:53 +00:00
# If we are still alive here.. Try starting the IRCd..
print " Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the valgrind and gdb output and get a backtrace. \n " ;
print " Once you're inside the screen session press ^C + d to re-detach from the session \n " ;
2009-01-25 00:21:54 +00:00
exec qw ( screen - m - d valgrind - v -- tool = memcheck -- leak - check = yes -- db - attach = yes -- num - callers = 10 ), " $binpath / $executable " , qw ( - nofork - debug - nolog ), @ _ ;
2008-12-15 01:06:51 +00:00
die " Failed to start screen: $ ! \n " ;
2006-05-07 10:10:53 +00:00
}
2005-04-21 13:22:15 +00:00
2008-12-15 01:06:51 +00:00
sub cmd_stop ()
{
2007-02-04 22:52:06 +00:00
if ( getstatus () == 0 ) { print " InspIRCd is not running. (Or PID File not found) \n " ; return 0 ; }
# Get to here, we have something to kill.
my $pid = getprocessid ();
2006-12-24 13:38:32 +00:00
print " Stopping InspIRCd (pid: $pid )... \n " ;
2009-06-14 21:12:16 +00:00
my $maxwait = ( `ps -o command $pid` =~ / valgrind / i ) ? 90 : 5 ;
2008-12-15 01:06:51 +00:00
kill TERM => $pid or die " Cannot terminate IRCd: $ ! \n " ;
2008-10-28 18:29:40 +00:00
for ( 1. . $maxwait ) {
sleep 1 ;
2009-01-15 19:32:45 +00:00
if ( getstatus () == 0 ) {
2008-10-28 18:29:40 +00:00
print " InspIRCd Stopped. \n " ;
return ;
}
2005-04-08 23:03:18 +00:00
}
2008-10-28 18:29:40 +00:00
print " InspIRCd not dying quietly -- forcing kill \n " ;
kill KILL => $pid ;
2009-02-09 19:55:56 +00:00
return 0 ;
2005-04-05 21:17:33 +00:00
}
2008-12-15 01:06:51 +00:00
###
# Generic Helper Functions.
###
2005-05-29 22:07:33 +00:00
# GetPidfile Version 2 - Now With Include Support..
2007-02-04 22:52:06 +00:00
# I beg for months for include support in insp, then..
2005-05-29 22:07:33 +00:00
# when it is added, it comes around and BITES ME IN THE ASS,
# because i then have to code support into this script.. Evil.
2005-04-05 21:17:33 +00:00
2006-12-24 13:38:32 +00:00
# Craig got bitten in the ass again --
# in 1.1 beta the include file is manditory, therefore
# if we cant find it, default to %conf%/inspircd.pid.
# Note, this also contains a fix for when the pid file is
# defined, but defined in a comment (line starts with #)
# -- Brain
2009-01-25 00:21:54 +00:00
my % filesparsed ;
2008-12-15 01:06:51 +00:00
sub getpidfile
{
2008-12-05 14:33:07 +00:00
my ( $file ) = @ _ ;
# Before we start, do we have a PID already? (Should never occur)
if ( $pid ne " " ) {
return ;
}
# Are We using a relative path?
if ( $file !~ /^ \ //) {
# Convert it to a full path.
$file = $confpath . $file ;
}
# Have we checked this file before?
2009-01-25 00:21:54 +00:00
return if $filesparsed { $file };
$filesparsed { $file } = 1 ;
2008-12-05 14:33:07 +00:00
# Open the File..
2008-12-22 15:05:01 +00:00
open INFILE , " < $file " or die " Unable to open file $file included in configuration \n " ;
2008-12-05 14:33:07 +00:00
# Grab entire file contents..
my ( @ lines ) = < INFILE > ;
# Close the file
close INFILE ;
# remove trailing spaces
chomp ( @ lines );
2009-01-25 00:21:54 +00:00
for my $i ( @ lines ) {
2008-12-05 14:33:07 +00:00
# clean it up
$i =~ s / [ ^= ] += \s ( .* ) / \1 / ;
# Does this file have a pid?
if (( $i =~ /< pid file = \ " ( \ S+) \" >/i) && ( $i !~ /^#/))
{
# Set the PID file and return.
$pidfile = $ 1 ;
return ;
}
}
# If we get here, NO PID FILE! -- Check for includes
2009-01-25 00:21:54 +00:00
for my $i ( @ lines ) {
2008-12-05 14:33:07 +00:00
$i =~ s / [ ^= ] += \s ( .* ) / \1 / ;
if (( $i =~ s / \ < include file = \ " (.+?) \" \ >//i) && ( $i !~ /^#/))
{
# Decend into that file, and check for PIDs.. (that sounds like an STD ;/)
getpidfile ( $ 1 );
# Was a PID found?
if ( $pidfile ne " " ) {
# Yes, Return.
return ;
}
}
}
# End of includes / No includes found. Using default.
$pidfile = $confpath . " inspircd.pid " ;
2005-04-05 21:17:33 +00:00
}
sub getstatus {
2007-02-04 22:52:06 +00:00
my $pid = getprocessid ();
2008-10-28 18:29:40 +00:00
return 0 if $pid == 0 ;
return kill 0 , $pid ;
2005-04-05 21:17:33 +00:00
}
sub getprocessid {
my $pid ;
2005-04-05 21:21:04 +00:00
open PIDFILE , " < $pidfile " or return 0 ;
2009-01-25 00:21:54 +00:00
while ( < PIDFILE > )
2005-04-05 21:17:33 +00:00
{
2009-01-25 00:21:54 +00:00
$pid = $_ ;
2005-04-05 21:17:33 +00:00
}
close PIDFILE ;
return $pid ;
}
2006-05-07 10:10:53 +00:00
sub checkvalgrind
{
unless ( `valgrind --version` )
{
print " Couldn't start valgrind: $ ! \n " ;
exit ;
}
}
sub checkgdb
{
unless ( `gdb --version` )
{
print " Couldn't start gdb: $ ! \n " ;
exit ;
}
}
sub checkscreen
{
unless ( `screen --version` )
{
print " Couldn't start screen: $ ! \n " ;
exit ;
}
}
2007-02-04 22:52:06 +00:00
sub checkxmllint
{
open ( FH , " xmllint| " ) or die " Couldn't start xmllint: $ ! \n " ;
}
2008-12-15 01:06:51 +00:00
sub cmd_checkconf ()
2007-02-04 22:52:06 +00:00
{
checkxmllint ();
2008-12-15 01:06:51 +00:00
validateconf ( $conf );
2007-02-04 22:52:06 +00:00
print " Config check complete \n " ;
2008-12-15 01:06:51 +00:00
exit 0 ;
2007-02-04 22:52:06 +00:00
}
2009-01-25 00:21:54 +00:00
my % filechecked ;
2007-02-04 22:52:06 +00:00
sub validateconf
{
my ( $file ) = @ _ ;
# Are We using a relative path?
if ( $file !~ /^ \ //) {
# Convert it to a full path..
$file = $confpath . $file ;
}
# Have we checked this file before?
2009-01-25 00:21:54 +00:00
return if $filechecked { $file };
$filechecked { $file } = 1 ;
2007-02-04 22:52:06 +00:00
# Open the File..
open INFILE , " < $file " or die " Unable to open file $file\n " ;
# Grab entire file contents..
my ( @ lines ) = < INFILE > ;
# Close the file
close INFILE ;
# remove trailing spaces
chomp ( @ lines );
my @ newlines = ();
my @ blanks = ();
my $conline ;
push @ newlines , " <?xml version= \" 1.0 \" encoding= \" ISO-8859-1 \" ?> " ;
# push @newlines, "<!DOCTYPE config SYSTEM \"".$confpath."inspircd.dtd\">";
push @ newlines , " <config> " ;
2009-01-25 00:21:54 +00:00
for my $i ( @ lines )
2007-02-05 18:26:59 +00:00
{
2007-02-04 22:52:06 +00:00
# remove trailing newlines
chomp ( $i );
# convert tabs to spaces
$i =~ s / \t / / g ;
# remove leading spaces
$i =~ s /^ *// ;
# remove comments
$i =~ s /^ #.*//;
# remove trailing #s
$i =~ s / ( .* ) #$/\1/;
2007-02-05 18:26:59 +00:00
# remove trailing comments
my $line = " " ;
my $quote = 0 ;
for ( my $j = 0 ; $j < length ( $i ); $j ++ )
{
if ( substr ( $i , $j , 1 ) eq '"' ) { $quote = ( $quote ) ? 0 : 1 ; } elsif ( substr ( $i , $j , 1 ) eq " # " && ! $quote ) { last ; }
$line .= substr ( $i , $j , 1 );
}
$i = $line ;
2007-02-04 22:52:06 +00:00
# remove trailing spaces
$i =~ s / * $ //;
2007-02-10 21:26:32 +00:00
# setup incf for include check and clean it up, since this breaks parsing use local var
my $incf = $i ;
$incf =~ s / [ ^= ] += \s ( .* ) / \1 / ;
2007-02-04 22:52:06 +00:00
# include file?
2007-02-10 21:26:32 +00:00
if (( $incf =~ s / \ < include file = \ " (.+?) \" \ >//i) && ( $incf !~ /^#/))
2007-02-04 22:52:06 +00:00
{
# yes, process it
validateconf ( $ 1 );
}
if ( $i =~ /^<.*/ && $conline =~ /^<.*/ )
{
push @ newlines , $conline ;
push @ newlines , @ blanks ;
$conline = $i ;
}
if ( $i =~ /^<.*> $ / )
{
$i =~ s / ( .* ) > $ / \1 \ />/ ;
push @ newlines , $i ;
}
elsif ( $i =~ /.*> $ / )
{
$conline .= " $i " ;
$conline =~ s / ( .* ) > $ / \1 \ />/ ;
push @ blanks , " " ;
push @ newlines , $conline ;
push @ newlines , @ blanks ;
$conline = " " ;
undef @ blanks ;
}
elsif ( $i =~ /^<.*/ )
{
$conline = $i ;
}
elsif ( $conline =~ /^<.*/ && $i )
{
$conline .= " $i " ;
push @ blanks , " " ;
}
else
{
if ( $conline )
{
push @ blanks , $i ;
}
else
{
push @ newlines , $i ;
}
}
}
if ( $conline )
{
push @ newlines , $conline ;
push @ newlines , @ blanks ;
}
push @ newlines , " </config> " ;
my $tmpfile ;
do
{
$tmpfile = tmpnam ();
} until sysopen ( TF , $tmpfile , O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW , 0700 );
2009-01-25 00:21:54 +00:00
for my $n ( @ newlines )
2007-02-04 22:52:06 +00:00
{
print TF " $n\n " ;
}
close TF ;
my @ result = `xmllint -noout $tmpfile 2>&1` ;
chomp ( @ result );
my $skip = 0 ;
2009-01-25 00:21:54 +00:00
for my $n ( @ result )
2007-02-04 22:52:06 +00:00
{
if ( $skip )
{
$skip = 0 ;
next ;
}
$n =~ s / $tmpfile\ : \d * \ : *// g ;
if ( $n =~ /.* config >.*/ )
{
$n = " " ;
$skip = 1 ;
}
if ( $n && ! $skip )
{
if ( $n =~ / line \d */ )
{
my $lineno = $n ;
$lineno =~ s /.* line ( \d * ) .*/ \1 / ;
$lineno = $lineno - 2 ;
$n =~ s / line ( \d * ) / line $lineno / ;
}
print " $file : $n\n " ;
}
}
unlink ( $tmpfile );
}