###
###  Copyright 2000-2007 University of Illinois Board of Trustees
###  All rights reserved. 
###
###  PSGConf::Action::ChMod - chmod file action type for psgconf
###
###  Campus Information Technologies and Educational Services
###  University of Illinois at Urbana-Champaign
###


package PSGConf::Action::ChMod;

use strict;

use File::stat;

use PSGConf::Action;

our @ISA = qw(PSGConf::Action);


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

sub new
{
	my ($class, %opts) = @_;
	my ($self) = \%opts;

	$self->{mode} = 0644
		if (!exists($self->{mode}));

	return PSGConf::Action::new($class, %$self);
}


###############################################################################
###  check method
###############################################################################

sub check
{
	my ($self, $psgconf) = @_;

	return if ($self->{mode} == -1);

	$self->{stat} = stat($self->{name});

     ### check permissions
	$self->{changed} = 1
     	if (!defined $self->{stat} 
     		|| ($self->{stat}->mode & 07777) != $self->{mode});

	return $self->{changed};
}


###############################################################################
###  diff method
###############################################################################

sub diff
{
	my ($self, $psgconf) = @_;

	return if ($self->{mode} == -1);

	$self->{stat} = stat($self->{name});

     if (!defined $self->{stat} 
		|| ($self->{stat}->mode & 07777) != $self->{mode})
	{
		print "###############################################################################\n";
		print "### DIFF FOR $self->{name}\n";
		print "###############################################################################\n";
		printf "+ MODE CHANGE: %04o -> %04o\n\n",
			(!defined $self->{stat})? 0: ($self->{stat}->mode & 07777),
			$self->{mode};
	}
}


###############################################################################
###  do() method
###############################################################################

sub do
{
	my ($self, $psgconf) = @_;

	return if ($self->{mode} == -1);

	$self->{stat} = stat($self->{name});

	### check permissions
     if (!defined $self->{stat}
		|| ($self->{stat}->mode & 07777) != $self->{mode})
	{
		if (!chmod($self->{mode}, $self->{name}))
		{
			warn "\t!!! chmod(\"$self->{name}\"): $!\n";
			return -1;
		}
	}

	return 1;
}

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

1;

__END__

=head1 NAME

PSGConf::Action::ChMod - chmod file action type for psgconf

=head1 SYNOPSIS

  use PSGConf::Action::ChMod;

  $psgconf->register_actions(
		PSGConf::Action::ChMod->new(
			'name'		=> '/path/to/file',
			'mode'		=> 'mode of file',
			...
		),
		...
	);

=head1 DESCRIPTION

The B<PSGConf::Action::ChMod> module provides a B<PSGConf> action
class for changing a file's mode.  The default mode is C<0644> and
C<-1> means ignore the mode of the file.

The B<PSGConf::Action::ChMod> class is derived from the
B<PSGConf::Action> class, but it defines/overrides the
following methods:

=over 4

=item check()

If the file mode is correct, returns 0.  Otherwise, returns 1.

=item diff()

Displays a message indicating that the file needs to be chmod()ed.

=item do()

Actually calls chmod().

=back

=head1 SEE ALSO

L<perl>

C<CE<lt>chmod(1)E<gt>>

L<PSGConf>

L<PSGConf::Action>

=cut



syntax highlighted by Code2HTML, v. 0.9.1