#!/usr/bin/perl # Copyright (C) 2011, Christoph Biedl, #%# license-gplv2+ =head1 NAME ngircd-conf-convert - convert ngircd.conf from pre18 version =head1 VERSION Version 2011.10.30 =cut our $VERSION = '2011.10.30'; =head1 SYNOPSIS convert ngircd.conf from pre18 version Usage: ngircd-conf-convert [options] =cut use 5.010; use strict; use warnings; use Getopt::Long; use Pod::Usage; my $ignorecomments; =head1 OPTIONS =over =cut { my $help; my $man; my %GetOptions = ( 'help|?' => \$help, 'man' => \$man ); =item B<--ignorecomments> By default, this program will rewrite configuration variables even if they are commented out, e.g. ;NoDNS = no to ;DNS = yes Use this option to disable that feature. =cut $GetOptions{'ignorecomments'} = \$ignorecomments; =item F F The old configuration file, and where to write the converted one to. The first one must exist, the content of the latter will be overwritten. If C<-> is given, content is read from stdin or written to stdout, respectively. =back =head1 DESCRIPTION The C converts ngIRCd configuration files according to the new section and variable names introduced in version 18. The changes done are small: Just renamings and adding the appropriate section name. No blocks are moved around, you might want to do that manually. Suggested workflow: ngircd-conf-convert ngircd.conf ngircd.conf.new # compare dumps created by --configtest dump.old dump.new cmp -s dump.old dump.new || echo "ALERT: configuration was changed!" Remember: Your C may contain sensitive data, so don't do that in a world-readable directory. =cut GetOptions (%GetOptions) or pod2usage (2); pod2usage (1) if ($help); pod2usage (-exitstatus => 0, -ignorecomments => 2) if ($man); (scalar (@ARGV) == 2) or die ("Need two file parameters.\n"); } my %convert_logic = ( # variable name => [ , , ] 'allowremoteoper' => [ 'Options' ], 'chrootdir' => [ 'Options' ], 'connectipv4' => [ 'Options' ], 'connectipv6' => [ 'Options' ], 'connectretry' => [ 'Limits' ], 'maxconnections' => [ 'Limits' ], 'maxconnectionsip' => [ 'Limits' ], 'maxjoins' => [ 'Limits' ], 'maxnicklength' => [ 'Limits' ], 'nodns' => [ 'Options', 'DNS', 1 ], 'noident' => [ 'Options', 'Ident', 1 ], 'nopam' => [ 'Options', 'PAM', 1 ], 'opercanusemode' => [ 'Options' ], 'operservermode' => [ 'Options' ], 'pingtimeout' => [ 'Limits' ], 'pongtimeout' => [ 'Limits' ], 'predefchannelsonly' => [ 'Options' ], 'sslcertfile' => [ 'SSL', 'CertFile' ], 'ssldhfile' => [ 'SSL', 'DHFile' ], 'sslkeyfile' => [ 'SSL', 'KeyFile' ], 'sslkeyfilepassword' => [ 'SSL', 'KeyFilePassword' ], 'sslports' => [ 'SSL', 'Ports' ], 'syslogfacility' => [ 'Options' ], 'webircpassword' => [ 'Options' ], ); my $oldvars = join ('|', keys %convert_logic); my ($old_file, $new_file) = @ARGV; my ($old_fh, $new_fh); if ($old_file eq '-') { $old_fh = *STDIN; } else { (-f $old_file) or die ("Not a file: '$old_file'.\n"); open ($old_fh, '<', $old_file) or die ("Canno read '$old_file': $!.\n"); } my $section = ''; # last section read from input my $set_section = ''; # section we're currently in # slurp content my @content = <$old_fh>; ($old_file eq '-') or close ($old_fh); sub insert_line ($$) { # insert content before the given line. If this is a comment, seek # further backwards. my ($before, $content) = @_; while ($before > 0 && $content[--$before] =~ /^\s*#/) { } splice @content, $before+1, 0, $content; } for (my $i = 0; $i < scalar (@content); $i++) { my $line = $content[$i]; if ($line =~ /^\s*\[([a-z]+)\]/i) { $set_section = $section = lc $1; } elsif ($line =~ /^\s*(,|#|$)/) { # nothing to do } elsif ( $section eq 'global' && $line =~ /^(\s*)(;\s*)?($oldvars)(\s*=\s*)(.*?)$/i ) { my ($left, $comment, $var, $middle, $value) = ($1 // '', $2 // '', $3, $4, $5 // ''); my ($new_section, $new_var, $invert) = @{$convert_logic{lc $var}}; $new_var //= $var; ($comment && $ignorecomments) and next; if ($set_section ne $new_section) { # switch section insert_line ($i, "[$new_section]\n"); $i++; $set_section = $new_section; } $invert and ($value = ($value =~ /^(yes|true|[1-9]\d*)\s*$/) ? 'no' : 'yes'); $content[$i] = "$left$comment$new_var$middle$value\n"; } elsif ($set_section ne $section) { # other content, switch back to global if necessary die if ($section ne 'global'); insert_line ($i, "[Global]\n"); $i++; $set_section = $section; } } if ($new_file eq '-') { $new_fh = *STDOUT; } else { open ($new_fh, '>', $new_file) or die ("Canno write '$new_file': $!.\n"); print $new_fh @content; } ($new_file eq '-') or close ($new_fh); exit 0; __END__ =head1 AUTHOR Christoph Biedl, Cdebian.axhn@manchmal.in-ulm.deE> =head1 COPYRIGHT & LICENSE #%# license-gplv2+ =cut # -- ETYKACLGPAK