###
###  Copyright 2000-2007 University of Illinois Board of Trustees
###  All rights reserved. 
###
###  PSGConf::Action::lpadmin - Configure LP printers
###
###  Campus Information Technologies and Educational Services
###  University of Illinois at Urbana-Champaign
###


package PSGConf::Action::lpadmin;

use strict;

use PSGConf::Action::File;

use PSGConf::Util;

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


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

sub check
{
	my ($self, $psgconf) = @_;
	my ($cmd, $res, @output);
	local *FP;

	### First check to see if the printer is even defined.
	$cmd = 'lpstat -p ' . $self->{name} . ' > /dev/null 2>&1';
	$res=&PSGConf::Util::RunCommand($cmd, 1);

	$self->{changed} = ($res == -1)? 1: 0;

	### Now check to make sure the print device is correct
	if ( ! $self->{changed} && defined $self->{device}) {
		$cmd = 'lpstat -v ' . $self->{name};
		if ( open (FP, "$cmd 2>&1 |") ) {
			$res=grep (/device for $self->{name}: $self->{device}/, <FP>);
			close FP;

			$self->{changed} = ($res == 1)? 0: 1;
		} else {
			$self->{changed} = 1;
		}
	}

	### Grab the output from lpstat -p $name -l and cache it.
	$cmd = 'lpstat -p ' . $self->{name} . ' -l 2>&1';
	if (open (FP, "$cmd |")) {
		@output = <FP>;
		close FP;
	}

	### And check to make sure the dest is correct
	if ( ! $self->{changed} && defined $self->{remotehost}) {
		$res=grep (/Options:.*dest=$self->{remotehost}/, @output);

		$self->{changed} = ($res == 1)? 0: 1;
	}

	### And check to make sure the model is correct
	if ( ! $self->{changed} && defined $self->{model}) {
		$res=grep (/Interface: .*$self->{model}$/, @output);

		$self->{changed} = ($res == 1)? 0: 1;
	}

	### And check to make sure the protocol is correct
	if ( ! $self->{changed} && defined $self->{protocol}) {
		$res=grep (/Options:.*protocol=$self->{protocol}/, @output);

		$self->{changed} = ($res == 1)? 0: 1;
	}

	if (  ! $self->{changed} && scalar @{$self->{content_type}}) {
		map {
			$res=grep (/Content types:.*$self->{content_type}->[$_]/, @output);
			$self->{changed} = ($res == 1)? $self->{changed}: 1;
		} @{$self->{content_type}};
	}

	### Now check to make sure this printer is setup as the default printer
	if ( ! $self->{changed} && $self->{name} eq $self->{default_printer} ) {
		$cmd = 'lpstat -d';
		if (open (FP, "$cmd 2>&1 |")) {
			$res=grep (/system default destination: $self->{name}$/, <FP>);
			close FP;

			$self->{changed} = ($res == 1)? 0: 1;
		} else {
			$self->{changed} = 1;
		}
	}

	return $self->{changed};
}


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

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

	print "###############################################################################\n";
	print "### DIFF FOR lpadmin\n";
	print "###############################################################################\n";
	print "+ lpadmin -p $self->{name} ...\n";
	print "\n";
}


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

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

	### Check to see if the printer is defined,
	### and then delete it and start over.
	$cmd = 'lpstat -p ' . $self->{name} . ' > /dev/null 2>&1';
	if ( ! &PSGConf::Util::RunCommand($cmd, 1) ) {
		$cmd = 'lpadmin -x ' . $self->{name} . ' >/dev/null 2>&1';
		$res=&PSGConf::Util::RunCommand($cmd, 1);
	}

	### First run the lpadmin -p <NAME> ... command
	$cmd = 'lpadmin -p ' . $self->{name};

	$cmd .= ' -v ' . $self->{device} 
		if ( defined $self->{device} );

	$cmd .= ' -m ' . $self->{model} 
		if ( defined $self->{model} );

	$cmd .= ' -I ' . join (',', @{$self->{content_type}})
		if ( defined $self->{content_type} );

	$cmd .= ' -o dest=' . $self->{remotehost} 
		if ( defined $self->{remotehost} );

	$cmd .= ' -o protocol=' . $self->{protocol} 
		if ( defined $self->{protocol} );

	$cmd .= ' -o ' . $self->{options} 
		if ( defined $self->{options} );

	$cmd .= ' >/dev/null 2>&1';

	$res=&PSGConf::Util::RunCommand($cmd);

	### Now set the default printer
	if ( ! $res && $self->{name} eq $self->{default_printer} ) {
		$cmd = 'lpadmin -d ' . $self->{name} . '> /dev/null 2>&1';
		$res=&PSGConf::Util::RunCommand($cmd);
	}

	### accept queue jobs for the printer
	if ( ! $res ) {
		$cmd = 'accept ' . $self->{name} . '> /dev/null 2>&1';
		$res=&PSGConf::Util::RunCommand($cmd);
	}

	### Finally enable the printer itself
	if ( ! $res ) {
		$cmd = 'enable ' . $self->{name} . '> /dev/null 2>&1';
		$res=&PSGConf::Util::RunCommand($cmd);
	}

	return $res;
}


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

1;

__END__

=head1 NAME

PSGConf::Action::lpadmin - Configure LP printers

=head1 SYNOPSIS

  use PSGConf::Action::lpadmin;

  $psgconf->register_actions(
		PSGConf::Action::lpadmin->new(
			'name'			=> 'Name of this printer to configure',
			'default_printer'	=> 'Name of default printer',
			'printers'		=> 'Hash of all printer definitions'
		),
		...
	);

=head1 DESCRIPTION

The B<PSGConf::Action::lpadmin> module provides a B<PSGConf> action
class for configuring LP based printers.

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

=over 4

=item check()

Checks the system to see if the printer has been configured or not.

=item diff()

Prints a message indicating which printers need to be configured.

=item do()

Does the printer configuration in up to 4 steps.  First it it
configures the printer via C<lpadmin> command.   Then it will
set the default printer and finally will run the C<accept> and
C<enable> commands for each print queue.

=back

In addition to the attributes supported by the B<PSGConf::Action>
class, the B<PSGConf::Action::lpadmin> class supports the following
attributes:

=over 4

=item I<name>

The name of this printer (print queue).

=item I<default_printer>

The name of the default print queue.

=item I<remotehost>

The DNS Name or IP address (with optional port) to talk to the remote
printer.

=item I<device>

The device for C<lpadmin> to use.

=item I<content_type>

The content type(s) for C<lpadmin> to use.

=item I<model>

The model for C<lpadmin> to use.

=item I<protocol>

The protocol for C<lpadmin> to use.

=item I<options>

Options for C<lpadmin> to use when setting the printer.

=back

=head1 SEE ALSO

L<perl>

L<PSGConf>

L<PSGConf::Action>

L<PSGConf::Util>

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

C<CE<lt>lpadmin(1m)E<gt>>

C<CE<lt>accept(1m)E<gt>>

C<CE<lt>enable(1m)E<gt>>

=cut



syntax highlighted by Code2HTML, v. 0.9.1