#!/usr/bin/perl -w
#
# apache2cherokee.pl
# Converts apache virtual host files to cherokee vservers
# 2009, Ivan Chavero <ichavero@chavero.com.mx>
# v. 0.01

=pod

=head1 NAME

apache2cherokee.pl  - Converts Apache Virtual Host files to Cherokee virtual hosts

=head1 SYNOPSIS

     Usage: 

    ./apache2cherokee.pl <apche virtual host file> [<cherokee virtual host max id>]

The max id argument is optional, if not present the program will guess the max id from the
cherokee.conf file

Currently this program only manages this basic directives:

DirectoryIndex

DocumentRoot

ServerName

CustomLog

ErrorLog

=head1 TODO:

Add more apache directives

=head1 AUTHOR

Ivan Chavero <ichavero@chavero.com.mx>

=cut

use strict;

my $CHEROKEE_CONF = "/etc/cherokee/cherokee.conf";
my $CHEROKEE_CONF_TEMPLATE = "cherokee_vserver.tpl";
my $CHEROKEE_VHOST_PATH = "/etc/cherokee/vhosts/";
my $APACHE = "";

if($#ARGV < 0){
	print "Usage: $0 <apache virtual host file> <cherokee vhost max id>\n";
	exit;
}
else {
	$APACHE = $ARGV[0];
}

my $max_id = 10;
if($#ARGV == 0){
	$max_id = GetCherokeeMaxId($CHEROKEE_CONF);

}
else {
	$max_id = $ARGV[1];
}


my @virtual_hosts = GetVirtualHosts($APACHE);
my @cherokee_conf_template = GetFile($CHEROKEE_CONF_TEMPLATE);
print "MAX ID: $max_id\n";
my $vhost_conf;
foreach my $vhost (@virtual_hosts){
	$max_id++;
	my ($vhost_conf, $vhost_file) = SetVhost($vhost, $max_id, @cherokee_conf_template);
	print "Backing up $CHEROKEE_CONF to $CHEROKEE_CONF.bak\n";
	print `cp $CHEROKEE_CONF $CHEROKEE_CONF.bak`;
	SaveVhostInCherokeeConf($CHEROKEE_CONF, $vhost_conf);
}


sub SaveVhostInCherokeeConf {
	my $file = shift;
	my $conf = shift;
	open(CONF, ">>$file") || die "Can't open $file $!\n";
	print CONF "\n$conf\n";
	close(CONF);
}


sub SaveVhost {
	my $file = shift;
	my $conf = shift;
	open(CONF, ">$file") || die "Can't open $file $!\n";
	print CONF $conf;
	close(CONF);
}

sub SetVhost {
	my $vhost = shift;
	my $max_id = shift;
	my @tpl = @_;
	my $str_tpl = "";
	my $nick = $vhost->{ServerName} ne "" ? $vhost->{ServerName} : "vhost_$max_id"; 
	$nick =~ s/(.+)\..*\..*/$1/g;
	print "Generating vhost $nick\n";
	my %template_labels = (id => $max_id,  directory_index => 'index.html,index.htm,index.php',
				document_root => '/var/www/localhost/htdocs', domain => '',
				access_log => '/var/log/cherokee.access', error_log => '/var/log/cherokee.error',
				nick => $nick); 
	my %labels_directive = (id => 'id', directory_index => 'DirectoryIndex',
				document_root => 'DocumentRoot', domain => 'ServerName', domain2 => 'ServerAlias',
				access_log => 'CustomLog', error_log => 'ErrorLog', nick => 'nick');

	foreach my $line (@tpl){
		$str_tpl .= $line;
	}

	foreach my $label (keys %template_labels){
		my $value = defined($vhost->{$labels_directive{$label}}) ? 
				$vhost->{$labels_directive{$label}} : "NOVAL";
		$str_tpl = SetCherokeeDirective($str_tpl, $label, $value,
						$template_labels{$label});
	}
	my $cherokee_vhost_file = $vhost->{ServerName}.".vhost";
	print "Generating $cherokee_vhost_file...\n";
	print "\n"."-"x80;
	print "\n$str_tpl\n";
	print "-"x80;
	print "\n";
	return($str_tpl, $cherokee_vhost_file);
}

sub SetCherokeeDirective {
	my $str_tpl = shift;
	my $label = shift;
	my $value = shift;
	my $default = shift;
	if($value ne "NOVAL"){
		$str_tpl =~ s/<$label>/$value/gsi;
	}
	else {
		$str_tpl =~ s/<$label>/$default/gsi
	}
	return($str_tpl);
}

sub GetVirtualHosts {
	my $file = shift;
	open(APACHE, $file) || die "Can't open $file\n";
	my $line = "";
	my $in = 0;
	my @hosts = ();
	my $vhost = {};
	while($line = <APACHE>){
		if($line =~ /<\/VirtualHost>/){
			push(@hosts, $vhost);
			$vhost = {};
			$in = 0;
		}

		if($in == 1){
			$line =~ s/^\s+//g;
			$line =~ s/<\///g;
			$line =~ s/<//g;
			$line =~ s/>//g;
			my @directive = split(/\s+/,$line);
			next if(!defined($directive[1]));
			print "ASSIGNING: $directive[0] = $directive[1]\n";
			$vhost->{$directive[0]} = $directive[1];
		}

		if($line =~ /<VirtualHost .+>/){
			print "\nVirtual Host Found $line\n";
			$in = 1;
		}

	}
	close(APACHE);
	return(@hosts);
}


sub GetFile {
	my $file = shift;
	open(FILE, $file) || die "Can't open $file\n";
	my @ret = <FILE>;
	close(FILE);
	return(@ret);
}

sub GetCherokeeMaxId {
	my $conf = shift;
	my @content = GetFile($conf);
	my $max_id = 0;
	foreach my $line (@content){
		next if($line eq "");
		my @cherokee_conf = split("!", $line);
		next if(!defined($cherokee_conf[1]));
		$max_id = $max_id < $cherokee_conf[1] ? $cherokee_conf[1] : $max_id if($cherokee_conf[1] =~ /^\d/);
	}
	return($max_id);
}
