#!/usr/bin/perl -w
# Automatic mono-server4 file generator
#
# With this script the user can update the host files 
# that are installed in /etc/mono-server4/conf.d/package and create a 
# 'big' host file (/etc/mono-server4/mono-server4-hosts.conf) that will be used
# by mono-server4 to setup the virtual hosts needed by 
# the user.
#
# Under GPL, please read: 
# http://www.gnu.org/copyleft/gpl.html
#
# Written by: Pablo Fischer

=head1 NAME

mono-server4-update - creates .webapp and .host file for mod_mono and mono-server4

=head1 SYNOPSIS

mono-server4-update

=head1 DESCRIPTION

 mono-server4-update is a perl tool to update/create a .webapp and a .host file in 
 /etc/mono-server4.

 These two files are needed by mod_mono (apache), they setup the alias, directory permissions, 
 and ASP.NET applications.

 Both files are created with other host configuration files that are in /etc/mono-server4/conf.d

 For more information read the README.Debian of this package (/usr/share/doc/mono-server4/README.Debian).

=head1 AUTHOR

 Pablo Fischer <pablo@pablo.com.mx>

=cut

use strict; 
use Digest::MD5;

#Main vars..
my ($monoserver4_dir, $monoserver4_confd, $monoserver4_hostfile, $monoserver4_webapp,
    $daemon, $daemon_pid, $default_file,
    $applications, $libs, $daemon4, $daemon4_pid);

#Setup main vars
$monoserver4_dir = "/etc/mono-server4";
$monoserver4_confd = "$monoserver4_dir/conf.d";
$monoserver4_webapp = "$monoserver4_dir/debian.webapp";
$monoserver4_hostfile = "$monoserver4_dir/mono-server4-hosts.conf";
$daemon = "/etc/init.d/apache";
$daemon_pid = "/var/run/apache.pid";
$daemon4 = "/etc/init.d/apache2";
$daemon4_pid = "/var/run/apache2.pid";
$applications = "";
$default_file = "/etc/default/mono-apache-server4";
$libs = "";

my $restart = "yes";
my $first_file = "yes";
my ($orig_md5, $new_md5);

#Check write access to $monoserver4_hostfile
if( ( -e "$monoserver4_hostfile" && ! -w "$monoserver4_hostfile" ) || ! -w "$monoserver4_dir" ) {
    print "mono-xsp-update requires write access to $monoserver4_hostfile or 
be executed by root\n" ; 
    exit 1 ;
}

#Read the default file
&read_default_file;
#Orig md5
$orig_md5 = &get_md5;
#Read directory..
&read_dir;
if(-f "$monoserver4_hostfile.tmp") {
    #Prepare the application string
    $applications =~ s/,$//;
    #and the libs..
    $libs = "/usr/lib/mono/4.0:/usr/lib:$libs"; 
    $libs =~ s/:$//;
    #sed the $monoserver4_hostfile to replace the Applications
#    &replace_applications;
    #Replace the MONOPATH
    &replace_monopath;
    &write_tempdefault_end;
    #cp the temp file to the original one..    
    system("cp -f $monoserver4_hostfile.tmp $monoserver4_hostfile");    
    #rm the temp
    system("rm -Rf $monoserver4_hostfile.tmp");
    #Final md5
    $new_md5 = &get_md5;
    #Equal?
    if(("$new_md5" ne "$orig_md5") && ($restart eq "yes")) {
	if(( -f $daemon ) && ( -f $daemon_pid )) {
	    system("$daemon reload");
	    system("$daemon restart");
	}
	if(( -f $daemon4 ) && ( -f $daemon4_pid )) {
	    system("$daemon4 reload");
	    system("$daemon4 restart");
	}
    }
}

sub get_md5 {
    if( -e $monoserver4_hostfile ) {
	open(HOSTFILE, $monoserver4_hostfile);
	binmode(HOSTFILE);
	return Digest::MD5->new->addfile(*HOSTFILE)->hexdigest;
	
    }
    else {
	return "";
    }
}

sub read_default_file {
    
    if(-e $default_file) {
	open(DEFAULT_FILE, "$default_file");
	while(my $line = <DEFAULT_FILE>) {
	    if($line =~ /start_apache/i) {
		if($line =~ /true/i) {
		    $restart = "yes";
		}
		else {
		    $restart = "no";
		}
	    }
	}
	close(DEFAULT_FILE);
    }
}


sub read_dir {
    opendir(DIR, $monoserver4_confd);
    my @host_dirs = sort (grep { -d "$monoserver4_confd/$_" } readdir(DIR));
    closedir(DIR);

    #to verify that the cfg file is new.. we should create a new one
    system("rm -Rf $monoserver4_hostfile");
    system("touch $monoserver4_hostfile");
    #also to the debian.webapp
    system("rm -Rf $monoserver4_webapp");
    system("touch $monoserver4_webapp");

    #How many dirs?
    if($#host_dirs ne "0") {
	#Write default content
	&write_tempdefault_start;
	foreach my $dir (@host_dirs) {
	    if(($dir ne "..") && ($dir ne ".")) {
		#Ok, in the dir.. we have more files, so read them
		opendir(DIR, "$monoserver4_confd/$dir");
		my @host_files = sort (readdir(DIR));
		closedir(DIR);
		#Is it empty?		
		if($#host_files ne "0") {
		    #So, read it..
		    foreach my $hostfile (@host_files) {
			#Just remember.. we don't like directories inside directories!
			if(($hostfile ne "..") && ($hostfile ne ".")) {
			    $hostfile = "$monoserver4_confd/$dir/$hostfile";
			    write_tempxsphostfile($hostfile);
			}
		    }
		}
	    }
	}
    }
}

sub replace_applications {
    local $/;

    open(TEMPHOST, "$monoserver4_hostfile.tmp");
    my $content = <TEMPHOST>;
    close(TEMPHOST);

    if($applications) {
	$content =~ s/MonoApplications .*/MonoApplications $applications/gi;
    }
    else {
	$content =~ s/MonoApplications//gi;
    }
    
    open(TEMPHOST, "> $monoserver4_hostfile.tmp");
    print TEMPHOST $content;
    close(TEMPHOST);
}

   
sub replace_monopath {
    local $/;

    open(TEMPHOST, "$monoserver4_hostfile.tmp");
    my $content = <TEMPHOST>;
    close(TEMPHOST);

    if($libs) {
	$content =~ s/MonoPath .*/MonoPath default $libs/gi;
    }
    else {
	$content =~ s/MonoPath default//gi;
    }
    
    open(TEMPHOST, "> $monoserver4_hostfile.tmp");
    print TEMPHOST $content;
    close(TEMPHOST);
}

sub write_tempdefault_start {
    open(TEMPHOST, ">> $monoserver4_hostfile.tmp");

    print TEMPHOST "# Default configuration, don't edit it!\n";
    print TEMPHOST "<IfModule mod_mono.c>\n";
    print TEMPHOST "  MonoUnixSocket default /tmp/.mod_mono_server4\n";    
    print TEMPHOST "  MonoServerPath default /usr/bin/mod-mono-server4\n";
    print TEMPHOST "  AddType application/x-asp-net .aspx .ashx .asmx .ascx .asax .config .ascx\n";
    print TEMPHOST "  MonoApplicationsConfigDir default /etc/mono-server4\n";
    print TEMPHOST "  MonoPath default \n";

    close(TEMPHOST);

    open(TEMPWEBAPP, ">> $monoserver4_webapp");
    print TEMPWEBAPP "<apps>\n";
    close(TEMPWEBAPP);
    
}

sub write_tempdefault_end {
    open(TEMPHOST, ">> $monoserver4_hostfile.tmp");
    print TEMPHOST "</IfModule>\n";
    close(TEMPHOST);

    #Now the debian.webapp
    open(TEMPWEBAPP, ">> $monoserver4_webapp");
    print TEMPWEBAPP "</apps>\n";
    close(TEMPWEBAPP);

}   


sub write_tempxsphostfile {
    my $hostfile = shift;

    #Write the content to a temp file..
    open(TEMPHOST, ">> $monoserver4_hostfile.tmp");
    open(TEMPWEBAPP, ">> $monoserver4_webapp");

    #And open the hostfile..
    open(HOSTFILE, "$hostfile");
    #Read it..
    my @content_hostfile = <HOSTFILE>;
    #Close it..
    close(HOSTFILE);
    #Write the header to the monoserver4_hostfile
    
    my ($path, $alias, $vhost, $port, $name);

    $vhost = "localhost";
    $port = "80";
    foreach my $line (@content_hostfile) {	
	if($line =~ /path/i) {
	    #Ok, the directory exists?
	    my $dir = (split /\=/, $line)[1];
	    #Remove blank spaces
	    $dir =~ tr/\ //d;
	    #remove that \n
	    $dir =~ s/\n//;
 	    if ( ! -d "$dir" ) {
		$dir = "";
		last;
 	    }
	    else {
		$path = $dir;
	    }
	}

	if($line =~ /alias/i) {
	    $alias = (split /\=/, $line)[1];
	    #Blank Spaces
	    $alias =~ tr/\ //d;
	    #New lines..
	    $alias =~ s/\n//;
	    #The name
	    $name = $alias;
	    $name =~ s|/*||;
	}

	if($line =~ /lib/i) {
	    $libs = (split /\=/, $line)[1];
	    #Blank spaces
	    $libs =~ tr/\ //d;
	    #New lines..
	    $libs =~ s/\n//;
	    #And remove the last and first ':'..
	    $libs =~ s/:$//;
        }    

	if($line =~ /vhost/i) {
	    $vhost = (split /\=/, $line)[1];
	    #Blank spaces
	    $vhost =~ tr/\ //d;
	    #New lines..
	    $vhost =~ s/\n//;
	    #And remove the last and first ':'..
	    $vhost =~ s/:$//;
        }   

	if($line =~ /port/i) {
	    $port = (split /\=/, $line)[1];
	    #Blank spaces
	    $port =~ tr/\ //d;
	    #New lines..
	    $port =~ s/\n//;
	    #And remove the last and first ':'..
	    $port =~ s/:$//;
        }  

	if($line =~ /name/i) {
	    $name = (split /\=/, $line)[1];
	    #Blank spaces
	    $name =~ tr/\ //d;
	    #New lines..
	    $name =~ s/\n//;
	    #And remove the last and first ':'..
	    $name =~ s/:$//;
        }  
	
    }	
    
    if($path) {
	$applications = "$applications$alias:$path,";
	$libs = "$libs:";

	print TEMPWEBAPP "  <web-application>\n";
	print TEMPWEBAPP "    <name>$name</name>\n";
	print TEMPWEBAPP "    <vpath>$alias</vpath>\n";       
	print TEMPWEBAPP "    <path>$path</path>\n";
	print TEMPWEBAPP "    <vhost>$vhost</vhost>\n";
	print TEMPWEBAPP "    <port>$port</port>\n";
	print TEMPWEBAPP "  </web-application>\n";

	print TEMPHOST "# start $hostfile\n";
	print TEMPHOST "     Alias $alias \"$path\"\n";
	print TEMPHOST "     AddMonoApplications default \"$alias:$path\"\n";
	print TEMPHOST "       <Directory $path>\n";
	print TEMPHOST "         SetHandler mono\n";
	print TEMPHOST "           <IfModule mod_dir.c>\n";
	print TEMPHOST "              DirectoryIndex index.aspx\n";
	print TEMPHOST "           </IfModule>\n";
	print TEMPHOST "       </Directory>\n";
	print TEMPHOST "# end $hostfile\n";
	
    }
    close(TEMPHOST);
    close(TEMPWEBAPP);
}  
