The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl
# make_sandbox_from_installed
#    The MySQL Sandbox
#    Copyright (C) 2006-2010 Giuseppe Maxia
#    Contacts: http://datacharmer.org
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; version 2 of the License
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


use strict;
use warnings;
use MySQL::Sandbox qw(runs_as_root);

runs_as_root();

my $new_version = shift
    or die "version needed\n";
if ($new_version =~ /^(-h|--help)$/) {
    print MySQL::Sandbox::credits();
    print<<END_HELP;

This script tries to create a sandbox using already installed binaries.
Since these binaries can be in several different places, the script 
creates a container with symbolic links, where the binaries 
(their links, actually) are arranged as MySQL Sandbox expects them to be.

To use this version, change directory to a place where you want to 
store this symbolic links container, and invoke

  make_sandbox_from_installed X.X.XX [options]

    where X.X.XX is the version number. 
    You can then pass any options accepted by make_sandbox.
END_HELP

    exit(1);

}

$new_version =~ /^\d+\.\d+\.\d+$/ 
    or die "invalid version format (required #.#.##)\n";

my $current_dir = $ENV{PWD};

if ( -d $new_version) {
    die "directory $new_version already exists. Choose another name or location\n"
}

my @binaries = (
    {files => 'my*',                from => 'bin/',     to => 'bin'},
    {files => 'resolveip',          from => 'bin/',     to => 'bin'},
    {files => 'mysql_install_db',   from => 'scripts/', to => 'bin', optional => 1},
    {files => 'mysql*',             from => 'lib64/',   to => 'lib', optional => 1},
    {files => 'mysql*',             from => 'lib/',     to => 'lib', optional => 1},
    {files => 'mysql*',             from => 'libexec/', to => 'bin', optional =>1},
    {files => 'mysql*',             from => 'sbin/',    to => 'bin', optional =>1},
    {files => 'mysql/',             from => 'share/',   to => 'share', optional =>1},
);

my @commands;
my @prefixes = (
    '/usr',
    '/usr/local',
    '/usr/local/mysql',
);

my $found_mysqld        = 0;
my $found_install_db    = 0;
my $found_libraries     = 0;

for my $prefix (@prefixes) {
    if (
       (-x "$prefix/bin/mysqld") 
       or (-x "$prefix/libexec/mysqld")
       or (-x "$prefix/sbin/mysqld")
       ) 
    {
        $found_mysqld =1;
    }
    if (
        (-x "$prefix/bin/mysql_install_db") 
        or (-x "$prefix/scripts/mysql_install_db")
        ) 
    {
        $found_install_db =1;
    }
    if ( glob("$prefix/lib/mysql/libmysqlclient*") 
       or glob( "$prefix/lib/libmysqlclient*")  ) {
        $found_libraries =1;
    }
}

unless ($found_mysqld) {
    die "can't find mysqld in (@prefixes)\n";
}
unless ($found_install_db) {
    die "can't find mysql_install_db in (@prefixes)\n";
}
unless ($found_libraries) {
    die "can't find mysql libraries in (@prefixes)\n";
}

for my $bin ( @binaries ) {
    my $found_prefix = undef;
    for my $prefix (@prefixes) {
        if ($bin->{files} =~ /\*/ ) {
            my @files = glob("$prefix/$bin->{from}/$bin->{files}");
            if (@files) {
                $found_prefix = $prefix;
                last;
            }
        }
        else {
            if ( -e "$prefix/$bin->{from}/$bin->{files}") {
                $found_prefix = $prefix;
                last;
            }
        }
    }
    unless ( $found_prefix) {
        if ($bin->{optional}) {
            next;
        }
        die "can't find $bin->{from}/$bin->{files} under (@prefixes) \n";
    }
    push @commands, sprintf("ln -s %s/%s/%s %s/%s/%s",
        $found_prefix,
        $bin->{from},
        $bin->{files},
        $current_dir,
        $new_version,
        $bin->{to}
    );
}

unless (grep { /share/ } @commands) {
    if ( -d "/usr/local/mysql/share" ) {
        push @commands, "ln -s /usr/local/mysql/share/* $current_dir/$new_version/share";
    }
}

#use Data::Dumper;
#print Dumper \@commands; 
#exit;
mkdir $new_version 
    or die "can't create $new_version ($!)\n";

chdir $new_version;
for my $dir (qw(bin lib share)) {
    mkdir $dir
        or die "can't create $new_version/$dir\n";
}

for my $command (@commands) {
    system $command;
    if ($?) {
        die "error creating symbolic link ($command) \n";
    } 
}

$ENV{SANDBOX_BINARY} = $current_dir;
system "make_sandbox $new_version -- @ARGV";