###
###  Copyright 2000-2007 University of Illinois Board of Trustees
###  All rights reserved. 
###
###  PSGConf::Control::SharedLibrary - class for configuring shared library support
###
###  Campus Information Technologies and Educational Services
###  University of Illinois at Urbana-Champaign
###


package PSGConf::Control::SharedLibrary;

use strict;

use PSGConf::Action::GenerateFile::Literal;
use PSGConf::Action::MkDir;
use PSGConf::Action::RunCommand;

use PSGConf::Data::List;
use PSGConf::Data::String;
use PSGConf::Data::Boolean;

###############################################################################
###  constructor
###############################################################################

sub _check_crle_cfg
{
	my ($self, $psgconf) = @_;
	my ($lib_list);
	local *FP;

	return 0
		if ( $psgconf->data_obj('shared_library_enable')->equals('false') );

	if (! open(FP, $psgconf->data_obj('shared_library_cmd')->get() . ' |'))
	{
		warn "\n\t!!! cannot run "
			. $psgconf->data_obj('shared_library_cmd')->get()
			. ": $!\n";
		return -1;
	}

	grep ( /Default Library Path \(ELF\):[\s\t]+([^\s\t]*)/o && ( $lib_list = $1), <FP>);
	close FP;

	return 1 
		if ($lib_list ne join(':', @{$psgconf->data_obj('shared_library_path_list')->get()}));

	return 0;
}

###############################################################################
###  constructor
###############################################################################

sub new
{
  my ($class, $psgconf) = @_;
  my ($self);
  
  $self = {};
  
  bless($self, $class);
  
  $self->{name} = 'shared_library';
	$self->{enable} = $self->{name} . '_enable';
	$self->{packages} = $self->{name} . '_packages';
  
  $psgconf->register_data(
	  'shared_library_path_list'		=> PSGConf::Data::List->new(),
	  'shared_library_alt_path_list'	=> PSGConf::Data::List->new(),
	  'shared_library_cmd' 			=> PSGConf::Data::String->new(
										'value_abspath' => 1
									),
	  'shared_library_enable'		=> PSGConf::Data::Boolean->new(
										value => 'false'
									)
  );

  return $self;
}

###############################################################################
###  decide
###############################################################################

sub decide
{
	my ($self, $psgconf) = @_;
	my ($cmd);
      
	return
		if ( $psgconf->data_obj('shared_library_enable')->equals('false') 
			|| ! $psgconf->data_obj('shared_library_path_list')->count() );

	if ( $psgconf->data_obj('platform')->match('solaris') ) {
		$cmd = $psgconf->data_obj('shared_library_cmd')->get()
			. ' -l '
			. join(':', @{$psgconf->data_obj('shared_library_path_list')->get()});
  
		$psgconf->register_actions(
			PSGConf::Action::RunCommand->new(
				name			=> $psgconf->data_obj('shared_library_cmd')->get() . ' LD_LIBRARY_PATH modification',
				command		=> $cmd,
				check_func	=> \&_check_crle_cfg
			)
		);
	}
	elsif ( $psgconf->data_obj('platform')->match('linux') ) {
		$psgconf->register_actions(
			PSGConf::Action::GenerateFile::Literal->new(
				name     => '/etc/ld.so.conf',
				content  => join("\n",
					@{$psgconf->data_obj('shared_library_path_list')->get()})
					. "\n"
			)
		);
	}
	elsif ( $psgconf->data_obj('platform')->match('freebsd') ) {
		$psgconf->register_actions(
			(map {
				PSGConf::Action::MkDir->new(
					name	=> $_
				)
			}@{$psgconf->data_obj('shared_library_path_list')->get()}),
			PSGConf::Action::GenerateFile::Literal->new(
				name		=> '/etc/ld-elf.so.conf',
				content	=> join("\n",
					@{$psgconf->data_obj('shared_library_path_list')->get()})
					. "\n"
			),
			PSGConf::Action::RunCommand->new(
				name		=> 'ldconfig (elf)',
				command	=>  $psgconf->data_obj('shared_library_cmd')->get() . ' -elf',
				filename	=> [ '/etc/ld-elf.so.conf' ]

			)
		);
		$psgconf->register_actions(
			(map {
				PSGConf::Action::MkDir->new(
					'name'         => $_
				)
			}@{$psgconf->data_obj('shared_library_alt_path_list')->get()}),
			PSGConf::Action::GenerateFile::Literal->new(
				name		=> '/etc/ld.so.conf',
				content  => join("\n",
					@{$psgconf->data_obj('shared_library_alt_path_list')->get()})
					. "\n"
			),
			PSGConf::Action::RunCommand->new(
				name		=> 'ldconfig (a.out)',
				command	=>  $psgconf->data_obj('shared_library_cmd')->get() . ' -aout',
				filename	=> [ '/etc/ld.so.conf' ]

			)
		) if ($psgconf->data_obj('platform')->match('ix86'));
	}
}

###############################################################################
###  documentation
###############################################################################

1;
__END__

=head1 NAME

PSGConf::Control::SharedLibrary - psgconf control class for controlling shared library locations

=head1 SYNOPSIS

In F<psgconf_modules>:

  Control PSGConf::Control::SharedLibrary

=head1 DESCRIPTION

The B<PSGConf::Control::SharedLibrary> module provides a B<psgconf>
control object for setting system-wide library load paths.
It supports the following methods:

=over 4

=item new()

The constructor.  Its parameter is a reference to the B<PSGConf>
object.  It registers the following data objects:

=over 4

=item I<shared_library_path_list>

A B<PSGConf::Data::List> object whose elements are the paths to
directories to be added to the library search path.

=item I<shared_library_alt_path_list>

A B<PSGConf::Data::List> object whose elements are the paths to
directories to be added to the alternate library search path.

=item I<shared_library_enable>

A B<PSGConf::Data::Boolean> object to enable/disable this feature

=item I<shared_library_cmd>

A B<PSGConf::Data::String> object to run to verify and/or modify
the shared library paths.

=back

=back

=head1 SEE ALSO

C<CE<lt>crle(8)E<gt>>

C<CE<lt>ldconfig(8)E<gt>>

C<CE<lt>ld.so(8)E<gt>>

L<perl>

L<PSGConf>

L<PSGConf::Action::GenerateFile::Literal>

L<PSGConf::Action::MkDir>

L<PSGConf::Action::RunCommand>

L<PSGConf::Data::Boolean>

L<PSGConf::Data::List>

L<PSGConf::Data::String>

L<psgconf-intro>

=cut


syntax highlighted by Code2HTML, v. 0.9.1